cetus_utils/
inquire_parser.rs1use inquire::validator::{ErrorMessage, Validation};
2use inquire::{Confirm, Text};
3use rust_decimal::Decimal;
4use std::fs::File;
5use std::str::FromStr;
6
7pub trait Parser {
8 fn to_u128(self) -> Result<u128, Box<dyn std::error::Error>>;
9 fn to_u64(self) -> Result<u64, Box<dyn std::error::Error>>;
10 fn to_u16(self) -> Result<u16, Box<dyn std::error::Error>>;
11 fn to_f64(self) -> Result<f64, Box<dyn std::error::Error>>;
12 fn to_file(self) -> Result<String, Box<dyn std::error::Error>>;
13 fn to_string(self) -> Result<String, Box<dyn std::error::Error>>;
14 fn to_decimal(self) -> Result<Decimal, Box<dyn std::error::Error>>;
15 fn confirm() -> Result<(), Box<dyn std::error::Error>>;
16 fn confirm_with_prompt(message: &str) -> Result<(), Box<dyn std::error::Error>>;
17}
18
19impl Parser for Text<'_> {
20 fn to_u128(self) -> Result<u128, Box<dyn std::error::Error>> {
21 let s = self
22 .with_validator(|s: &str| match s.parse::<u128>().is_err() {
23 true => Ok(Validation::Invalid(ErrorMessage::Custom(
24 "wrong number with u128".to_string(),
25 ))),
26 false => Ok(Validation::Valid),
27 })
28 .prompt()?;
29 Ok(s.parse::<u128>().unwrap())
30 }
31
32 fn to_u64(self) -> Result<u64, Box<dyn std::error::Error>> {
33 let s = self
34 .with_validator(|s: &str| match s.parse::<u64>().is_err() {
35 true => Ok(Validation::Invalid(ErrorMessage::Custom(
36 "wrong number with u64".to_string(),
37 ))),
38 false => Ok(Validation::Valid),
39 })
40 .prompt()?;
41 Ok(s.parse::<u64>().unwrap())
42 }
43
44 fn to_u16(self) -> Result<u16, Box<dyn std::error::Error>> {
45 let s = self
46 .with_validator(|s: &str| match s.parse::<u16>().is_err() {
47 true => Ok(Validation::Invalid(ErrorMessage::Custom(
48 "wrong number with u16".to_string(),
49 ))),
50 false => Ok(Validation::Valid),
51 })
52 .prompt()?;
53 Ok(s.parse::<u16>().unwrap())
54 }
55
56 fn to_f64(self) -> Result<f64, Box<dyn std::error::Error>> {
57 let s = self
58 .with_validator(|s: &str| match s.parse::<f64>().is_err() {
59 true => Ok(Validation::Invalid(ErrorMessage::Custom(
60 "wrong number with f64".to_string(),
61 ))),
62 false => Ok(Validation::Valid),
63 })
64 .prompt()?;
65 Ok(s.parse::<f64>().unwrap())
66 }
67
68 fn to_file(self) -> Result<String, Box<dyn std::error::Error>> {
69 let s = self
70 .with_validator(|s: &str| match File::open(s).is_err() {
71 true => Ok(Validation::Invalid(ErrorMessage::Custom(
72 "wrong file path".to_string(),
73 ))),
74 false => Ok(Validation::Valid),
75 })
76 .prompt()?;
77 Ok(s)
78 }
79
80 fn to_string(self) -> Result<String, Box<dyn std::error::Error>> {
81 Ok(self.prompt()?)
82 }
83
84 fn to_decimal(self) -> Result<Decimal, Box<dyn std::error::Error>> {
85 let s = self
86 .with_validator(|s: &str| match Decimal::from_str(s).is_err() {
87 true => Ok(Validation::Invalid(ErrorMessage::Custom(
88 "wrong decimal".to_string(),
89 ))),
90 false => Ok(Validation::Valid),
91 })
92 .prompt()?;
93 Ok(Decimal::from_str(s.as_str()).unwrap())
94 }
95
96 fn confirm() -> Result<(), Box<dyn std::error::Error>> {
97 let res = Confirm::new("Confirm this operation?")
98 .with_default(false)
99 .prompt();
100 match res {
101 Ok(true) => Ok(()),
102 Ok(false) => Err(Box::<dyn std::error::Error>::from("Cancel the operation")),
103 Err(_) => Err(Box::new(res.err().unwrap())),
104 }
105 }
106
107 fn confirm_with_prompt(message: &str) -> Result<(), Box<dyn std::error::Error>> {
108 let res = Confirm::new(message).with_default(false).prompt();
109 match res {
110 Ok(true) => Ok(()),
111 Ok(false) => Err(Box::<dyn std::error::Error>::from("Cancel the operation")),
112 Err(_) => Err(Box::new(res.err().unwrap())),
113 }
114 }
115}