High-level stdin casting

I think Rust is very much missing a high-level input functionality similar to Python's input. Goals are to have a simple beginner-friendly function to start an stdin loop and cast it to a specified type. I'm a Rust apprentice, but with some guidance can lead this implementation. Here's a simple boilerplate library implementation.

use std::io::{self, Write};
use std::str::FromStr;
use std::error::Error;
use std::fmt::Debug;

pub fn input<T: FromStr, S: Into<Option<&'static str>>>(prompt: S) -> Result<T, Box<dyn Error>>
where
    T::Err: Error + 'static + Debug {
    let prompt = prompt.into();  // Convert S into Option<&'static str>

    if let Some(p) = prompt {
        print!("{}", p);  // Print the prompt if it's Some
        io::stdout().flush()?;
    }

    let mut input = String::new();
    loop {
        io::stdin().read_line(&mut input).map_err(|e| e.to_string())?;

        match input.trim().parse::<T>() {
            Ok(val) => return Ok(val),
            Err(_) => {
                input.clear();
            },
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn get_int() {
        let i: i32 = input(None).unwrap();
        println!("{}", i);
        let j: i32 = input(None).unwrap();
        println!("{}", j);

    }

    #[test]
    fn get_int_2() {
        let i: i32 = input("Input: ").unwrap();
        print!("Output: {}", i);
    }

    #[test]
    fn hacker_rank() {
        let s: String = input(None).unwrap();
        println!("hello, {}", s);
    }

}

Have you seen RFC: Add std::io::inputln() by not-my-profile · Pull Request #3196 · rust-lang/rfcs · GitHub ?

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.