input_utils/
lib.rs

1use std::{
2    io::{self, Write},
3    str::FromStr,
4};
5
6/// Reads input from the standard input stream and attempts to parse it into the specified type.
7/// Continuously prompts for input until a valid input is entered.
8///
9/// # Arguments
10///
11/// * `prompt` - A string slice that holds the text to be displayed as a prompt before reading input.
12/// * `err` - A string slice that holds the text to be displayed as an error message if parsing fails.
13///
14/// # Returns
15///
16/// Returns the parsed value of type `T` if parsing is successful. If parsing fails, the function will
17/// continue to prompt for input and display the error message until a valid input is entered.
18///
19/// # Example
20///
21/// ```
22/// let age: u32 = read_input("Enter your age: ", "Invalid input. Please enter a valid age.");
23/// println!("Your age is {}", age);
24/// ```
25///
26/// # Panics
27///
28/// The function will panic if flushing stdout or reading from stdin fails.
29pub fn read_input<T: FromStr>(prompt: &str, err: &str) -> T {
30    loop {
31        print!("{}", prompt);
32        io::stdout().flush().expect("Failed to flush stdout");
33        let mut input = String::new();
34        io::stdin()
35            .read_line(&mut input)
36            .expect("Failed to read line");
37        print!("\n");
38        match input.trim().parse() {
39            Ok(parsed_input) => break parsed_input,
40            Err(_) => eprintln!("{}", err),
41        }
42    }
43}