meme_id/schemes/
simple_phrase.rs

1use core::fmt;
2
3use crate::{
4    dict::{Adjective, Adverb, Mapper, Noun, Plural, Verb},
5    Hyphenated,
6};
7
8use super::{skip_one_of, string_to_words, Error};
9
10#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
11pub struct SimplePhrase {
12    pub adjective: &'static str,
13    pub noun: &'static str,
14    pub verb: &'static str,
15    pub adverb: &'static str,
16}
17
18impl SimplePhrase {
19    /// Encodes bits into `adjective noun verb adverb` scheme
20    #[inline]
21    pub fn encode(bits: u32) -> Self {
22        encode(bits)
23    }
24
25    /// Transform to hyphenated.
26    #[inline]
27    pub fn hyphenated(self) -> Hyphenated<Self> {
28        Hyphenated(self)
29    }
30}
31
32impl fmt::Display for SimplePhrase {
33    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34        write!(
35            f,
36            "The {} {} {} {}",
37            self.adjective, self.noun, self.verb, self.adverb
38        )
39    }
40}
41
42impl fmt::Display for Hyphenated<SimplePhrase> {
43    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44        write!(
45            f,
46            "{}-{}-{}-{}",
47            self.0.adjective, self.0.noun, self.0.verb, self.0.adverb
48        )
49    }
50}
51
52/// Encodes bits into a simple phrase.
53/// For 32-bit ids.
54pub fn encode(bits: u32) -> SimplePhrase {
55    let (adjective, bits) = Adjective::encode_word(bits.into());
56    let (noun, bits) = Noun::encode_word(bits);
57    let (verb, bits) = Verb::<Plural>::encode_word(bits);
58    let (adverb, bits) = Adverb::encode_word(bits);
59
60    debug_assert_eq!(bits, 0);
61
62    SimplePhrase {
63        adjective,
64        noun,
65        verb,
66        adverb,
67    }
68}
69
70/// Decodes a simple phrase.
71/// For 32-bit ids.
72pub fn decode(s: &str) -> Result<u32, Error> {
73    let mut iter = string_to_words(s);
74
75    skip_one_of(&mut iter, &["a", "the"]);
76
77    let adjective = iter.next().ok_or(Error::NotEnoughWords {
78        expected: 4,
79        actual: 0,
80    })?;
81    let noun = iter.next().ok_or(Error::NotEnoughWords {
82        expected: 4,
83        actual: 1,
84    })?;
85    let verb = iter.next().ok_or(Error::NotEnoughWords {
86        expected: 4,
87        actual: 2,
88    })?;
89    let adverb = iter.next().ok_or(Error::NotEnoughWords {
90        expected: 4,
91        actual: 3,
92    })?;
93
94    if iter.next().is_some() {
95        return Err(Error::TrailingWords);
96    }
97
98    let mut bits = 0;
99    bits = Adverb::decode_word(adverb, bits).ok_or(Error::Unrecognized { word: adverb })?;
100    bits = Verb::<Plural>::decode_word(verb, bits).ok_or(Error::Unrecognized { word: verb })?;
101    bits = Noun::decode_word(noun, bits).ok_or(Error::Unrecognized { word: noun })?;
102    bits =
103        Adjective::decode_word(adjective, bits).ok_or(Error::Unrecognized { word: adjective })?;
104
105    Ok(bits as u32)
106}
107
108#[cfg(feature = "serde")]
109pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
110where
111    T: Copy + Into<u32>,
112    S: serde::ser::Serializer,
113{
114    use alloc::string::ToString;
115    use serde::Serialize;
116
117    let an = encode((*value).into());
118    an.to_string().serialize(serializer)
119}
120
121#[cfg(feature = "serde")]
122pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
123where
124    u32: Into<T>,
125    D: serde::de::Deserializer<'de>,
126{
127    use alloc::borrow::Cow;
128
129    let s = <Cow<str> as serde::de::Deserialize>::deserialize(deserializer)?;
130    match decode(&*s) {
131        Err(err) => Err(serde::de::Error::custom(err)),
132        Ok(id) => Ok(id.into()),
133    }
134}