use super::macros::impl_with_validator;
use crate::{InteractionEnvironment, InteractionError};
use l10n_embed::Localize;
struct PasswordConfirmation {
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 mut localized_prompt = String::new();
prompt.localize(&environment.localization_context, &mut localized_prompt);
Self {
environment,
prompt: localized_prompt,
confirmation: None,
validator: None,
}
}
pub fn with_confirmation<L1: Localize, L2: Localize>(
mut self,
confirmation_prompt: L1,
mismatch_error: L2,
) -> Self {
let mut localized_prompt = String::new();
confirmation_prompt.localize(
&self.environment.localization_context,
&mut localized_prompt,
);
let mut localized_mismatch_error = String::new();
mismatch_error.localize(
&self.environment.localization_context,
&mut localized_mismatch_error,
);
self.confirmation = Some(PasswordConfirmation {
prompt: localized_prompt,
mismatch_error: localized_mismatch_error,
});
self
}
pub fn interact(self) -> Result<Option<String>, InteractionError> {
match self.environment.interaction_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.prompt, confirmation.mismatch_error);
}
if let Some(validator) = self.validator {
prompt = prompt.validate_with(validator);
}
Ok(Some(prompt.interact()?))
}
crate::InteractionContext::NonInteractive => Ok(None),
}
}
}