How to loop over error catched by match from _

I apologize if this is a wrong place to post code issue. Please disregard this and i hope it wont bother you further.
I needed help to understand if i can take user input, loop over the error catch by match and ask for correct user input for further execution.
Outline:
I take input string from user, match it with characters k,f or c. if anything else, returns "input k,f or c".
How do i put "input k,f or c" in a loop so that when the user inputs correct string, i can extract value out of the loop.
my code: (it compiles but not the way i want. can't interact with rust playground terminal but compiles)

fn main() {
    println!("K : for Kelvin    C : for Celsius     F : for Fahrenheit : ");
    
    let mut unit = String::new();
    std::io::stdin().read_line(&mut unit).expect("Failed to read line");
    
    let unit = unit.trim().to_uppercase();
    println!("unit is {unit} -before match");// this line is for test
    
    let unit:&str = match &*unit{
        "K"=>"K",
        "F"=>"F",
        "C"=>"C",
         _ =>{println!("input k,f or c");return},
    };
    println!("unit is {unit} after match");// this line is for test
    
}

Here's one suggestion:

fn main() {
    let unit = loop {
        println!("K : for Kelvin    C : for Celsius     F : for Fahrenheit : ");

        let mut unit = String::new();
        std::io::stdin()
            .read_line(&mut unit)
            .expect("Failed to read line");

        let unit = unit.trim().to_uppercase();
        println!("unit is {unit} -before match"); // this line is for test

        match &*unit {
            "K" | "F" | "C" => break unit,
            _ => {
                println!("input k,f or c");
            }
        };
    };
    println!("unit is {unit} after match"); // this line is for test
}

The changes I made was, I wrapped it all in a loop, and modified the match so that it breaks out of the loop with the desired input, placing it in the outer unit variable, and if it doesn't match, print a message and loop around to try again.

3 Likes

That was a beautiful solution and a clear explanation to complement with. Than you very much for the help. i have spent hours over this. I did find a solution in stackoverflow and yours was very similar too. Both the solutions helped a lot to understand rust better and all thanks to you. I wish you a healthy and sound life. Here's the other solution for anyone interested.

fn main() {
        println!("K : for Kelvin    C : for Celsius     F : for Fahrenheit : ");
        let unit = loop {

        let mut unit = String::new();
        std::io::stdin()
            .read_line(&mut unit)
            .expect("Failed to read line");
        let unit = unit.trim().to_uppercase();
        println!("unit is {unit} before match"); // this line is for test

        break match unit.as_str() {
            "K" => "K",
            "F" => "F",
            "C" => "C",
            _ =>{println!("please input k,f or c");continue},

        };
    };
    println!("unit is {unit} after match"); // this line is for test
}
1 Like