entroll_dictionaries/
lib.rs1use 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;