Skip to main content

entroll_dictionaries/
lib.rs

1use entroll_core::AsciiFaces;
2use entroll_core::{Compact, Faces};
3
4pub mod ascii;
5pub mod wordlist;
6
7pub trait Dirctionary {
8    fn name(&self) -> &str;
9}
10
11pub trait Dictionary {
12    fn name(&self) -> &str;
13    fn canonical(&self) -> &str {
14        self.name()
15    }
16}
17
18pub trait AsciiDictionary: Compact {
19    fn name(&self) -> &str;
20    fn canonical(&self) -> &str {
21        self.name()
22    }
23}
24
25pub struct AsciiDictionaryWrapper<T>
26where
27    T: AsciiDictionary,
28{
29    inner: T,
30    faces: AsciiFaces,
31}
32
33impl<T> AsciiDictionaryWrapper<T>
34where
35    T: AsciiDictionary,
36{
37    pub fn new(inner: T) -> Self {
38        let faces = AsciiFaces::try_from(inner.ranges()).unwrap();
39        Self { inner, faces }
40    }
41}
42
43impl<T> Default for AsciiDictionaryWrapper<T>
44where
45    T: AsciiDictionary + Default,
46{
47    fn default() -> Self {
48        let inner = T::default();
49        let faces = AsciiFaces::try_from(inner.ranges()).unwrap();
50        Self { inner, faces }
51    }
52}
53
54impl<T> Dictionary for AsciiDictionaryWrapper<T>
55where
56    T: AsciiDictionary,
57{
58    fn name(&self) -> &str {
59        self.inner.name()
60    }
61
62    fn canonical(&self) -> &str {
63        self.inner.canonical()
64    }
65}
66
67impl<T> Faces for AsciiDictionaryWrapper<T>
68where
69    T: AsciiDictionary,
70{
71    fn len(&self) -> usize {
72        self.faces.len()
73    }
74}
75
76impl<T> std::ops::Index<usize> for AsciiDictionaryWrapper<T>
77where
78    T: AsciiDictionary,
79{
80    type Output = u8;
81
82    fn index(&self, idx: usize) -> &u8 {
83        &self.faces[idx]
84    }
85}
86
87impl<T> rand::distributions::Distribution<u8> for AsciiDictionaryWrapper<T>
88where
89    T: AsciiDictionary,
90{
91    fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> u8 {
92        let idx = rng.gen_range(0..self.len());
93        self[idx]
94    }
95}
96
97pub struct WordList<const N: usize> {
98    words: [&'static str; N],
99    name: &'static str,
100}
101
102impl<const N: usize> Faces for WordList<N> {
103    fn len(&self) -> usize {
104        self.words.len()
105    }
106}
107
108impl<const N: usize> std::ops::Index<usize> for WordList<N> {
109    type Output = str;
110
111    fn index(&self, idx: usize) -> &str {
112        self.words[idx]
113    }
114}
115
116impl<const N: usize> rand::distributions::Distribution<String> for WordList<N> {
117    fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> String {
118        let idx = rng.gen_range(0..self.len());
119        self[idx].to_string()
120    }
121}
122
123impl<const N: usize> Dictionary for WordList<N> {
124    fn name(&self) -> &str {
125        self.name
126    }
127}
128
129pub type ArabicNumerals = AsciiDictionaryWrapper<ascii::ArabicNumerals>;
130pub type Hexadecimal = AsciiDictionaryWrapper<ascii::Hexadecimal>;
131pub type Alphanumeric = AsciiDictionaryWrapper<ascii::Alphanumeric>;
132pub type Expect = AsciiDictionaryWrapper<ascii::Expect>;
133
134pub use wordlist::EFFDiceware5;