inquire/formatter.rs
1//! Type aliases and default implementations for functions called as formatters
2//! of a given input.
3//!
4//! Formatters receive the user input to a given prompt and return a formatted
5//! output `String`, which is displayed to the user as the submitted value.
6//!
7//! # Example
8//!
9//! **Prompt code**
10//!
11//! ```no_run
12//! use inquire::formatter::StringFormatter;
13//! use inquire::Text;
14//!
15//! let formatter: StringFormatter = &|s| {
16//! let mut c = s.chars();
17//! match c.next() {
18//! None => String::from("No name given"),
19//! Some(f) => {
20//! String::from("My name is ")
21//! + f.to_uppercase().collect::<String>().as_str()
22//! + c.as_str()
23//! }
24//! }
25//! };
26//!
27//! let name = Text::new("What's your name?")
28//! .with_formatter(formatter)
29//! .prompt();
30//!
31//! match name {
32//! Ok(_) => {}
33//! Err(err) => println!("Error: {}", err),
34//! }
35//! ```
36//!
37//! **Before submission (pressing Enter)**
38//!
39//! ```text
40//! ? What's your name? mikael
41//! ```
42//!
43//! **After submission**
44//!
45//! ```text
46//! ? What's your name? My name is Mikael
47//! ```
48
49use crate::list_option::ListOption;
50
51/// Type alias for formatters that receive a string slice as the input,
52/// required by [Text](crate::Text) and [Password](crate::Password) for example.
53///
54/// Formatters receive the user input and return a [String] to be displayed
55/// to the user as the final answer.
56///
57/// # Examples
58///
59/// ```
60/// use inquire::formatter::StringFormatter;
61///
62/// let formatter: StringFormatter = &|i| i.to_lowercase();
63/// assert_eq!(String::from("times square"), formatter("Times Square"));
64/// assert_eq!(String::from("times square"), formatter("times square"));
65/// ```
66pub type StringFormatter<'a> = &'a dyn Fn(&str) -> String;
67
68/// Type alias for formatters used in [Confirm](crate::Confirm) prompts.
69///
70/// Formatters receive the user input and return a [String] to be displayed
71/// to the user as the final answer.
72///
73/// # Examples
74///
75/// ```
76/// use inquire::formatter::BoolFormatter;
77///
78/// let formatter: BoolFormatter = &|i| match i {
79/// true => String::from("si"),
80/// false => String::from("no"),
81/// };
82/// assert_eq!(String::from("si"), formatter(true));
83/// assert_eq!(String::from("no"), formatter(false));
84/// ```
85pub type BoolFormatter<'a> = &'a dyn Fn(bool) -> String;
86
87/// Type alias for formatters used in [Select](crate::Select) prompts.
88///
89/// Formatters receive the user input and return a [String] to be displayed
90/// to the user as the final answer.
91///
92/// # Examples
93///
94/// ```
95/// use inquire::list_option::ListOption;
96/// use inquire::formatter::OptionFormatter;
97///
98/// let formatter: OptionFormatter<str> = &|i| format!("Option {}: '{}'", i.index + 1, i.value);
99/// assert_eq!(String::from("Option 1: 'a'"), formatter(ListOption::new(0, "a")));
100/// assert_eq!(String::from("Option 2: 'b'"), formatter(ListOption::new(1, "b")));
101/// ```
102pub type OptionFormatter<'a, T> = &'a dyn Fn(ListOption<&T>) -> String;
103
104/// Type alias for formatters used in [`MultiSelect`](crate::MultiSelect) prompts.
105///
106/// Formatters receive the user input and return a [String] to be displayed
107/// to the user as the final answer.
108///
109/// # Examples
110///
111/// ```
112/// use inquire::list_option::ListOption;
113/// use inquire::formatter::MultiOptionFormatter;
114///
115/// let formatter: MultiOptionFormatter<str> = &|opts| {
116/// let len = opts.len();
117/// let options = match len {
118/// 1 => "option",
119/// _ => "options",
120/// };
121/// format!("You selected {} {}", len, options)
122/// };
123///
124/// let mut ans = vec![ListOption::new(0, "a")];
125/// assert_eq!(String::from("You selected 1 option"), formatter(&ans));
126///
127/// ans.push(ListOption::new(3, "d"));
128/// assert_eq!(String::from("You selected 2 options"), formatter(&ans));
129/// ```
130pub type MultiOptionFormatter<'a, T> = &'a dyn Fn(&[ListOption<&T>]) -> String;
131
132/// Type alias for formatters used in [`CustomType`](crate::CustomType) prompts.
133///
134/// Formatters receive the user input and return a [String] to be displayed
135/// to the user as the final answer.
136///
137/// # Examples
138///
139/// ```
140/// use inquire::CustomType;
141/// use inquire::formatter::CustomTypeFormatter;
142///
143/// let formatter: CustomTypeFormatter<f64> = &|i| format!("${:.2}", i);
144///
145/// assert_eq!(String::from("$12.33"), formatter(12.33));
146/// assert_eq!(String::from("$44.91"), formatter(44.9123));
147/// assert_eq!(String::from("$45.00"), formatter(44.998));
148/// ```
149pub type CustomTypeFormatter<'a, T> = &'a dyn Fn(T) -> String;
150
151#[cfg(feature = "date")]
152
153/// Type alias for formatters used in [`DateSelect`](crate::DateSelect) prompts.
154///
155/// Formatters receive the user input and return a [String] to be displayed
156/// to the user as the final answer.
157///
158/// # Examples
159///
160/// ```
161/// use chrono::NaiveDate;
162/// use inquire::formatter::DateFormatter;
163///
164/// let formatter: DateFormatter = &|val| val.format("%d/%m/%Y").to_string();
165///
166/// assert_eq!(
167/// String::from("25/07/2021"),
168/// formatter(NaiveDate::from_ymd(2021, 7, 25)),
169/// );
170/// ```
171pub type DateFormatter<'a> = &'a dyn Fn(chrono::NaiveDate) -> String;
172
173/// String formatter used by default in inputs that return a `String` as input.
174/// Its behavior is to just echo the received input.
175///
176/// # Examples
177///
178/// ```
179/// use inquire::formatter::DEFAULT_STRING_FORMATTER;
180///
181/// let formatter = DEFAULT_STRING_FORMATTER;
182/// assert_eq!(String::from("Times Square"), formatter("Times Square"));
183/// assert_eq!(String::from("times sQuare"), formatter("times sQuare"));
184/// ```
185pub const DEFAULT_STRING_FORMATTER: StringFormatter = &|val| String::from(val);
186
187/// String formatter used by default in [Confirm](crate::Confirm) prompts.
188/// Translates `bool` to `"Yes"` and `false` to `"No"`.
189///
190/// # Examples
191///
192/// ```
193/// use inquire::formatter::DEFAULT_BOOL_FORMATTER;
194///
195/// let formatter = DEFAULT_BOOL_FORMATTER;
196/// assert_eq!(String::from("Yes"), formatter(true));
197/// assert_eq!(String::from("No"), formatter(false));
198/// ```
199pub const DEFAULT_BOOL_FORMATTER: BoolFormatter = &|ans| {
200 if ans {
201 String::from("Yes")
202 } else {
203 String::from("No")
204 }
205};
206
207#[cfg(feature = "date")]
208/// String formatter used by default in [`DateSelect`](crate::DateSelect) prompts.
209/// Prints the selected date in the format: Month Day, Year.
210///
211/// # Examples
212///
213/// ```
214/// use chrono::NaiveDate;
215/// use inquire::formatter::DEFAULT_DATE_FORMATTER;
216///
217/// let formatter = DEFAULT_DATE_FORMATTER;
218///
219/// assert_eq!(
220/// String::from("July 25, 2021"),
221/// formatter(NaiveDate::from_ymd(2021, 7, 25)),
222/// );
223/// assert_eq!(
224/// String::from("January 1, 2021"),
225/// formatter(NaiveDate::from_ymd(2021, 1, 1)),
226/// );
227/// ```
228pub const DEFAULT_DATE_FORMATTER: DateFormatter = &|val| val.format("%B %-e, %Y").to_string();