passg_lib/
generator.rs

1//! This module defines the type used to configure and generate passwords
2use derive_builder::Builder;
3use rand::Rng;
4
5use crate::charsets::{Alpha, CollatingSeq, Digit, Special};
6
7/// This is the structure you'll use to generate a random password
8#[derive(Debug, Builder)]
9pub struct Generator {
10    #[builder(default = "20")]
11    length: usize,
12    #[builder(default = "Alpha::Dist")]
13    alpha: Alpha,
14    #[builder(default = "Digit::Dist")]
15    digit: Digit,
16    #[builder(default = "Special::Basic")]
17    special: Special,
18}
19impl Default for Generator {
20    fn default() -> Self {
21        Generator {
22            length: 20,
23            alpha: Alpha::Dist,
24            digit: Digit::Dist,
25            special: Special::Basic,
26        }
27    }
28}
29impl Generator {
30    /// Generates a new random password as per specified configuration
31    pub fn generate(&self) -> String {
32        let charset = self.charset();
33        let mut out = String::new();
34        for _ in 0..self.length {
35            let idx = rand::thread_rng().gen_range(0..charset.len());
36            out.push(charset[idx]);
37        }
38        out
39    }
40    /// Returns a vector comprising only those characters that can be used to
41    /// generate a new password
42    fn charset(&self) -> Vec<char> {
43        let mut chars = vec![];
44
45        self.alpha
46            .characters()
47            .iter()
48            .copied()
49            .for_each(|c| chars.push(c));
50        self.digit
51            .characters()
52            .iter()
53            .copied()
54            .for_each(|c| chars.push(c));
55        self.special
56            .characters()
57            .iter()
58            .copied()
59            .for_each(|c| chars.push(c));
60
61        chars
62    }
63}