initiative_core/world/npc/
gender.rs

1use initiative_macros::WordList;
2use serde::{Deserialize, Serialize};
3use std::fmt;
4
5#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize, WordList)]
6#[serde(into = "&'static str", try_from = "&str")]
7pub enum Gender {
8    #[alias = "female"]
9    #[alias = "woman"]
10    #[alias = "girl"]
11    Feminine,
12
13    #[alias = "male"]
14    #[alias = "man"]
15    #[alias = "boy"]
16    Masculine,
17
18    Neuter,
19
20    #[term = "non-binary"]
21    #[alias = "enby"]
22    #[alias = "nb"]
23    NonBinaryThey,
24}
25
26impl Gender {
27    pub fn name(&self) -> &'static str {
28        match self {
29            Self::Feminine => "feminine",
30            Self::Masculine => "masculine",
31            Self::Neuter => "neuter",
32            Self::NonBinaryThey => "non-binary",
33        }
34    }
35
36    pub fn pronouns(&self) -> &'static str {
37        match self {
38            Self::Feminine => "she/her",
39            Self::Masculine => "he/him",
40            Self::Neuter => "it",
41            Self::NonBinaryThey => "they/them",
42        }
43    }
44
45    pub fn they(&self) -> &'static str {
46        match self {
47            Self::Feminine => "she",
48            Self::Masculine => "he",
49            Self::Neuter => "it",
50            Self::NonBinaryThey => "they",
51        }
52    }
53
54    pub fn they_cap(&self) -> &'static str {
55        match self {
56            Self::Feminine => "She",
57            Self::Masculine => "He",
58            Self::Neuter => "It",
59            Self::NonBinaryThey => "They",
60        }
61    }
62
63    pub fn theyre(&self) -> &'static str {
64        match self {
65            Self::Feminine => "she's",
66            Self::Masculine => "he's",
67            Self::Neuter => "it's",
68            Self::NonBinaryThey => "they're",
69        }
70    }
71
72    pub fn theyre_cap(&self) -> &'static str {
73        match self {
74            Self::Feminine => "She's",
75            Self::Masculine => "He's",
76            Self::Neuter => "It's",
77            Self::NonBinaryThey => "They're",
78        }
79    }
80
81    pub fn theyve(&self) -> &'static str {
82        match self {
83            Self::Feminine => "she's",
84            Self::Masculine => "he's",
85            Self::Neuter => "it's",
86            Self::NonBinaryThey => "they've",
87        }
88    }
89
90    pub fn theyve_cap(&self) -> &'static str {
91        match self {
92            Self::Feminine => "She's",
93            Self::Masculine => "He's",
94            Self::Neuter => "It's",
95            Self::NonBinaryThey => "They've",
96        }
97    }
98
99    pub fn them(&self) -> &'static str {
100        match self {
101            Self::Feminine => "her",
102            Self::Masculine => "him",
103            Self::Neuter => "it",
104            Self::NonBinaryThey => "them",
105        }
106    }
107
108    pub fn them_cap(&self) -> &'static str {
109        match self {
110            Self::Feminine => "Her",
111            Self::Masculine => "Him",
112            Self::Neuter => "It",
113            Self::NonBinaryThey => "Them",
114        }
115    }
116
117    pub fn their(&self) -> &'static str {
118        match self {
119            Self::Feminine => "her",
120            Self::Masculine => "his",
121            Self::Neuter => "its",
122            Self::NonBinaryThey => "their",
123        }
124    }
125
126    pub fn their_cap(&self) -> &'static str {
127        match self {
128            Self::Feminine => "Her",
129            Self::Masculine => "His",
130            Self::Neuter => "Its",
131            Self::NonBinaryThey => "Their",
132        }
133    }
134
135    pub fn theirs(&self) -> &'static str {
136        match self {
137            Self::Feminine => "hers",
138            Self::Masculine => "his",
139            Self::Neuter => "its",
140            Self::NonBinaryThey => "theirs",
141        }
142    }
143
144    pub fn theirs_cap(&self) -> &'static str {
145        match self {
146            Self::Feminine => "Hers",
147            Self::Masculine => "His",
148            Self::Neuter => "Its",
149            Self::NonBinaryThey => "Theirs",
150        }
151    }
152
153    pub fn themself(&self) -> &'static str {
154        match self {
155            Self::Feminine => "herself",
156            Self::Masculine => "himself",
157            Self::Neuter => "itself",
158            Self::NonBinaryThey => "themself",
159        }
160    }
161
162    pub fn themself_cap(&self) -> &'static str {
163        match self {
164            Self::Feminine => "Herself",
165            Self::Masculine => "Himself",
166            Self::Neuter => "Itself",
167            Self::NonBinaryThey => "Themself",
168        }
169    }
170
171    pub fn conjugate<'a>(&self, singular_form: &'a str, plural_form: &'a str) -> &'a str {
172        if self == &Self::NonBinaryThey {
173            plural_form
174        } else {
175            singular_form
176        }
177    }
178}
179
180impl fmt::Display for Gender {
181    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
182        match self {
183            Self::Feminine => write!(f, "feminine (she/her)"),
184            Self::Masculine => write!(f, "masculine (he/him)"),
185            Self::Neuter => write!(f, "neuter (it)"),
186            Self::NonBinaryThey => write!(f, "non-binary (they/them)"),
187        }
188    }
189}
190
191#[cfg(test)]
192mod test {
193    use super::*;
194
195    #[test]
196    fn pronouns_test() {
197        let [f, m, n, t] = variants();
198
199        assert_eq!("she/her", f.pronouns());
200        assert_eq!("he/him", m.pronouns());
201        assert_eq!("it", n.pronouns());
202        assert_eq!("they/them", t.pronouns());
203
204        assert_eq!("she", f.they());
205        assert_eq!("She", f.they_cap());
206        assert_eq!("he", m.they());
207        assert_eq!("He", m.they_cap());
208        assert_eq!("it", n.they());
209        assert_eq!("It", n.they_cap());
210        assert_eq!("they", t.they());
211        assert_eq!("They", t.they_cap());
212
213        assert_eq!("she's", f.theyre());
214        assert_eq!("She's", f.theyre_cap());
215        assert_eq!("he's", m.theyre());
216        assert_eq!("He's", m.theyre_cap());
217        assert_eq!("it's", n.theyre());
218        assert_eq!("It's", n.theyre_cap());
219        assert_eq!("they're", t.theyre());
220        assert_eq!("They're", t.theyre_cap());
221
222        assert_eq!("she's", f.theyve());
223        assert_eq!("She's", f.theyve_cap());
224        assert_eq!("he's", m.theyve());
225        assert_eq!("He's", m.theyve_cap());
226        assert_eq!("it's", n.theyve());
227        assert_eq!("It's", n.theyve_cap());
228        assert_eq!("they've", t.theyve());
229        assert_eq!("They've", t.theyve_cap());
230
231        assert_eq!("her", f.them());
232        assert_eq!("Her", f.them_cap());
233        assert_eq!("him", m.them());
234        assert_eq!("Him", m.them_cap());
235        assert_eq!("it", n.them());
236        assert_eq!("It", n.them_cap());
237        assert_eq!("them", t.them());
238        assert_eq!("Them", t.them_cap());
239
240        assert_eq!("her", f.their());
241        assert_eq!("Her", f.their_cap());
242        assert_eq!("his", m.their());
243        assert_eq!("His", m.their_cap());
244        assert_eq!("its", n.their());
245        assert_eq!("Its", n.their_cap());
246        assert_eq!("their", t.their());
247        assert_eq!("Their", t.their_cap());
248
249        assert_eq!("hers", f.theirs());
250        assert_eq!("Hers", f.theirs_cap());
251        assert_eq!("his", m.theirs());
252        assert_eq!("His", m.theirs_cap());
253        assert_eq!("its", n.theirs());
254        assert_eq!("Its", n.theirs_cap());
255        assert_eq!("theirs", t.theirs());
256        assert_eq!("Theirs", t.theirs_cap());
257
258        assert_eq!("herself", f.themself());
259        assert_eq!("Herself", f.themself_cap());
260        assert_eq!("himself", m.themself());
261        assert_eq!("Himself", m.themself_cap());
262        assert_eq!("itself", n.themself());
263        assert_eq!("Itself", n.themself_cap());
264        assert_eq!("themself", t.themself());
265        assert_eq!("Themself", t.themself_cap());
266    }
267
268    #[test]
269    fn conjugate_test() {
270        let [f, m, n, t] = variants();
271
272        assert_eq!("conjugate", m.conjugate("conjugate", "conjugates"));
273        assert_eq!("conjugate", f.conjugate("conjugate", "conjugates"));
274        assert_eq!("conjugates", t.conjugate("conjugate", "conjugates"));
275        assert_eq!("conjugate", n.conjugate("conjugate", "conjugates"));
276    }
277
278    #[test]
279    fn fmt_test() {
280        assert_eq!("masculine (he/him)", format!("{}", Gender::Masculine));
281        assert_eq!("feminine (she/her)", format!("{}", Gender::Feminine));
282        assert_eq!(
283            "non-binary (they/them)",
284            format!("{}", Gender::NonBinaryThey)
285        );
286        assert_eq!("neuter (it)", format!("{}", Gender::Neuter));
287    }
288
289    #[test]
290    fn serialize_deserialize_test() {
291        let [f, m, n, t] = variants();
292
293        assert_eq!("\"feminine\"", serde_json::to_string(&f).unwrap());
294        assert_eq!("\"masculine\"", serde_json::to_string(&m).unwrap());
295        assert_eq!("\"neuter\"", serde_json::to_string(&n).unwrap());
296        assert_eq!("\"non-binary\"", serde_json::to_string(&t).unwrap());
297
298        let value: Gender = serde_json::from_str("\"feminine\"").unwrap();
299        assert_eq!(f, value);
300
301        let value: Gender = serde_json::from_str("\"masculine\"").unwrap();
302        assert_eq!(m, value);
303
304        let value: Gender = serde_json::from_str("\"neuter\"").unwrap();
305        assert_eq!(n, value);
306
307        let value: Gender = serde_json::from_str("\"non-binary\"").unwrap();
308        assert_eq!(t, value);
309    }
310
311    fn variants() -> [Gender; 4] {
312        [
313            Gender::Feminine,
314            Gender::Masculine,
315            Gender::Neuter,
316            Gender::NonBinaryThey,
317        ]
318    }
319}