1use colored::Colorize;
2use std::{
3 fmt::Display,
4 io::{self, Write},
5 str::FromStr,
6};
7
8pub enum CompareResult {
9 Less,
10 Greater,
11 Equal,
12}
13
14pub trait Compare {
15 fn cmp(&self, other: &f64) -> CompareResult;
16}
17
18impl Compare for f64 {
19 fn cmp(&self, other: &f64) -> CompareResult {
20 if (*self - other).abs() < 1e-9 {
21 CompareResult::Equal
22 } else if *self < *other {
23 CompareResult::Less
24 } else {
25 CompareResult::Greater
26 }
27 }
28}
29
30pub fn trim_quotes(val: &str) -> String {
41 let mut trimmed = String::from(val);
42
43 let quote_start = val.find("\"");
44
45 if let Some(start) = quote_start {
46 let quote_end = val.rfind("\"");
47
48 if let Some(end) = quote_end {
49 trimmed = String::from(&val[start + 1..end]);
50 }
51 }
52
53 trimmed
54}
55
56pub fn number_pad(num: u32, min_length: usize) -> String {
71 let num_str = num.to_string();
72
73 let padding = min_length - num_str.len();
74
75 let mut result = String::new();
76
77 for _ in 0..padding {
78 result.push_str(" ");
79 }
80
81 result.push_str(&num_str);
82
83 result
84}
85
86pub fn request_value<T>(value: &mut T, message: &str)
87where
88 T: FromStr + Display,
89 <T as FromStr>::Err: std::fmt::Debug,
90{
91 printf(&format!(
92 "{message} {}",
93 value.to_string().truecolor(125, 125, 125)
94 ));
95
96 printf(&format!("\x1B[{}D", value.to_string().len()));
97
98 let mut input = String::new();
99
100 io::stdin().read_line(&mut input).unwrap();
101
102 input = input.trim().to_string();
103
104 if !input.is_empty() {
105 *value = input.parse::<T>().unwrap();
106 }
107}
108
109pub fn printf(message: &str) {
110 print!("{message}");
111 io::stdout().flush().unwrap();
112}
113
114pub enum Answer {
115 Yes,
116 No,
117}
118
119impl Answer {
120 pub fn to_string(&self) -> String {
121 match self {
122 Answer::Yes => String::from("y"),
123 Answer::No => String::from("N"),
124 }
125 }
126}
127
128pub fn ask_yes_no(question: &str, default: Answer) -> Answer {
130 let default_string = default.to_string();
131
132 printf(&format!(
133 "{question} y/N? {}",
134 default_string.truecolor(125, 125, 125)
135 ));
136
137 printf(&format!("\x1B[{}D", default_string.len()));
139
140 let mut input = String::new();
141
142 io::stdin().read_line(&mut input).unwrap();
143
144 match input.trim().to_lowercase().as_str() {
145 "y" | "yes" => Answer::Yes,
146 "n" | "no" => Answer::No,
147 _ => default,
148 }
149}