Rust implementation of the animal guessing game, where the computer learns about animals and then guesses them with yes/no answers.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
animals.rs/src/prompt.rs

74 lines
1.6 KiB

use std::io;
use std::io::Write;
use std::str::FromStr;
fn flush() {
io::stdout().flush().expect("Failed to flush stdout");
}
struct YesNo(bool);
struct YesNoParseError();
impl From<YesNo> for bool {
fn from(yn: YesNo) -> Self {
yn.0
}
}
impl FromStr for YesNo {
type Err = YesNoParseError;
fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
match s {
"true" => Ok(YesNo(true)),
"y" => Ok(YesNo(true)),
"1" => Ok(YesNo(true)),
"yes" => Ok(YesNo(true)),
"a" => Ok(YesNo(true)),
"false" => Ok(YesNo(false)),
"f" => Ok(YesNo(false)),
"no" => Ok(YesNo(false)),
"n" => Ok(YesNo(false)),
"0" => Ok(YesNo(false)),
_ => Err(YesNoParseError()),
}
}
}
pub fn ask_yn(prompt: &str) -> Option<bool> {
match ask::<YesNo>(prompt) {
Some(yn) => Some(yn.into()),
None => None,
}
}
pub fn ask<T>(prompt: &str) -> Option<T>
where
T: FromStr,
{
let mut buf = String::new();
loop {
print!("{}", prompt);
flush();
buf.clear();
io::stdin()
.read_line(&mut buf)
.expect("Failed to read line");
let s = buf.trim();
if s.is_empty() {
println!(); // empty string returns None as a signal to terminate the program
break None;
}
match s.parse() {
Ok(val) => {
break Some(val);
}
Err(_) => {
println!("Could not parse \"{}\", please try again.", s);
}
};
}
}