pwgen/
lib.rs

1//! Auxiliary functions to generate passwords.
2use rand::{distributions::Alphanumeric, thread_rng, Rng};
3
4/// Returns password containing alphanumeric chars.
5fn alphanum(length: u8) -> String {
6    let mut rng = thread_rng();
7    (0..length)
8        .filter_map(|_| -> Option<char> { rng.sample(Alphanumeric).try_into().ok() })
9        .collect()
10}
11
12/// Returns password containing ascii chars ranging from '0' to '9'.
13/// In other words, digits.
14fn pin(length: u8) -> String {
15    let mut rng = thread_rng();
16    (0..length)
17        .filter_map(|_| -> Option<char> { rng.gen_range(b'0'..=b'9').try_into().ok() })
18        .collect()
19}
20
21/// Returns password containing ascii chars ranging from '!' to '~'.
22/// In other words, alphanum + symbols.
23fn everything(length: u8) -> String {
24    let mut rng = thread_rng();
25    (0..length)
26        .filter_map(|_| -> Option<char> { rng.gen_range(b'!'..=b'~').try_into().ok() })
27        .collect()
28}
29
30/// Generate random passwords.
31///
32/// `option` sets the password type. It can be `pin`, `alpha` or `full`. `length` sets the password length.
33///
34/// # Examples
35///
36/// ```
37/// use pwgen::generate;
38///
39/// let pw = generate("pin", 8);
40///
41/// assert_eq!(pw.len(), 8);
42/// assert!(pw.chars().all(|ch| ch.is_ascii_digit()));
43/// ```
44#[inline]
45#[must_use]
46pub fn generate(option: &str, length: u8) -> String {
47    match option {
48        "pin" => pin(length),
49        "full" => everything(length),
50        &_ => alphanum(length),
51    }
52}
53
54#[cfg(test)]
55mod tests;