Finding century of any year

Hello Rust forum!

Century: Take the first 2 digit of 4-digit year, and add it 1. For example, 2020 -> 21, 1567 -> 16 ...

I want to write rust code that it finds century of any year.

My Codes
fn main() {
    let result = find_century("2014");
    println!("{}", result);
}

fn find_century(year: &str) {
    if year.len() != 4 {
        panic!("Must to be 4");
    }

    let century: u32 = year.parse().unwrap() + 1;

    century;
}

But, rust raises these errors:

Error
Compiling tarih v0.1.0 (/home/emre/Projects/Learning/Rust/tarih)
error[E0277]: `()` doesn't implement `std::fmt::Display`
 --> src/main.rs:3:20
  |
3 |     println!("{}", result);
  |                    ^^^^^^ `()` cannot be formatted with the default formatter
  |
  = help: the trait `std::fmt::Display` is not implemented for `()`
  = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
  = note: required by `std::fmt::Display::fmt`
  = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0284]: type annotations needed
  --> src/main.rs:11:29
   |
11 |     let century: u32 = year.parse().unwrap() + 1;
   |                             ^^^^^ cannot infer type for type parameter `F` declared on the associated function `parse`
   |
   = note: cannot satisfy `<_ as std::str::FromStr>::Err == _`
help: consider specifying the type argument in the method call
   |
11 |     let century: u32 = year.parse::<F>().unwrap() + 1;
   |                                  ^^^^^

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0277, E0284.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `tarih`.

How can i solve this problem?

Your first error tells you that the return type () of the function find_century cannot be formatted using the default formatter. This happens because the return type of your function should probably be u32:

fn find_century(year: &str) -> u32 {
    ....
    century
}

(Note the missing ; at the end of the last line, this indicates that the century is returned from the function)

The second error tells you that the compiler is not able to infer some type arguments (generics) and requires you to specify them:

let century: u32 = year.parse::<u32>().unwrap() + 1;

All together is:

fn main() {
    let result = find_century("2014");
    println!("{}", result);
}

fn find_century(year: &str) -> u32 {
    if year.len() != 4 {
        panic!("Must to be 4");
    }

    let century: u32 = year.parse::<u32>().unwrap() + 1;

    century
}

Edit: I would however write the function differently:

fn find_century(year: &str) -> u32 {
    match year.parse::<u32>() {
        Ok(year) => {
            //do some logic on year here
            return year +1
        },
        _ => panic!("Not a number"),
    }
}
2 Likes

Thanks!

Is this part of code casts string to integer(u32)?

Basically yes, the parse function however does not return a u32 but a Result<u32,SomeErrorKindIDontRememberTheNameOf>. The Result type is what the match is for (checking if there was an error or not).

1 Like

FYI, it's called ParseIntError (in std::num).

Even more information for the interested: