1use thiserror::Error;
2
3use crate::{EMLError, EMLValueResultExt as _, utils::StringValueData};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7pub enum ElectionCategory {
8 EK,
10 TK,
12 EP,
14 PS,
16 AB,
18 GR,
20 BC,
22 GC,
24 ER,
26 NR,
28 PR,
30 LR,
32 IR,
34}
35
36impl ElectionCategory {
37 pub fn new(s: impl AsRef<str>) -> Result<Self, EMLError> {
39 Self::from_eml_value(s).wrap_value_error()
40 }
41
42 pub fn from_eml_value(s: impl AsRef<str>) -> Result<Self, UnknownElectionCategoryError> {
44 let data = s.as_ref();
45 match data {
46 "EK" => Ok(ElectionCategory::EK),
47 "TK" => Ok(ElectionCategory::TK),
48 "EP" => Ok(ElectionCategory::EP),
49 "PS" => Ok(ElectionCategory::PS),
50 "AB" => Ok(ElectionCategory::AB),
51 "GR" => Ok(ElectionCategory::GR),
52 "BC" => Ok(ElectionCategory::BC),
53 "GC" => Ok(ElectionCategory::GC),
54 "ER" => Ok(ElectionCategory::ER),
55 "NR" => Ok(ElectionCategory::NR),
56 "PR" => Ok(ElectionCategory::PR),
57 "LR" => Ok(ElectionCategory::LR),
58 "IR" => Ok(ElectionCategory::IR),
59 _ => Err(UnknownElectionCategoryError(data.to_string())),
60 }
61 }
62
63 pub fn to_eml_value(&self) -> &'static str {
65 match self {
66 ElectionCategory::EK => "EK",
67 ElectionCategory::TK => "TK",
68 ElectionCategory::EP => "EP",
69 ElectionCategory::PS => "PS",
70 ElectionCategory::AB => "AB",
71 ElectionCategory::GR => "GR",
72 ElectionCategory::BC => "BC",
73 ElectionCategory::GC => "GC",
74 ElectionCategory::ER => "ER",
75 ElectionCategory::NR => "NR",
76 ElectionCategory::PR => "PR",
77 ElectionCategory::LR => "LR",
78 ElectionCategory::IR => "IR",
79 }
80 }
81}
82
83#[derive(Debug, Clone, Error, PartialEq, Eq)]
85#[error("Unknown election category: {0}")]
86pub struct UnknownElectionCategoryError(String);
87
88impl StringValueData for ElectionCategory {
89 type Error = UnknownElectionCategoryError;
90
91 fn parse_from_str(s: &str) -> Result<Self, Self::Error>
92 where
93 Self: Sized,
94 {
95 Self::from_eml_value(s)
96 }
97
98 fn to_raw_value(&self) -> String {
99 self.to_eml_value().to_string()
100 }
101}
102
103#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
105pub enum ElectionSubcategory {
106 PS1,
108 PS2,
110 AB1,
112 AB2,
114 GR1,
116 GR2,
118 BC,
120 GC,
122 ER1,
124 TK,
126 EK,
128 EP,
130 NR,
132 PR,
134 LR,
136 IR,
138}
139
140impl ElectionSubcategory {
141 pub fn new(s: impl AsRef<str>) -> Result<Self, EMLError> {
143 Self::from_eml_value(s).wrap_value_error()
144 }
145
146 pub fn from_eml_value(s: impl AsRef<str>) -> Result<Self, UnknownElectionSubcategoryError> {
148 let data = s.as_ref();
149 match data {
150 "PS1" => Ok(ElectionSubcategory::PS1),
151 "PS2" => Ok(ElectionSubcategory::PS2),
152 "AB1" => Ok(ElectionSubcategory::AB1),
153 "AB2" => Ok(ElectionSubcategory::AB2),
154 "GR1" => Ok(ElectionSubcategory::GR1),
155 "GR2" => Ok(ElectionSubcategory::GR2),
156 "BC" => Ok(ElectionSubcategory::BC),
157 "GC" => Ok(ElectionSubcategory::GC),
158 "ER1" => Ok(ElectionSubcategory::ER1),
159 "TK" => Ok(ElectionSubcategory::TK),
160 "EK" => Ok(ElectionSubcategory::EK),
161 "EP" => Ok(ElectionSubcategory::EP),
162 "NR" => Ok(ElectionSubcategory::NR),
163 "PR" => Ok(ElectionSubcategory::PR),
164 "LR" => Ok(ElectionSubcategory::LR),
165 "IR" => Ok(ElectionSubcategory::IR),
166 _ => Err(UnknownElectionSubcategoryError(data.to_string())),
167 }
168 }
169
170 pub fn to_eml_value(&self) -> &'static str {
172 match self {
173 ElectionSubcategory::PS1 => "PS1",
174 ElectionSubcategory::PS2 => "PS2",
175 ElectionSubcategory::AB1 => "AB1",
176 ElectionSubcategory::AB2 => "AB2",
177 ElectionSubcategory::GR1 => "GR1",
178 ElectionSubcategory::GR2 => "GR2",
179 ElectionSubcategory::BC => "BC",
180 ElectionSubcategory::GC => "GC",
181 ElectionSubcategory::ER1 => "ER1",
182 ElectionSubcategory::TK => "TK",
183 ElectionSubcategory::EK => "EK",
184 ElectionSubcategory::EP => "EP",
185 ElectionSubcategory::NR => "NR",
186 ElectionSubcategory::PR => "PR",
187 ElectionSubcategory::LR => "LR",
188 ElectionSubcategory::IR => "IR",
189 }
190 }
191
192 pub fn is_subcategory_of(self, category: ElectionCategory) -> bool {
194 match self {
195 ElectionSubcategory::PS1 | ElectionSubcategory::PS2 => category == ElectionCategory::PS,
196 ElectionSubcategory::AB1 | ElectionSubcategory::AB2 => category == ElectionCategory::AB,
197 ElectionSubcategory::GR1 | ElectionSubcategory::GR2 => category == ElectionCategory::GR,
198 ElectionSubcategory::BC => category == ElectionCategory::BC,
199 ElectionSubcategory::GC => category == ElectionCategory::GC,
200 ElectionSubcategory::ER1 => category == ElectionCategory::ER,
201 ElectionSubcategory::TK => category == ElectionCategory::TK,
202 ElectionSubcategory::EK => category == ElectionCategory::EK,
203 ElectionSubcategory::EP => category == ElectionCategory::EP,
204 ElectionSubcategory::NR => category == ElectionCategory::NR,
205 ElectionSubcategory::PR => category == ElectionCategory::PR,
206 ElectionSubcategory::LR => category == ElectionCategory::LR,
207 ElectionSubcategory::IR => category == ElectionCategory::IR,
208 }
209 }
210}
211
212#[derive(Debug, Clone, Error, PartialEq, Eq)]
214#[error("Unknown election subcategory: {0}")]
215pub struct UnknownElectionSubcategoryError(String);
216
217impl StringValueData for ElectionSubcategory {
218 type Error = UnknownElectionSubcategoryError;
219
220 fn parse_from_str(s: &str) -> Result<Self, Self::Error>
221 where
222 Self: Sized,
223 {
224 Self::from_eml_value(s)
225 }
226
227 fn to_raw_value(&self) -> String {
228 self.to_eml_value().to_string()
229 }
230}
231
232#[cfg(test)]
233mod tests {
234 use super::*;
235
236 #[test]
237 fn test_election_category_from_str() {
238 assert_eq!(
239 ElectionCategory::from_eml_value("EK"),
240 Ok(ElectionCategory::EK)
241 );
242 assert_eq!(
243 ElectionCategory::from_eml_value("TK"),
244 Ok(ElectionCategory::TK)
245 );
246 assert_eq!(
247 ElectionCategory::from_eml_value("UNKNOWN"),
248 Err(UnknownElectionCategoryError("UNKNOWN".to_string()))
249 );
250 }
251
252 #[test]
253 fn test_election_category_to_str() {
254 assert_eq!(ElectionCategory::EK.to_eml_value(), "EK");
255 assert_eq!(ElectionCategory::TK.to_eml_value(), "TK");
256 }
257}