1pub mod formats;
2
3use tokio::io::{self, AsyncBufReadExt, BufReader};
4use crate::Format;
5
6pub async fn read_string_option(prompt: &str, format_checker: Format) -> Option<String> {
7 let mut reader = BufReader::new(io::stdin());
8 loop {
9 println!("{prompt}");
10 println!("(Leave empty and press Enter to set as None)");
11 let mut value = String::new();
12 match reader.read_line(&mut value).await {
13 Ok(_) => (),
14 Err(_) => continue
15 }
16
17 let value = value.trim();
18
19 if value.is_empty() {
20 return None
21 }
22
23 if format_checker.valid(value) {
24 return Some(value.to_string());
25 } else {
26 println!("invalid input");
27 }
28 }
29}
30
31pub async fn read_string(prompt: &str, format_checker: Format, default: Option<String>) -> String {
32 let mut reader = BufReader::new(io::stdin());
33 loop {
34 println!("{prompt}");
35 let mut value = String::new();
36 match reader.read_line(&mut value).await {
37 Ok(_) => (),
38 Err(_) => continue
39 }
40
41 let value = value.trim();
42
43 if value.is_empty() && let Some(default) = default {
44 return default;
45 }
46
47 if format_checker.valid(value) {
48 return value.to_string();
49 } else {
50 println!("invalid input");
51 }
52 }
53}
54
55pub async fn read_int(prompt: &str) -> i32 {
56 let mut reader = BufReader::new(io::stdin());
57 loop {
58 println!("{prompt}");
59 let mut value = String::new();
60 match reader.read_line(&mut value).await {
61 Ok(_) => (),
62 Err(_) => continue
63 }
64
65 let value = value.trim();
66
67 match value.parse() {
68 Ok(value) => {
69 return value
70 },
71 Err(_) => {
72 println!("invalid input");
73 continue;
74 }
75 };
76 }
77}