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/// Type alias for formatters used in [`DateSelect`](crate::DateSelect) prompts.
152///
153/// Formatters receive the user input and return a [String] to be displayed
154/// to the user as the final answer.
155///
156/// # Examples
157///
158/// ```
159/// use chrono::NaiveDate;
160/// use inquire::formatter::DateFormatter;
161///
162/// let formatter: DateFormatter = &|val| val.format("%d/%m/%Y").to_string();
163///
164/// assert_eq!(
165///     String::from("25/07/2021"),
166///     formatter(NaiveDate::from_ymd(2021, 7, 25)),
167/// );
168/// ```
169#[cfg(feature = "date")]
170pub type DateFormatter<'a> = &'a dyn Fn(chrono::NaiveDate) -> String;
171
172/// String formatter used by default in inputs that return a `String` as input.
173/// Its behavior is to just echo the received input.
174///
175/// # Examples
176///
177/// ```
178/// use inquire::formatter::DEFAULT_STRING_FORMATTER;
179///
180/// let formatter = DEFAULT_STRING_FORMATTER;
181/// assert_eq!(String::from("Times Square"), formatter("Times Square"));
182/// assert_eq!(String::from("times sQuare"), formatter("times sQuare"));
183/// ```
184pub const DEFAULT_STRING_FORMATTER: StringFormatter<'_> = &|val| String::from(val);
185
186/// String formatter used by default in [Confirm](crate::Confirm) prompts.
187/// Translates `bool` to `"Yes"` and `false` to `"No"`.
188///
189/// # Examples
190///
191/// ```
192/// use inquire::formatter::DEFAULT_BOOL_FORMATTER;
193///
194/// let formatter = DEFAULT_BOOL_FORMATTER;
195/// assert_eq!(String::from("Yes"), formatter(true));
196/// assert_eq!(String::from("No"), formatter(false));
197/// ```
198pub const DEFAULT_BOOL_FORMATTER: BoolFormatter<'_> = &|ans| {
199    if ans {
200        String::from("Yes")
201    } else {
202        String::from("No")
203    }
204};
205
206#[cfg(feature = "date")]
207/// String formatter used by default in [`DateSelect`](crate::DateSelect) prompts.
208/// Prints the selected date in the format: Month Day, Year.
209///
210/// # Examples
211///
212/// ```
213/// use chrono::NaiveDate;
214/// use inquire::formatter::DEFAULT_DATE_FORMATTER;
215///
216/// let formatter = DEFAULT_DATE_FORMATTER;
217///
218/// assert_eq!(
219///     String::from("July 25, 2021"),
220///     formatter(NaiveDate::from_ymd(2021, 7, 25)),
221/// );
222/// assert_eq!(
223///     String::from("January 1, 2021"),
224///     formatter(NaiveDate::from_ymd(2021, 1, 1)),
225/// );
226/// ```
227pub const DEFAULT_DATE_FORMATTER: DateFormatter<'_> = &|val| val.format("%B %-e, %Y").to_string();