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}