initiative_core/world/npc/
age.rs

1use super::{Ethnicity, Species};
2use initiative_macros::WordList;
3use serde::{Deserialize, Serialize};
4use std::fmt;
5
6#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize, WordList)]
7#[serde(into = "&'static str", try_from = "&str")]
8pub enum Age {
9    #[alias = "baby"]
10    Infant,
11
12    #[alias = "boy"]
13    #[alias = "girl"]
14    Child,
15
16    #[alias = "teenage"]
17    #[alias = "teenager"]
18    Adolescent,
19
20    #[alias = "young"]
21    #[alias = "young adult"]
22    YoungAdult,
23
24    #[alias = "man"]
25    #[alias = "woman"]
26    Adult,
27
28    #[alias = "middle aged"]
29    MiddleAged,
30
31    #[alias = "old"]
32    Elderly,
33
34    #[alias = "feeble"]
35    #[alias = "ancient"]
36    #[alias = "wizened"]
37    Geriatric,
38}
39
40impl Age {
41    pub fn fmt_with_species_ethnicity(
42        &self,
43        species: Option<&Species>,
44        ethnicity: Option<&Ethnicity>,
45        f: &mut fmt::Formatter,
46    ) -> fmt::Result {
47        if let Some(species) = species {
48            match self {
49                Age::Infant | Age::Child => write!(f, "{} {}", species, self),
50                _ => write!(f, "{} {}", self, species),
51            }
52        } else if let Some(ethnicity) = ethnicity {
53            match self {
54                Age::MiddleAged | Age::Elderly | Age::Geriatric => {
55                    write!(f, "{} {} person", self, ethnicity)
56                }
57                _ => write!(f, "{} {}", ethnicity, self),
58            }
59        } else {
60            match self {
61                Age::MiddleAged | Age::Elderly | Age::Geriatric => write!(f, "{} person", self),
62                _ => write!(f, "{}", self),
63            }
64        }
65    }
66}
67
68impl fmt::Display for Age {
69    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70        match self {
71            Self::Infant => write!(f, "infant"),
72            Self::Child => write!(f, "child"),
73            Self::Adolescent => write!(f, "adolescent"),
74            Self::YoungAdult => write!(f, "young adult"),
75            Self::Adult => write!(f, "adult"),
76            Self::MiddleAged => write!(f, "middle-aged"),
77            Self::Elderly => write!(f, "elderly"),
78            Self::Geriatric => write!(f, "geriatric"),
79        }
80    }
81}
82
83#[cfg(test)]
84mod test {
85    use super::*;
86
87    #[test]
88    fn display_test() {
89        let cases = [
90            ("infant", Age::Infant),
91            ("child", Age::Child),
92            ("adolescent", Age::Adolescent),
93            ("young adult", Age::YoungAdult),
94            ("adult", Age::Adult),
95            ("middle-aged", Age::MiddleAged),
96            ("elderly", Age::Elderly),
97            ("geriatric", Age::Geriatric),
98        ];
99
100        for (age_str, age) in cases {
101            assert_eq!(age_str, format!("{}", age));
102            assert_eq!(Ok(age), format!("{}", age).parse::<Age>());
103        }
104    }
105
106    #[test]
107    fn from_str_test() {
108        assert_eq!(Ok(Age::Infant), "infant".parse::<Age>());
109        assert_eq!(Ok(Age::Infant), "baby".parse::<Age>());
110
111        assert_eq!(Ok(Age::Child), "child".parse::<Age>());
112        assert_eq!(Ok(Age::Child), "boy".parse::<Age>());
113        assert_eq!(Ok(Age::Child), "girl".parse::<Age>());
114
115        assert_eq!(Ok(Age::Adolescent), "adolescent".parse::<Age>());
116        assert_eq!(Ok(Age::Adolescent), "teenage".parse::<Age>());
117        assert_eq!(Ok(Age::Adolescent), "teenager".parse::<Age>());
118
119        assert_eq!(Ok(Age::YoungAdult), "young".parse::<Age>());
120        assert_eq!(Ok(Age::YoungAdult), "young adult".parse::<Age>());
121        assert_eq!(Ok(Age::YoungAdult), "young-adult".parse::<Age>());
122
123        assert_eq!(Ok(Age::Adult), "adult".parse::<Age>());
124
125        assert_eq!(Ok(Age::MiddleAged), "middle aged".parse::<Age>());
126        assert_eq!(Ok(Age::MiddleAged), "middle-aged".parse::<Age>());
127
128        assert_eq!(Ok(Age::Elderly), "elderly".parse::<Age>());
129        assert_eq!(Ok(Age::Elderly), "old".parse::<Age>());
130
131        assert_eq!(Ok(Age::Geriatric), "geriatric".parse::<Age>());
132        assert_eq!(Ok(Age::Geriatric), "feeble".parse::<Age>());
133        assert_eq!(Ok(Age::Geriatric), "ancient".parse::<Age>());
134        assert_eq!(Ok(Age::Geriatric), "wizened".parse::<Age>());
135
136        assert_eq!(Err(()), "potato".parse::<Age>());
137    }
138
139    #[test]
140    fn fmt_with_species_test_some_species() {
141        let s = Species::Elf;
142
143        assert_eq!(
144            "elf infant",
145            format!("{}", TestWrapper(&Age::Infant, Some(&s), None)),
146        );
147        assert_eq!(
148            "elf child",
149            format!("{}", TestWrapper(&Age::Child, Some(&s), None)),
150        );
151        assert_eq!(
152            "adolescent elf",
153            format!("{}", TestWrapper(&Age::Adolescent, Some(&s), None)),
154        );
155        assert_eq!(
156            "young adult elf",
157            format!("{}", TestWrapper(&Age::YoungAdult, Some(&s), None)),
158        );
159        assert_eq!(
160            "adult elf",
161            format!("{}", TestWrapper(&Age::Adult, Some(&s), None)),
162        );
163        assert_eq!(
164            "middle-aged elf",
165            format!("{}", TestWrapper(&Age::MiddleAged, Some(&s), None)),
166        );
167        assert_eq!(
168            "elderly elf",
169            format!("{}", TestWrapper(&Age::Elderly, Some(&s), None)),
170        );
171        assert_eq!(
172            "geriatric elf",
173            format!("{}", TestWrapper(&Age::Geriatric, Some(&s), None)),
174        );
175    }
176
177    #[test]
178    fn fmt_with_species_test_some_ethnicity() {
179        let e = Ethnicity::Elvish;
180
181        assert_eq!(
182            "elvish infant",
183            format!("{}", TestWrapper(&Age::Infant, None, Some(&e))),
184        );
185        assert_eq!(
186            "elvish child",
187            format!("{}", TestWrapper(&Age::Child, None, Some(&e))),
188        );
189        assert_eq!(
190            "elvish adolescent",
191            format!("{}", TestWrapper(&Age::Adolescent, None, Some(&e))),
192        );
193        assert_eq!(
194            "elvish young adult",
195            format!("{}", TestWrapper(&Age::YoungAdult, None, Some(&e))),
196        );
197        assert_eq!(
198            "elvish adult",
199            format!("{}", TestWrapper(&Age::Adult, None, Some(&e))),
200        );
201        assert_eq!(
202            "middle-aged elvish person",
203            format!("{}", TestWrapper(&Age::MiddleAged, None, Some(&e))),
204        );
205        assert_eq!(
206            "elderly elvish person",
207            format!("{}", TestWrapper(&Age::Elderly, None, Some(&e))),
208        );
209        assert_eq!(
210            "geriatric elvish person",
211            format!("{}", TestWrapper(&Age::Geriatric, None, Some(&e))),
212        );
213    }
214
215    #[test]
216    fn fmt_with_species_test_none() {
217        assert_eq!(
218            "elf infant",
219            format!(
220                "{}",
221                TestWrapper(&Age::Infant, Some(&Species::Elf), Some(&Ethnicity::Human)),
222            ),
223        );
224
225        assert_eq!(
226            "infant",
227            format!("{}", TestWrapper(&Age::Infant, None, None)),
228        );
229        assert_eq!("adult", format!("{}", TestWrapper(&Age::Adult, None, None)));
230    }
231
232    #[test]
233    fn serialize_deserialize_test() {
234        assert_eq!(r#""adult""#, serde_json::to_string(&Age::Adult).unwrap());
235
236        let value: Age = serde_json::from_str(r#""adult""#).unwrap();
237        assert_eq!(Age::Adult, value);
238    }
239
240    struct TestWrapper<'a>(&'a Age, Option<&'a Species>, Option<&'a Ethnicity>);
241
242    impl fmt::Display for TestWrapper<'_> {
243        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
244            self.0.fmt_with_species_ethnicity(self.1, self.2, f)
245        }
246    }
247}