1#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
13#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
14pub enum Gender {
15 #[default]
16 Unknown,
17 Masc,
18 Fem,
19 Neut,
20 Common,
22}
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
28#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
29pub enum Number {
30 #[default]
31 Unknown,
32 Singular,
33 Plural,
34 Dual,
36}
37
38#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
43#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
44pub enum Case {
45 #[default]
46 Unknown,
47 Nominative,
48 Accusative,
49 Dative,
50 Genitive,
51}
52
53#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
57#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
58pub enum Definiteness {
59 #[default]
60 Unknown,
61 Definite,
62 Indefinite,
63}
64
65#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
69#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
70pub enum Animacy {
71 #[default]
72 Unknown,
73 Animate,
74 Inanimate,
75}
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
86#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
87pub enum AgreementPerson {
88 First,
89 Second,
90 #[default]
91 Third,
92}
93
94#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
115#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
116pub struct AgreementFeatures {
117 pub gender: Gender,
118 pub number: Number,
119 pub case: Case,
120 pub definiteness: Definiteness,
121 pub animacy: Animacy,
122 pub person: AgreementPerson,
123}
124
125impl AgreementFeatures {
126 pub fn new() -> Self {
129 Self::default()
130 }
131
132 pub fn with_gender(mut self, g: Gender) -> Self {
134 self.gender = g;
135 self
136 }
137
138 pub fn with_number(mut self, n: Number) -> Self {
140 self.number = n;
141 self
142 }
143
144 pub fn with_case(mut self, c: Case) -> Self {
146 self.case = c;
147 self
148 }
149
150 pub fn with_definiteness(mut self, d: Definiteness) -> Self {
152 self.definiteness = d;
153 self
154 }
155
156 pub fn with_animacy(mut self, a: Animacy) -> Self {
158 self.animacy = a;
159 self
160 }
161
162 pub fn with_person(mut self, p: AgreementPerson) -> Self {
164 self.person = p;
165 self
166 }
167}
168
169#[cfg(test)]
170mod tests {
171 use super::*;
172
173 #[test]
174 fn default_is_all_unknown() {
175 let f = AgreementFeatures::default();
176 assert_eq!(f.gender, Gender::Unknown);
177 assert_eq!(f.number, Number::Unknown);
178 assert_eq!(f.case, Case::Unknown);
179 assert_eq!(f.definiteness, Definiteness::Unknown);
180 assert_eq!(f.animacy, Animacy::Unknown);
181 assert_eq!(f.person, AgreementPerson::Third);
182 }
183
184 #[test]
185 fn builder_with_methods_set_fields() {
186 let f = AgreementFeatures::new()
187 .with_gender(Gender::Fem)
188 .with_number(Number::Singular)
189 .with_case(Case::Accusative)
190 .with_definiteness(Definiteness::Definite)
191 .with_animacy(Animacy::Animate)
192 .with_person(AgreementPerson::First);
193 assert_eq!(f.gender, Gender::Fem);
194 assert_eq!(f.number, Number::Singular);
195 assert_eq!(f.case, Case::Accusative);
196 assert_eq!(f.definiteness, Definiteness::Definite);
197 assert_eq!(f.animacy, Animacy::Animate);
198 assert_eq!(f.person, AgreementPerson::First);
199 }
200
201 #[test]
202 fn features_are_copy() {
203 fn takes_copy<T: Copy>(_: T) {}
204 takes_copy(AgreementFeatures::default());
205 takes_copy(Gender::Fem);
206 takes_copy(Number::Plural);
207 takes_copy(Case::Dative);
208 takes_copy(Definiteness::Indefinite);
209 takes_copy(Animacy::Animate);
210 takes_copy(AgreementPerson::First);
211 }
212
213 #[test]
214 fn all_gender_variants_are_distinct() {
215 assert_ne!(Gender::Masc, Gender::Fem);
216 assert_ne!(Gender::Fem, Gender::Neut);
217 assert_ne!(Gender::Neut, Gender::Common);
218 assert_ne!(Gender::Common, Gender::Unknown);
219 }
220
221 #[test]
222 fn all_number_variants_are_distinct() {
223 assert_ne!(Number::Singular, Number::Plural);
224 assert_ne!(Number::Plural, Number::Dual);
225 assert_ne!(Number::Dual, Number::Unknown);
226 }
227
228 #[test]
229 fn all_case_variants_are_distinct() {
230 assert_ne!(Case::Nominative, Case::Accusative);
231 assert_ne!(Case::Accusative, Case::Dative);
232 assert_ne!(Case::Dative, Case::Genitive);
233 assert_ne!(Case::Genitive, Case::Unknown);
234 }
235}