1 //! Pretty (and colored) dialog for asking [Y/n] for the end user.
4 //! "Do you want to overwrite 'archive.tar.gz'? [Y/n]"
11 use crate::utils::colors;
13 /// Confirmation dialog for end user with [Y/n] question.
15 /// If the placeholder is found in the prompt text, it will be replaced to form the final message.
16 pub struct Confirmation<'a> {
17 /// The message to be displayed with the placeholder text in it.
18 /// e.g.: "Do you want to overwrite 'FILE'?"
21 /// The placeholder text that will be replaced in the `ask` function:
22 /// e.g.: Some("FILE")
23 pub placeholder: Option<&'a str>,
26 impl<'a> Confirmation<'a> {
27 /// Creates a new Confirmation.
28 pub const fn new(prompt: &'a str, pattern: Option<&'a str>) -> Self {
29 Self { prompt, placeholder: pattern }
32 /// Creates user message and receives a boolean input to be used on the program
33 pub fn ask(&self, substitute: Option<&'a str>) -> crate::Result<bool> {
34 let message = match (self.placeholder, substitute) {
35 (None, _) => Cow::Borrowed(self.prompt),
36 (Some(_), None) => unreachable!("dev error, should be reported, we checked this won't happen"),
37 (Some(placeholder), Some(subs)) => Cow::Owned(self.prompt.replace(placeholder, subs)),
40 // Ask the same question to end while no valid answers are given
42 print!("{} [{}Y{}/{}n{}] ", message, *colors::GREEN, *colors::RESET, *colors::RED, *colors::RESET);
43 io::stdout().flush()?;
45 let mut answer = String::new();
46 io::stdin().read_line(&mut answer)?;
48 answer.make_ascii_lowercase();
50 "" | "y" | "yes" => return Ok(true),
51 "n" | "no" => return Ok(false),
52 _ => continue, // Try again