String to decimal in rust

Hi,

I find the following fn I wrote in rust to convert a string into a decimal number too clumsy working though. Input from stdin is passed to this function to get the decimal number or to throw error if input is not in the range of 10..2.

How to make it better? Mostly, I (from C background to rust) searched through the available methods in std library and chose one, help on idiomatic rust way is sought.

fn string_to_decimal(s: &mut String) -> Result<u8, String> {

    let len = s.trim().len();

    if  len == 0 || len > 2{
        Err("Maximum players 10 & minimum players 2".to_string())
    } else if len == 2{
        let mut num: u8 = 0;
    
        let mut ch = s.remove(0); /* Tens */
        if let Some(tens) = ch.to_digit(10) {
            num += (tens * 10) as u8;
        }

        ch = s.remove(0); /* Ones */
        if let Some(ones) = ch.to_digit(10){
            num += ones as u8;
        }

        if num <= 10 {
            Ok(num)
        }else {
            Err("Maximum players allowed is 10".to_string())
        }
    } else /* len is 1*/{
 
        let ch = s.remove(0); /* Ones */
        if let Some(ones) = ch.to_digit(10){
            if ones < 10 && ones > 1 {
                Ok(ones as u8)
            } else {
                Err("Maximum players 10 & minimum players 2".to_string())
            }
        }else {
            Err("Maximum players 10 & minimum players 2".to_string())
        }
    } 
}

Have you tried the parse method on str? str - Rust

Example: Rust Playground

Or is your goal to write your own parsing function?

1 Like

NO, I dont want to write my own parsing function.

Changed the function with parse as below, but when run (no compilation error though), it panicked. thread 'main' panicked at 'called Result::unwrap() on an Err value: ParseIntError { kind: InvalidDigit }

fn string_to_decimal(s: &mut String) -> Result<u8, String>  {
    let k: u8 = s.parse().unwrap();
    if k > 2 && k <11 {
        Ok(k)
    }else {
        Err("Maximum players 10 and minimum players 2".to_string())
    }
}

match string_to_decimal(& mut buf) {
                    Ok(v) => {
                        //println!("Chosen number of players {}", v);
                        player_count = v;
                        break;
                    }
                    Err(e) => println!("Error: {}", e),
                }

That's what unwrap does. You may want to read this chapter of the book.

Here's another alternative.

    let k: u8 = s.trim().parse().map_err(|e| {
        format!("Could not parse number of players: {e}")
    })?;
5 Likes

Thank you. Got to know that the newline character at the input string caused the panic.

1 Like