| use anyhow::Result; |
| use colored::Colorize; |
|
|
| use crate::input::InputBuilder; |
|
|
| |
| pub struct ConfirmBuilder { |
| pub(crate) message: String, |
| pub(crate) default: Option<bool>, |
| } |
|
|
| impl ConfirmBuilder { |
| |
| |
| |
| |
| pub fn with_default(mut self, default: bool) -> Self { |
| self.default = Some(default); |
| self |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| pub fn prompt(self) -> Result<Option<bool>> { |
| let hint = match self.default { |
| Some(true) => "Y/n".to_string(), |
| Some(false) => "y/N".to_string(), |
| None => "y/n".to_string(), |
| }; |
|
|
| let message_with_hint = if cfg!(windows) { |
| format!("{} {}", self.message, hint) |
| } else { |
| format!("{} {}", self.message, hint.yellow()) |
| }; |
|
|
| loop { |
| let input_builder = InputBuilder { |
| message: message_with_hint.clone(), |
| allow_empty: true, |
| default: None, |
| default_display: None, |
| }; |
|
|
| let result = input_builder.prompt()?; |
|
|
| |
| if result.is_none() { |
| return Ok(None); |
| } |
|
|
| let input = result.unwrap().trim().to_lowercase(); |
|
|
| |
| if input.is_empty() { |
| return Ok(Some(self.default.unwrap_or(false))); |
| } |
|
|
| |
| if input == "y" || input == "yes" { |
| return Ok(Some(true)); |
| } |
| if input == "n" || input == "no" { |
| return Ok(Some(false)); |
| } |
| } |
| } |
| } |
|
|