use super::macros::impl_with_validator;
use crate::{InteractionEnvironment, InteractionError};
use l10n_embed::Localize;
struct PasswordConfirmation {
localized_prompt: String,
mismatch_error: String,
}
pub struct Password<'environment> {
environment: &'environment InteractionEnvironment,
prompt: String,
confirmation: Option<PasswordConfirmation>,
validator: Option<Box<dyn Fn(&String) -> Result<(), String>>>,
}
impl_with_validator!(Password);
impl<'environment> Password<'environment> {
pub fn new<L: Localize>(
environment: &'environment InteractionEnvironment,
prompt: L,
) -> Self {
let localized_prompt = prompt.localize_for(&environment.locale);
Self {
environment,
prompt: localized_prompt,
confirmation: None,
validator: None,
}
}
pub fn with_confirmation<L1: Localize, L2: Localize>(
mut self,
confirmation: L1,
mismatch_error: L2,
) -> Self {
let confirmation_text = confirmation.localize_for(&self.environment.locale);
let mismatch_error_text = mismatch_error.localize_for(&self.environment.locale);
self.confirmation = Some(PasswordConfirmation {
localized_prompt: confirmation_text,
mismatch_error: mismatch_error_text,
});
self
}
pub fn interact(self) -> Result<Option<String>, InteractionError> {
match self.environment.context {
crate::InteractionContext::Terminal => {
let mut prompt =
dialoguer::Password::with_theme(&*super::THEME).with_prompt(self.prompt);
if let Some(confirmation) = self.confirmation {
prompt = prompt.with_confirmation(
confirmation.localized_prompt,
confirmation.mismatch_error,
);
}
if let Some(validator) = self.validator {
prompt = prompt.validate_with(validator);
}
Ok(Some(prompt.interact()?))
}
crate::InteractionContext::NonInteractive => Ok(None),
}
}
}