passgenlib/lib.rs
1mod gen_engine;
2
3/// Main [Passgen] structure.
4///
5/// # Examples
6///
7/// You can create a token that includes lowercase letters and numbers up to 30 characters long:
8///
9/// ```
10/// use passgenlib::Passgen;
11/// let result = Passgen::new().set_enabled_letters(true).set_enabled_numbers(true).generate(30);
12/// ```
13///
14/// You can create a default strong password including all literals, numbers and symbols:
15///
16/// ```
17/// use passgenlib::Passgen;
18/// let result = Passgen::default().generate(12);
19/// ```
20///
21/// You can create a strong and usability password.
22/// Including all characters, but
23/// the first position in the password is a capital or small letter,
24/// the last position is the symbol.
25/// 🔸 Excluded ambiguous characters `"0oOiIlL1"`.
26///
27/// ```
28/// use passgenlib::Passgen;
29/// let result = Passgen::default_strong_and_usab().generate(8);
30/// ```
31/// You can create a set from your custom charset:
32///
33/// ```
34/// use passgenlib::Passgen;
35/// let result = Passgen::new().set_custom_charset("bla@.321").generate(8);
36/// ```
37pub struct Passgen {
38 /// Presence of letters.
39 pub enab_letters: bool,
40
41 /// Presence of a capital letters.
42 pub enab_u_letters: bool,
43
44 /// Presence of numeric characters.
45 pub enab_num: bool,
46
47 /// Presence of special characters.
48 pub enab_spec_symbs: bool,
49
50 /// Including all characters, but
51 /// the first position in the password is a capital or small letter,
52 /// the last position is the symbol. Excluded ambiguous characters `"0oOiIlL1"`.
53 ///
54 /// ⚠️ If this rule is enabled, the other consistency rules of the generating are not taken,
55 /// except for a rule `custom_charset`.
56 pub enab_strong_usab: bool,
57
58 /// User defined character set.
59 ///
60 /// ⚠️This set of characters will exclude all other rules except for a rule `"enab_strong_usab"`.
61 ///
62 /// ⚙️If `"enab_strong_usab"` on too then you can generate combined strong and usability result with custom charset.
63 pub custom_charset: &'static str,
64}
65
66impl Passgen {
67 /// Get an instance of `Passgen` without any rules.
68 pub fn new() -> Passgen {
69 Passgen {
70 enab_letters: false,
71 enab_u_letters: false,
72 enab_num: false,
73 enab_spec_symbs: false,
74 enab_strong_usab: false,
75 custom_charset: "",
76 }
77 }
78
79 /// Set default ruleset of `Passgen` to *"all simple rules are enabled"*.
80 pub fn default() -> Passgen {
81 Passgen {
82 enab_letters: true,
83 enab_u_letters: true,
84 enab_num: true,
85 enab_spec_symbs: true,
86 enab_strong_usab: false,
87 custom_charset: "",
88 }
89 }
90
91 /// Set default ruleset of `Passgen` to *"Strong & usability"*.
92 ///
93 /// Including all characters, but
94 /// the first position in the password is a capital or small letter,
95 /// the last position is the symbol. Excluded ambiguous characters `"0oOiIlL1"`.
96 ///
97 /// ⚠️ If this rule is enabled, the other consistency rules of the generating are not taken,
98 /// except for a rule `custom_charset`.
99 pub fn default_strong_and_usab() -> Passgen {
100 Passgen {
101 enab_letters: false,
102 enab_u_letters: false,
103 enab_num: false,
104 enab_spec_symbs: false,
105 custom_charset: "",
106 enab_strong_usab: true,
107 }
108 }
109
110 /// Set value of the field `enab_letters` for `Passgen`.
111 pub fn set_enabled_letters(&mut self, value: bool) -> &mut Passgen {
112 self.enab_letters = value;
113 self
114 }
115
116 /// Set value of the field `enab_u_letters` for `Passgen`.
117 pub fn set_enabled_uppercase_letters(&mut self, value: bool) -> &mut Passgen {
118 self.enab_u_letters = value;
119 self
120 }
121
122 /// Set value of the field `enab_num` for `Passgen`.
123 pub fn set_enabled_numbers(&mut self, value: bool) -> &mut Passgen {
124 self.enab_num = value;
125 self
126 }
127
128 /// Set value of the field `enab_spec_symbs` for `Passgen`.
129 pub fn set_enabled_spec_symbols(&mut self, value: bool) -> &mut Passgen {
130 self.enab_spec_symbs = value;
131 self
132 }
133
134 /// Set value of the field `enab_strong_usab` for `Passgen`.
135 ///
136 /// Including all characters, but
137 /// the first position in the password is a capital or small letter,
138 /// the last position is the symbol. Excluded ambiguous characters `"0oOiIlL1"`.
139 ///
140 /// ⚠️ If this rule is enabled, the other consistency rules of the generating are not taken,
141 /// except for a rule `custom_charset`.
142 pub fn set_enabled_strong_usab(&mut self, value: bool) -> &mut Passgen {
143 self.enab_strong_usab = value;
144 self
145 }
146
147 /// Set user defined character set.
148 /// You can use any Unicode characters and emoji. For example: abcABC123⭕➖❎⚫⬛n₼⁂🙂
149 ///
150 /// ⚠️This set of characters will exclude all other rules except for a rule `"enab_strong_usab"`.
151 ///
152 /// ⚙️If `"enab_strong_usab"` on too then you can generate combined strong and usability result with custom charset.
153 pub fn set_custom_charset(&mut self, value: &'static str) -> &mut Passgen {
154 self.custom_charset = value;
155 self
156 }
157
158 /// Generate result. Argument "length" will not be less than 4
159 pub fn generate(&mut self, length: u32) -> String {
160 if !self.is_ruleset_clean() {
161 let res_len = if length < 4 { 4 } else { length };
162
163 let mut pwd = self.generate_pass(res_len);
164
165 if self.custom_charset.len() == 0 {
166 while !self.is_valid_pwd_by_consist(pwd.clone()) {
167 pwd = self.generate_pass(res_len);
168 }
169 }
170 pwd
171 } else {
172 "".to_string()
173 }
174 }
175
176 fn is_ruleset_clean(&self) -> bool {
177 !self.enab_letters
178 && !self.enab_u_letters
179 && !self.enab_num
180 && !self.enab_spec_symbs
181 && !self.enab_strong_usab
182 && self.custom_charset.len() == 0
183 }
184}
185
186#[cfg(test)]
187mod tests {
188 use crate::Passgen;
189
190 #[test]
191 fn it_works() {
192 assert_eq!(Passgen::new().generate(4).len(), 0);
193 assert_ne!(
194 Passgen::new().set_enabled_letters(true).generate(4).len(),
195 0
196 );
197 assert_ne!(
198 Passgen::default()
199 .set_custom_charset("abcABC123⭕➖❎⚫⬛п₼⁂🙂")
200 .generate(4)
201 .len(),
202 0
203 );
204
205 assert_ne!(Passgen::default_strong_and_usab().generate(4).len(), 0);
206 }
207}