Parse input string into vector of i16 in Rust I'm new to Rust and I'm working through the exercises found at the bottom of this page. The following code parses a space deliminated input string from the user into a Vec&lt;i16&gt;. If the input string is invalid, the code loops and prompts again. If the string is valid, it prints out the debug value of the Vec&lt;i16&gt; and prompts again.

The code works, but I feel there is a more idomatic Rust way to deal with this. Particularly, in the get_input function's looping and how its assigning the return value. Behold.

use std::io::Write;

fn main() {
    while let Some(ary) = get_input() {
        println!("{:?}", ary);
    }

    println!("Peace!");
}

fn get_input() -&gt; Option&lt;Vec&lt;i16&gt;&gt; {
    let mut out: Option&lt;Vec&lt;i16&gt;&gt; = None;
    let mut valid = false;
    while !valid {
        // Get user input.
        print!("Enter series-&gt; ");
        std::io::stdout().flush().unwrap();
        let mut input = String::new();
        std::io::stdin().read_line(&amp;mut input).unwrap();

        // Parse it.
        match input.trim() {
            "q" =&gt; {
                valid = true;
                out = None;
            }
            _ =&gt; {
                let parsed = parse_input(input);
                if let Ok(_) = parsed {
                    out = Some(parsed.unwrap());
                    valid = true;
                }
            }
        }
    }
    out
}

fn parse_input(input: String) -&gt; Result&lt;Vec&lt;i16&gt;, std::num::ParseIntError&gt; {
    input
        .split_whitespace()
        .map(|token| token.parse::&lt;i16&gt;())
        .collect::&lt;Result&lt;Vec&lt;i16&gt;, _&gt;&gt;()
}
I don't know Rust too well, so take this review with a grain of salt. That being said, your get_input can be heavily simplified if you return. That way we don't need to remember whether the parsed input was valid: if it's valid we just return:

fn get_input() -&gt; Option&lt;Vec&lt;i16&gt;&gt; {
    loop {
        // Get user input.
        print!("Enter series-&gt; ");
        std::io::stdout().flush().unwrap();
        let mut input = String::new();
        std::io::stdin().read_line(&amp;mut input).unwrap();

        // Parse it.
        match input.trim() {
            "q" =&gt; return None,
            _ =&gt; {
                let parsed = parse_input(input);
                if let Ok(out) = parsed {
                    return Some(out);
                }
            }
        }
    }
}


Note that this prevents some errors that were possible before. For example you could have missed to set out and accidentally returned None instead of Some, e.g.

    // ...
    _ =&gt; {
        let parsed = parse_input(input);
        if let Ok(_) = parsed {
            valid = true;
            // whoops forgot out
        }
    }


This erroneous state cannot happen now.

Also note that we now have a simple loop. We don't have any mut bindings, only a single if let is left. Also note that we don't need to unwrap parsed: if parsed is an Ok(out), we can use that out.

That being said, you should add an error message after the match, e.g.

match input.trim() {
    // same as above
}
println!("Your input could not get parsed. Please write space-separated numbers or 'q' to quit");