1use core::fmt;
2
3use crate::{
4 dict::{Adjective, Adverb, Mapper, Noun, Plural, Preposition, Verb},
5 Hyphenated,
6};
7
8use super::{skip_one_of, string_to_words, Error};
9
10pub struct ComplexPhrase {
11 adjective1: &'static str,
12 noun1: &'static str,
13 verb1: &'static str,
14 adverb1: &'static str,
15 preposition1: &'static str,
16 adjective2: &'static str,
17 noun2: &'static str,
18 preposition2: &'static str,
19 noun3: &'static str,
20 verb2: &'static str,
21 adverb2: &'static str,
22 adjective3: &'static str,
23 adjective4: &'static str,
24 noun4: &'static str,
25 verb3: &'static str,
26 verb4: &'static str,
27}
28
29impl ComplexPhrase {
30 #[inline]
32 pub fn encode(bits: u128) -> Self {
33 encode(bits)
34 }
35
36 #[inline]
38 pub fn hyphenated(self) -> Hyphenated<Self> {
39 Hyphenated(self)
40 }
41}
42
43impl fmt::Display for ComplexPhrase {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 write!(
46 f,
47 "The {} {} {} {} {} the {} {} {} the {} and {} {} that the {} {} {} {} and {}",
48 self.adjective1,
49 self.noun1,
50 self.verb1,
51 self.adverb1,
52 self.preposition1,
53 self.adjective2,
54 self.noun2,
55 self.preposition2,
56 self.noun3,
57 self.verb2,
58 self.adverb2,
59 self.adjective3,
60 self.adjective4,
61 self.noun4,
62 self.verb3,
63 self.verb4
64 )
65 }
66}
67
68impl fmt::Display for Hyphenated<ComplexPhrase> {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 write!(
71 f,
72 "{}-{}-{}-{}-{}-{}-{}-{}-{}-{}-{}-{}-{}-{}-{}-{}",
73 self.0.adjective1,
74 self.0.noun1,
75 self.0.verb1,
76 self.0.adverb1,
77 self.0.preposition1,
78 self.0.adjective2,
79 self.0.noun2,
80 self.0.preposition2,
81 self.0.noun3,
82 self.0.verb2,
83 self.0.adverb2,
84 self.0.adjective3,
85 self.0.adjective4,
86 self.0.noun4,
87 self.0.verb3,
88 self.0.verb4,
89 )
90 }
91}
92
93pub fn encode(bits: u128) -> ComplexPhrase {
96 let ([adjective1, adjective2, adjective3, adjective4], bits) = Adjective::encode_words(bits);
97 let ([noun1, noun2, noun3, noun4], bits) = Noun::encode_words(bits);
98 let ([verb1, verb2, verb3, verb4], bits) = Verb::<Plural>::encode_words(bits);
99 let ([adverb1, adverb2], bits) = Adverb::encode_words(bits);
100 let ([preposition1, preposition2], bits) = Preposition::encode_words(bits);
101 debug_assert_eq!(bits, 0);
102
103 ComplexPhrase {
104 adjective1,
105 noun1,
106 verb1,
107 adverb1,
108 preposition1,
109 adjective2,
110 noun2,
111 preposition2,
112 noun3,
113 verb2,
114 adverb2,
115 adjective3,
116 adjective4,
117 noun4,
118 verb3,
119 verb4,
120 }
121}
122
123pub fn decode(s: &str) -> Result<u128, Error> {
126 let mut iter = string_to_words(s);
127
128 skip_one_of(&mut iter, &["a", "the"]);
129
130 let adjective1 = iter.next().ok_or(Error::NotEnoughWords {
131 expected: 16,
132 actual: 0,
133 })?;
134 let noun1 = iter.next().ok_or(Error::NotEnoughWords {
135 expected: 16,
136 actual: 1,
137 })?;
138 let verb1 = iter.next().ok_or(Error::NotEnoughWords {
139 expected: 16,
140 actual: 2,
141 })?;
142 let adverb1 = iter.next().ok_or(Error::NotEnoughWords {
143 expected: 16,
144 actual: 3,
145 })?;
146 let preposition1 = iter.next().ok_or(Error::NotEnoughWords {
147 expected: 16,
148 actual: 4,
149 })?;
150
151 skip_one_of(&mut iter, &["a", "the"]);
152 let adjective2 = iter.next().ok_or(Error::NotEnoughWords {
153 expected: 16,
154 actual: 5,
155 })?;
156 let noun2 = iter.next().ok_or(Error::NotEnoughWords {
157 expected: 16,
158 actual: 6,
159 })?;
160 let preposition2 = iter.next().ok_or(Error::NotEnoughWords {
161 expected: 16,
162 actual: 7,
163 })?;
164
165 skip_one_of(&mut iter, &["a", "the"]);
166 let noun3 = iter.next().ok_or(Error::NotEnoughWords {
167 expected: 16,
168 actual: 8,
169 })?;
170
171 skip_one_of(&mut iter, &["and"]);
172 let verb2 = iter.next().ok_or(Error::NotEnoughWords {
173 expected: 16,
174 actual: 9,
175 })?;
176 let adverb2 = iter.next().ok_or(Error::NotEnoughWords {
177 expected: 16,
178 actual: 10,
179 })?;
180
181 skip_one_of(&mut iter, &["that"]);
182 skip_one_of(&mut iter, &["a", "the"]);
183 let adjective3 = iter.next().ok_or(Error::NotEnoughWords {
184 expected: 16,
185 actual: 11,
186 })?;
187 let adjective4 = iter.next().ok_or(Error::NotEnoughWords {
188 expected: 16,
189 actual: 12,
190 })?;
191 let noun4 = iter.next().ok_or(Error::NotEnoughWords {
192 expected: 16,
193 actual: 13,
194 })?;
195 let verb3 = iter.next().ok_or(Error::NotEnoughWords {
196 expected: 16,
197 actual: 14,
198 })?;
199
200 skip_one_of(&mut iter, &["and"]);
201
202 let verb4 = iter.next().ok_or(Error::NotEnoughWords {
203 expected: 16,
204 actual: 15,
205 })?;
206
207 let mut bits = 0;
208
209 let prepositions = [preposition2, preposition1];
210 let adverbs = [adverb2, adverb1];
211 let verbs = [verb4, verb3, verb2, verb1];
212 let nouns = [noun4, noun3, noun2, noun1];
213 let adjectives = [adjective4, adjective3, adjective2, adjective1];
214
215 bits = Preposition::decode_words(prepositions, bits).map_err(|i| Error::Unrecognized {
216 word: prepositions[i],
217 })?;
218 bits = Adverb::decode_words(adverbs, bits)
219 .map_err(|i| Error::Unrecognized { word: adverbs[i] })?;
220 bits = Verb::<Plural>::decode_words(verbs, bits)
221 .map_err(|i| Error::Unrecognized { word: verbs[i] })?;
222 bits = Noun::decode_words(nouns, bits).map_err(|i| Error::Unrecognized { word: nouns[i] })?;
223 bits = Adjective::decode_words(adjectives, bits).map_err(|i| Error::Unrecognized {
224 word: adjectives[i],
225 })?;
226
227 Ok(bits)
228}
229
230#[cfg(feature = "serde")]
231pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
232where
233 T: Copy + Into<u128>,
234 S: serde::ser::Serializer,
235{
236 use alloc::string::ToString;
237 use serde::Serialize;
238
239 let an = encode((*value).into());
240 an.to_string().serialize(serializer)
241}
242
243#[cfg(feature = "serde")]
244pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
245where
246 u128: Into<T>,
247 D: serde::de::Deserializer<'de>,
248{
249 use alloc::borrow::Cow;
250
251 let s = <Cow<str> as serde::de::Deserialize>::deserialize(deserializer)?;
252 match decode(&*s) {
253 Err(err) => Err(serde::de::Error::custom(err)),
254 Ok(id) => Ok(id.into()),
255 }
256}