Make `Extension` non-exhaustive
[ouch.git] / src / dialogs.rs
blobdbf6a73a1ce93034bb1cb78c071daa116140bbfd
1 //! Pretty (and colored) dialog for asking [Y/n] for the end user.
2 //!
3 //! Example:
4 //!   "Do you want to overwrite 'archive.tar.gz'? [Y/n]"
6 use std::{
7     borrow::Cow,
8     io::{self, Write},
9 };
11 use crate::utils::colors;
13 /// Confirmation dialog for end user with [Y/n] question.
14 ///
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'?"
19     pub prompt: &'a str,
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 }
30     }
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)),
38         };
40         // Ask the same question to end while no valid answers are given
41         loop {
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();
49             match answer.trim() {
50                 "" | "y" | "yes" => return Ok(true),
51                 "n" | "no" => return Ok(false),
52                 _ => continue, // Try again
53             }
54         }
55     }