Skip to content

Commit c3774c0

Browse files
committed
Add PasswordValidator trait
1 parent 09e2ff1 commit c3774c0

File tree

3 files changed

+34
-9
lines changed

3 files changed

+34
-9
lines changed

examples/password.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ fn main() {
44
let password = Password::with_theme(&ColorfulTheme::default())
55
.with_prompt("Password")
66
.with_confirmation("Repeat password", "Error: the passwords don't match.")
7-
.validate_with(|input: &String| -> Result<(), &str> {
7+
.validate_with(|input: &str| -> Result<(), &str> {
88
if input.len() > 3 {
99
Ok(())
1010
} else {

src/prompts/password.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
use std::io;
22

3-
use crate::theme::{SimpleTheme, TermThemeRenderer, Theme};
3+
use crate::{
4+
theme::{SimpleTheme, TermThemeRenderer, Theme},
5+
validate::PasswordValidator,
6+
};
47

58
use console::Term;
69
use zeroize::Zeroizing;
710

8-
type PasswordValidatorCallback<'a> = Box<dyn Fn(&String) -> Option<String> + 'a>;
11+
type PasswordValidatorCallback<'a> = Box<dyn Fn(&str) -> Option<String> + 'a>;
912

1013
/// Renders a password input prompt.
1114
///
@@ -84,7 +87,7 @@ impl<'a> Password<'a> {
8487
/// # use dialoguer::Password;
8588
/// let password: String = Password::new()
8689
/// .with_prompt("Enter password")
87-
/// .validate_with(|input: &String| -> Result<(), &str> {
90+
/// .validate_with(|input: &str| -> Result<(), &str> {
8891
/// if input.len() > 8 {
8992
/// Ok(())
9093
/// } else {
@@ -94,21 +97,21 @@ impl<'a> Password<'a> {
9497
/// .interact()
9598
/// .unwrap();
9699
/// ```
97-
pub fn validate_with<V, E>(&mut self, validator: V) -> &mut Self
100+
pub fn validate_with<V>(&mut self, validator: V) -> &mut Self
98101
where
99-
V: Fn(&String) -> Result<(), E> + 'a,
100-
E: ToString,
102+
V: PasswordValidator + 'a,
103+
V::Err: ToString,
101104
{
102105
let old_validator_func = self.validator.take();
103106

104-
self.validator = Some(Box::new(move |value: &String| -> Option<String> {
107+
self.validator = Some(Box::new(move |value: &str| -> Option<String> {
105108
if let Some(old) = &old_validator_func {
106109
if let Some(err) = old(value) {
107110
return Some(err);
108111
}
109112
}
110113

111-
match validator(value) {
114+
match validator.validate(value) {
112115
Ok(()) => None,
113116
Err(err) => Some(err.to_string()),
114117
}

src/validate.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,25 @@ where
2424
self(input)
2525
}
2626
}
27+
28+
/// Trait for password validators.
29+
pub trait PasswordValidator {
30+
type Err;
31+
32+
/// Invoked with the value to validate.
33+
///
34+
/// If this produces `Ok(())` then the value is used and parsed, if
35+
/// an error is returned validation fails with that error.
36+
fn validate(&self, input: &str) -> Result<(), Self::Err>;
37+
}
38+
39+
impl<F, E> PasswordValidator for F
40+
where
41+
F: Fn(&str) -> Result<(), E>,
42+
{
43+
type Err = E;
44+
45+
fn validate(&self, input: &str) -> Result<(), Self::Err> {
46+
self(input)
47+
}
48+
}

0 commit comments

Comments
 (0)