use std::{io::{stdin, stdout, Write}, str::FromStr}; pub fn prompt(prompt_text: &str) -> Vec { let stdin = stdin(); let mut stdout = stdout(); print!("{prompt_text} "); let _ = stdout.flush(); let mut buffer = String::new(); if let Ok(_) = stdin.read_line(&mut buffer) { return buffer.trim_end().split([' ', ',']).map(|s| s.to_string()).collect(); } Vec::new() } pub fn prompt_yes_no(prompt_text: &str) -> bool { loop { let response = prompt(&format!("{prompt_text} (Y/N)")); if response.len() == 0 { continue; } let first_word = response[0].to_uppercase(); if first_word.starts_with("Y") { return true; } if first_word.starts_with("N") { return false; } } } pub fn prompt_value(prompt_text: &str, min: T, max: T) -> Option { let passed = prompt(prompt_text); if passed.len() != 1 { return None } match passed[0].parse::() { Ok(n) if (n >= min && n <= max) => Some(n), _ => None } } pub fn param_or_prompt_value(params: &Vec, param_pos: usize, prompt_text: &str, min: T, max: T) -> Option { let mut res: Option = None; if params.len() > param_pos { match params[param_pos].parse::() { Ok(n) if (n >= min && n <= max) => res = Some(n), _ => () } } if res.is_some() { return res; } return prompt_value::(prompt_text, min, max); } pub fn prompt_two_values(prompt_text: &str, min: T, max: T) -> Option<(T, T)> { let passed = prompt(prompt_text); if passed.len() != 2 { return None } match passed[0].parse::() { Ok(n1) if (n1 >= min && n1 <= max) => { match passed[1].parse::() { Ok(n2) if (n2 >= min && n2 <= max) => Some((n1, n2)), _ => None } } _ => None } }