prompt_input/
primitive.rs1use std::io::{self, Write};
2
3pub trait Promptable {
4 fn prompt(output: &str) -> Self;
5}
6
7pub trait PromptableWithOption
8where
9 Self: Sized,
10{
11 fn prompt(output: &str) -> Option<Self>;
12}
13
14pub trait PromptableWithAlternatives
15where
16 Self: Sized,
17{
18 fn prompt(output: &str, trues: Vec<&str>, falses: Vec<&str>) -> Option<Self>;
19}
20
21impl Promptable for String {
22 fn prompt(output: &str) -> Self {
23 print!("{}", output);
24 io::stdout().flush().unwrap();
25
26 let mut input = String::new();
27 io::stdin()
28 .read_line(&mut input)
29 .expect("Failed to read the prompt");
30
31 input.trim().to_string()
32 }
33}
34
35impl PromptableWithAlternatives for bool {
36 fn prompt(output: &str, trues: Vec<&str>, falses: Vec<&str>) -> Option<Self> {
37 let input = String::prompt(output).to_lowercase();
38
39 let mapped_trues: Vec<String> = trues.into_iter().map(|w| w.to_lowercase()).collect();
40 let mapped_falses: Vec<String> = falses.into_iter().map(|w| w.to_lowercase()).collect();
41
42 if mapped_trues.contains(&input) {
43 return Some(true);
44 }
45
46 if mapped_falses.contains(&input) {
47 return Some(false);
48 }
49
50 return None;
51 }
52}
53
54macro_rules! create_promptable_with_option {
55 ($($type:ty), *) => {
56 $(
57 impl PromptableWithOption for $type {
58 fn prompt(output: &str) -> Option<Self> {
59 let input = String::prompt(output);
60
61 input.parse().ok()
62 }
63 }
64 )*
65 };
66}
67
68create_promptable_with_option!(
69 i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, isize, usize, f32, f64, char
70);