meme_id/schemes/
complex_phrase.rs

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    /// Encodes bits into `adjective noun verb adverb` scheme
31    #[inline]
32    pub fn encode(bits: u128) -> Self {
33        encode(bits)
34    }
35
36    /// Transform to hyphenated.
37    #[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
93/// Encodes bits into a complex phrase.
94/// For 128-bit ids.
95pub 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
123/// Decodes a complex phrase.
124/// For 128-bit ids.
125pub 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}