1use hashbrown::HashMap;
2use error::ErrorKind;
3use failure::Error;
4use util::{Bits11, Bits};
5
6pub struct WordMap {
7 inner: HashMap<&'static str, Bits11>
8
9}
10
11pub struct WordList {
12 inner: Vec<&'static str>
13}
14
15impl WordMap {
16 pub fn get_bits(&self, word: &str) -> Result<Bits11, Error> {
17 match self.inner.get(word) {
18 Some(n) => Ok(*n),
19 None => Err(ErrorKind::InvalidWord)?
20 }
21 }
22}
23
24impl WordList {
25 pub fn get_word(&self, bits: Bits11) -> &'static str {
26 self.inner[bits.bits() as usize]
27 }
28}
29
30mod lazy {
31 use super::{Bits11, WordList, WordMap};
32 use once_cell::sync::Lazy;
33
34 fn gen_wordlist(lang_words: &'static str) -> WordList {
36 let inner: Vec<_> = lang_words.split_whitespace().collect();
37
38 debug_assert!(inner.len() == 2048, "Invalid wordlist length");
39
40 WordList {
41 inner
42 }
43 }
44
45 fn gen_wordmap(wordlist: &WordList) -> WordMap {
47 let inner = wordlist.inner
48 .iter()
49 .enumerate()
50 .map(|(i, item)| (*item, Bits11::from(i as u16)))
51 .collect();
52
53 WordMap {
54 inner
55 }
56 }
57
58 pub static WORDLIST_ENGLISH: Lazy<WordList> = sync_lazy!{ gen_wordlist(include_str!("langs/english.txt")) };
59 #[cfg(feature = "chinese-simplified")]
60 pub static WORDLIST_CHINESE_SIMPLIFIED: Lazy<WordList> = sync_lazy!{ gen_wordlist(include_str!("langs/chinese_simplified.txt")) };
61 #[cfg(feature = "chinese-traditional")]
62 pub static WORDLIST_CHINESE_TRADITIONAL: Lazy<WordList> = sync_lazy!{ gen_wordlist(include_str!("langs/chinese_traditional.txt")) };
63 #[cfg(feature = "french")]
64 pub static WORDLIST_FRENCH: Lazy<WordList> = sync_lazy!{ gen_wordlist(include_str!("langs/french.txt")) };
65 #[cfg(feature = "italian")]
66 pub static WORDLIST_ITALIAN: Lazy<WordList> = sync_lazy!{ gen_wordlist(include_str!("langs/italian.txt")) };
67 #[cfg(feature = "japanese")]
68 pub static WORDLIST_JAPANESE: Lazy<WordList> = sync_lazy!{ gen_wordlist(include_str!("langs/japanese.txt")) };
69 #[cfg(feature = "korean")]
70 pub static WORDLIST_KOREAN: Lazy<WordList> = sync_lazy!{ gen_wordlist(include_str!("langs/korean.txt")) };
71 #[cfg(feature = "spanish")]
72 pub static WORDLIST_SPANISH: Lazy<WordList> = sync_lazy!{ gen_wordlist(include_str!("langs/spanish.txt")) };
73
74 pub static WORDMAP_ENGLISH: Lazy<WordMap> = sync_lazy!{ gen_wordmap(&WORDLIST_ENGLISH) };
75 #[cfg(feature = "chinese-simplified")]
76 pub static WORDMAP_CHINESE_SIMPLIFIED: Lazy<WordMap> = sync_lazy!{ gen_wordmap(&WORDLIST_CHINESE_SIMPLIFIED) };
77 #[cfg(feature = "chinese-traditional")]
78 pub static WORDMAP_CHINESE_TRADITIONAL: Lazy<WordMap> = sync_lazy!{ gen_wordmap(&WORDLIST_CHINESE_TRADITIONAL) };
79 #[cfg(feature = "french")]
80 pub static WORDMAP_FRENCH: Lazy<WordMap> = sync_lazy!{ gen_wordmap(&WORDLIST_FRENCH) };
81 #[cfg(feature = "italian")]
82 pub static WORDMAP_ITALIAN: Lazy<WordMap> = sync_lazy!{ gen_wordmap(&WORDLIST_ITALIAN) };
83 #[cfg(feature = "japanese")]
84 pub static WORDMAP_JAPANESE: Lazy<WordMap> = sync_lazy!{ gen_wordmap(&WORDLIST_JAPANESE) };
85 #[cfg(feature = "korean")]
86 pub static WORDMAP_KOREAN: Lazy<WordMap> = sync_lazy!{ gen_wordmap(&WORDLIST_KOREAN) };
87 #[cfg(feature = "spanish")]
88 pub static WORDMAP_SPANISH: Lazy<WordMap> = sync_lazy!{ gen_wordmap(&WORDLIST_SPANISH) };
89
90}
91
92#[derive(Debug, Clone, Copy, Serialize, Deserialize, Eq, PartialEq)]
101pub enum Language {
102 English,
103 #[cfg(feature = "chinese-simplified")]
104 ChineseSimplified,
105 #[cfg(feature = "chinese-traditional")]
106 ChineseTraditional,
107 #[cfg(feature = "french")]
108 French,
109 #[cfg(feature = "italian")]
110 Italian,
111 #[cfg(feature = "japanese")]
112 Japanese,
113 #[cfg(feature = "korean")]
114 Korean,
115 #[cfg(feature = "spanish")]
116 Spanish,
117}
118
119impl Language {
120 pub fn wordlist(&self) -> &'static WordList {
122 match *self {
123 Language::English => &lazy::WORDLIST_ENGLISH,
124 #[cfg(feature = "chinese-simplified")]
125 Language::ChineseSimplified => &lazy::WORDLIST_CHINESE_SIMPLIFIED,
126 #[cfg(feature = "chinese-traditional")]
127 Language::ChineseTraditional => &lazy::WORDLIST_CHINESE_TRADITIONAL,
128 #[cfg(feature = "french")]
129 Language::French => &lazy::WORDLIST_FRENCH,
130 #[cfg(feature = "italian")]
131 Language::Italian => &lazy::WORDLIST_ITALIAN,
132 #[cfg(feature = "japanese")]
133 Language::Japanese => &lazy::WORDLIST_JAPANESE,
134 #[cfg(feature = "korean")]
135 Language::Korean => &lazy::WORDLIST_KOREAN,
136 #[cfg(feature = "spanish")]
137 Language::Spanish => &lazy::WORDLIST_SPANISH,
138 }
139 }
140
141 pub fn wordmap(&self) -> &'static WordMap {
146 match *self {
147 Language::English => &lazy::WORDMAP_ENGLISH,
148 #[cfg(feature = "chinese-simplified")]
149 Language::ChineseSimplified => &lazy::WORDMAP_CHINESE_SIMPLIFIED,
150 #[cfg(feature = "chinese-traditional")]
151 Language::ChineseTraditional => &lazy::WORDMAP_CHINESE_TRADITIONAL,
152 #[cfg(feature = "french")]
153 Language::French => &lazy::WORDMAP_FRENCH,
154 #[cfg(feature = "italian")]
155 Language::Italian => &lazy::WORDMAP_ITALIAN,
156 #[cfg(feature = "japanese")]
157 Language::Japanese => &lazy::WORDMAP_JAPANESE,
158 #[cfg(feature = "korean")]
159 Language::Korean => &lazy::WORDMAP_KOREAN,
160 #[cfg(feature = "spanish")]
161 Language::Spanish => &lazy::WORDMAP_SPANISH,
162 }
163 }
164}
165
166impl Default for Language {
167 fn default() -> Language {
168 Language::English
169 }
170}