# Basic rust Celsius to Fahrenheit conversion

I've been following the rust book, and I made a Celsius to Fahrenheit converter as it advised me. After a bit, I came up with this code; however in my opinion, there's a lot of unnecessary parts that I couldn't figure out how to simplify. Here is the code:

fn readnum() -> i32 {
loop {
let mut raw_inp = String::new();
Err(er) => {println!("\nError! {}",er); continue; }
Ok(_o) => {}
}
match raw_inp.trim().parse() {
Err(er) => {println!("\nError! {er}"); continue;}
Ok(o) => { return o}
};

}

}

fn main() {
loop {
let converted:f32 = (val as f32 * (9f32/5f32 ))+ 32f32;
println!("In Fahrenheit it is: {}", converted);

}
}

• What do you think are the "unnecessary parts"? Commented Apr 17 at 19:29
• @MaartenBodewes The first match in the readnum function especially as the Ok just does nothing. Commented Apr 17 at 19:39

I don't think there is too much to simplify. Note that we generally would err towards readable code rather than concise code. Or at least that was what I was used to as Java coder. Actually I'd introduce a function or two.

You've indicated that the error handling may contain "unnecessary parts". I'd indicate that you could visit this page and then look at how unwrap_or_else can be used.

Personally though I'd probably have one function asking for a number, returning an error if the function doesn't. Then you can loop until you do get a number. This would work well with the propagating errors & ? operator.

Some remarks:

• Asymmetry: the user enters an i32 which is then converted to an f32 (32 bit floating point); both are similar units and should probably have similar representations (f32 makes the most sense to me, as temperature is a continuous spectrum).
• readnum retrieves a number from a user (with possible retries), but the name only indicates that a number is read from somewhere.
• Generally it is a good idea use the input source as a parameter, e.g. for testing (i.e. the call would be inputNumber(std::io::stdin()), uh or something similar (Rust seems to have this return something of type Stdin which seems to be it's own class).
• You have one println!("\nError! {}",er) and one println!("\nError! {er}" which looks unbalanced. I'd personally prefer the latter. I'd also indicate the type of error.
• There really should be a function called celciusToFahrenheit in there. Always make sure that the "business logic" is separated from the I/O and therefore the main() function. Remember you want to test your functions for any serious piece of code, e.g. using Unit tests.
• The println!("Enter your celsius number: "); is in the main function while it is part of the UI code. It makes most sense to have the println and read_line statements grouped together in one function - possibly with sub-functions where required.
• It's best practice to also repeat the println!("Enter your celsius number: "); so that the user knows what to do after getting an error.

      };

As an extreme nitpick, I'd generally first handle the positive outcome in a match statement (i.e. focus on the good flow). There is something to be said for fail-fast, but basically the matches are at the same level so I don't think it would count as an argument.