passg_lib/
charsets.rs

1//! This module configures the collating sequences (aka charsets) that are
2//! available for generating a pseudo-random password.
3use std::str::FromStr;
4
5use crate::errors::Error;
6
7// -----------------------------------------------------------------------------
8// GLOBAL CONSTANTS
9// -----------------------------------------------------------------------------
10
11/// The empty charset
12static NONE: [char; 0] = [];
13/// The lowercase alphabetic
14static ALPHA_LOWER: [char; 26] = [
15    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
16    't', 'u', 'v', 'w', 'x', 'y', 'z',
17];
18/// The upper case alphabetic
19static ALPHA_UPPER: [char; 26] = [
20    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
21    'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
22];
23/// All alphabetic characters
24static ALPHA_ALL: [char; 52] = [
25    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
26    't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
27    'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
28];
29/// Only easily distinguished characters
30static ALPHA_DIST: [char; 49] = [
31    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
32    'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
33    'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
34];
35
36/// All digits
37static DIGIT_ALL: [char; 10] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
38/// Only the digits that are easily distinguished
39static DIGIT_DIST: [char; 7] = ['3', '4', '5', '6', '7', '8', '9'];
40/// *All* (actually, a small subset) the special characters
41static SPECIAL_ALL: [char; 29] = [
42    '#', '@', '&', '"', '\'', '(', '§', '!', ')', '-', '_', '¨', '^', '*', '$', '€', '%', '£', '`',
43    '<', '>', '?', ',', '.', ';', ':', '/', '+', '=',
44];
45/// Only the most common (easiest to distinguish) special characters
46static SPECIAL_BASIC: [char; 19] = [
47    '#', '@', '&', '(', '!', ')', '-', '_', '*', '$', '%', '?', ',', '.', ';', ':', '/', '+', '=',
48];
49
50// -----------------------------------------------------------------------------
51// THE VARIOUS DEFINED CHARSETS
52// -----------------------------------------------------------------------------
53
54/// A collating sequence
55pub trait CollatingSeq {
56    /// return all characters from the charset
57    fn characters(&self) -> &[char];
58}
59
60/// Sets related to the alphabetic collating sequence
61#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
62pub enum Alpha {
63    /// Both lower and upper case letters ("*", "b", "both")    
64    All,
65    /// Characters that are easily distinguished (O,l,Z).
66    Dist,
67    /// Lower case letters only ("l", "lc", "lower" or "lower-case")
68    Lower,
69    /// Upper case letters only ("u", "uc", "upper" or "upper-case")
70    Upper,
71    /// No letters
72    None,
73}
74impl FromStr for Alpha {
75    type Err = Error;
76    fn from_str(s: &str) -> Result<Self, Self::Err> {
77        match s.to_lowercase().as_str() {
78            "*" => Ok(Self::All),
79            "a" => Ok(Self::All),
80            "all" => Ok(Self::All),
81            "any" => Ok(Self::All),
82            "d" => Ok(Self::Dist),
83            "e" => Ok(Self::Dist),
84            "easy" => Ok(Self::Dist),
85            "dist" => Ok(Self::Dist),
86            "l" => Ok(Self::Lower),
87            "lc" => Ok(Self::Lower),
88            "lower" => Ok(Self::Lower),
89            "lower-case" => Ok(Self::Lower),
90            "u" => Ok(Self::Upper),
91            "uc" => Ok(Self::Upper),
92            "upper" => Ok(Self::Upper),
93            "upper-case" => Ok(Self::Upper),
94            "0" => Ok(Self::None),
95            "n" => Ok(Self::None),
96            "none" => Ok(Self::None),
97            _ => Err(Error::ParseError(s.to_string())),
98        }
99    }
100}
101/// Sets related to the numeric collating sequence
102#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
103pub enum Digit {
104    /// All digits
105    All,
106    /// Characters that are easily distinguished (excludes 0 and 1, 2).
107    Dist,
108    /// No digits
109    None,
110}
111impl FromStr for Digit {
112    type Err = Error;
113
114    fn from_str(s: &str) -> Result<Self, Self::Err> {
115        match s.to_lowercase().as_str() {
116            "d" => Ok(Self::Dist),
117            "e" => Ok(Self::Dist),
118            "easy" => Ok(Self::Dist),
119            "dist" => Ok(Self::Dist),
120            "*" => Ok(Self::All),
121            "a" => Ok(Self::All),
122            "all" => Ok(Self::All),
123            "any" => Ok(Self::All),
124            "0" => Ok(Self::None),
125            "n" => Ok(Self::None),
126            "none" => Ok(Self::None),
127            _ => Err(Error::ParseError(s.to_string())),
128        }
129    }
130}
131/// Sets related to the special characters collating sequence
132#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
133pub enum Special {
134    /// All special characters
135    All,
136    /// Only the most usual special characters
137    Basic,
138    /// No special characters
139    None,
140}
141impl FromStr for Special {
142    type Err = Error;
143
144    fn from_str(s: &str) -> Result<Self, Self::Err> {
145        match s.to_lowercase().as_str() {
146            "b" => Ok(Self::Basic),
147            "basic" => Ok(Self::Basic),
148            "*" => Ok(Self::All),
149            "a" => Ok(Self::All),
150            "all" => Ok(Self::All),
151            "any" => Ok(Self::All),
152            "0" => Ok(Self::None),
153            "n" => Ok(Self::None),
154            "none" => Ok(Self::None),
155            _ => Err(Error::ParseError(s.to_string())),
156        }
157    }
158}
159
160impl CollatingSeq for Alpha {
161    fn characters(&self) -> &[char] {
162        match *self {
163            Alpha::All => &ALPHA_ALL,
164            Alpha::Dist => &ALPHA_DIST,
165            Alpha::Lower => &ALPHA_LOWER,
166            Alpha::Upper => &ALPHA_UPPER,
167            Alpha::None => &NONE,
168        }
169    }
170}
171impl CollatingSeq for Digit {
172    fn characters(&self) -> &[char] {
173        match *self {
174            Digit::All => &DIGIT_ALL,
175            Digit::Dist => &DIGIT_DIST,
176            Digit::None => &NONE,
177        }
178    }
179}
180impl CollatingSeq for Special {
181    fn characters(&self) -> &[char] {
182        match *self {
183            Special::All => &SPECIAL_ALL,
184            Special::Basic => &SPECIAL_BASIC,
185            Special::None => &NONE,
186        }
187    }
188}