wordlists/types/
diceware.rs1use crate::*;
2use itertools::Itertools;
3
4pub struct DicewareWordlist {
7 name: String,
9
10 dice_count: u8,
12
13 dice_size: u8,
15
16 wordlist: Box<[(&'static str, &'static str)]>,
20}
21
22impl DicewareWordlist {
23 pub fn new(
25 name: String,
26 dice_count: u8,
27 dice_size: u8,
28 wordlist: Box<[(&'static str, &'static str)]>,
29 ) -> Self {
30 DicewareWordlist {
31 name,
32 dice_count,
33 dice_size,
34 wordlist,
35 }
36 }
37
38 pub fn word(&self, index: usize) -> Result<&'static str> {
40 if index > self.wordlist.len() {
41 Err(WordlistError::IndexOutOfBounds(index, self.wordlist.len()))
42 } else {
43 self.wordlist
44 .get(index)
45 .map(|(_, v)| *v)
46 .ok_or(WordlistError::WordlistIsIncomplete)
47 }
48 }
49
50 pub fn dice_count(&self) -> u8 {
52 self.dice_count
53 }
54
55 pub fn dice_size(&self) -> u8 {
57 self.dice_size
58 }
59}
60
61impl WordlistByteConverter for DicewareWordlist {
66 fn to_words(&self, bytes: &BitVec) -> Result<WordVec> {
67 let mut wordlist = Vec::new();
68 for index in bytes.as_raw_slice().into_iter() {
69 wordlist.push(self.word(*index)?);
70 }
71 Ok(wordlist)
72 }
73 fn to_bytes(&self, words: &WordVec) -> Result<BitVec> {
74 let mut bytes = Vec::new();
75 for word in words.iter() {
76 let b = self
77 .wordlist
78 .iter()
79 .find_position(|(_, v)| v.eq(word))
80 .map(|(index, _)| index)
81 .ok_or_else(|| WordlistError::InvalidWord(word.to_string()))?;
82 bytes.push(b);
83 }
84 Ok(BitVec::from_vec(bytes))
85 }
86}
87
88impl Wordlist for DicewareWordlist {
89 fn name(&self) -> &String {
90 &self.name
91 }
92 fn size(&self) -> usize {
93 self.wordlist.len()
94 }
95 fn contains(&self, word: &str) -> bool {
96 self.wordlist.iter().map(|(_x, y)| *y).any(|v| v.eq(word))
97 }
98}