1use std::{convert::{TryFrom, TryInto}, fmt::Display};
2
3use crate::ConversionError;
4
5#[derive(Debug, PartialEq, Clone, Copy)]
14
15pub enum State {
16 Alabama,
17 Alaska,
18 Arizona,
19 Arkansas,
20 California,
21 Colorado,
22 Connecticut,
23 Delaware,
24 DistrictOfColumbia,
25 Florida,
26 Georgia,
27 Hawaii,
28 Idaho,
29 Illinois,
30 Indiana,
31 Iowa,
32 Kansas,
33 Kentucky,
34 Louisiana,
35 Maine,
36 Maryland,
37 Massachusetts,
38 Michigan,
39 Minnesota,
40 Mississippi,
41 Missouri,
42 Montana,
43 Nebraska,
44 Nevada,
45 NewHampshire,
46 NewJersey,
47 NewMexico,
48 NewYork,
49 NorthCarolina,
50 NorthDakota,
51 Ohio,
52 Oklahoma,
53 Oregon,
54 Pennsylvania,
55 RhodeIsland,
56 SouthCarolina,
57 SouthDakota,
58 Tennessee,
59 Texas,
60 Utah,
61 Vermont,
62 Virginia,
63 Washington,
64 WestVirginia,
65 Wisconsin,
66 Wyoming,
67 PuertoRico,
68}
69
70impl State {
71 pub fn abbreviation(&self) -> &'static str {
73 match self {
74 State::Alabama => "AL",
75 State::Alaska => "AK",
76 State::Arizona => "AZ",
77 State::Arkansas => "AR",
78 State::California => "CA",
79 State::Colorado => "CO",
80 State::Connecticut => "CT",
81 State::Delaware => "DE",
82 State::DistrictOfColumbia => "DC",
83 State::Florida => "FL",
84 State::Georgia => "GA",
85 State::Hawaii => "HI",
86 State::Idaho => "ID",
87 State::Illinois => "IL",
88 State::Indiana => "IN",
89 State::Iowa => "IA",
90 State::Kansas => "KS",
91 State::Kentucky => "KY",
92 State::Louisiana => "LA",
93 State::Maine => "ME",
94 State::Maryland => "MD",
95 State::Massachusetts => "MA",
96 State::Michigan => "MI",
97 State::Minnesota => "MN",
98 State::Mississippi => "MS",
99 State::Missouri => "MO",
100 State::Montana => "MT",
101 State::Nebraska => "NE",
102 State::Nevada => "NV",
103 State::NewHampshire => "NH",
104 State::NewJersey => "NJ",
105 State::NewMexico => "NM",
106 State::NewYork => "NY",
107 State::NorthCarolina => "NC",
108 State::NorthDakota => "ND",
109 State::Ohio => "OH",
110 State::Oklahoma => "OK",
111 State::Oregon => "OR",
112 State::Pennsylvania => "PA",
113 State::RhodeIsland => "RI",
114 State::SouthCarolina => "SC",
115 State::SouthDakota => "SD",
116 State::Tennessee => "TN",
117 State::Texas => "TX",
118 State::Utah => "UT",
119 State::Vermont => "VT",
120 State::Virginia => "VA",
121 State::Washington => "WA",
122 State::WestVirginia => "WV",
123 State::Wisconsin => "WI",
124 State::Wyoming => "WY",
125 State::PuertoRico => "PR",
126 }
127 }
128}
129
130impl TryFrom<String> for State {
131 type Error = ConversionError;
132
133 fn try_from(value: String) -> Result<Self, Self::Error> {
134 match value.to_lowercase().replace(" ", "").as_str() {
135 "al" | "alabama" => Ok(State::Alabama),
136 "ak" | "alaska" => Ok(State::Alaska),
137 "az" | "arizona" => Ok(State::Arizona),
138 "ar" | "arkansas" => Ok(State::Arkansas),
139 "ca" | "california" => Ok(State::California),
140 "co" | "colorado" => Ok(State::Colorado),
141 "ct" | "connecticut" => Ok(State::Connecticut),
142 "de" | "delaware" => Ok(State::Delaware),
143 "dc" | "districtofcolumbia" => Ok(State::DistrictOfColumbia),
144 "fl" | "florida" => Ok(State::Florida),
145 "ga" | "georgia" => Ok(State::Georgia),
146 "hi" | "hawaii" => Ok(State::Hawaii),
147 "id" | "idaho" => Ok(State::Idaho),
148 "il" | "illinois" => Ok(State::Illinois),
149 "in" | "indiana" => Ok(State::Indiana),
150 "ia" | "iowa" => Ok(State::Iowa),
151 "ks" | "kansas" => Ok(State::Kansas),
152 "ky" | "kentucky" => Ok(State::Kentucky),
153 "la" | "louisiana" => Ok(State::Louisiana),
154 "me" | "maine" => Ok(State::Maine),
155 "md" | "maryland" => Ok(State::Maryland),
156 "ma" | "massachusetts" => Ok(State::Massachusetts),
157 "mi" | "michigan" => Ok(State::Michigan),
158 "mn" | "minnesota" => Ok(State::Minnesota),
159 "ms" | "mississippi" => Ok(State::Mississippi),
160 "mo" | "missouri" => Ok(State::Missouri),
161 "mt" | "montana" => Ok(State::Montana),
162 "ne" | "nebraska" => Ok(State::Nebraska),
163 "nv" | "nevada" => Ok(State::Nevada),
164 "nh" | "newhampshire" => Ok(State::NewHampshire),
165 "nj" | "newjersey" => Ok(State::NewJersey),
166 "nm" | "newmexico" => Ok(State::NewMexico),
167 "ny" | "newyork" => Ok(State::NewYork),
168 "nc" | "northcarolina" => Ok(State::NorthCarolina),
169 "nd" | "northdakota" => Ok(State::NorthDakota),
170 "oh" | "ohio" => Ok(State::Ohio),
171 "ok" | "oklahoma" => Ok(State::Oklahoma),
172 "or" | "oregon" => Ok(State::Oregon),
173 "pa" | "pennsylvania" => Ok(State::Pennsylvania),
174 "ri" | "rhodeisland" => Ok(State::RhodeIsland),
175 "sc" | "southcarolina" => Ok(State::SouthCarolina),
176 "sd" | "southdakota" => Ok(State::SouthDakota),
177 "tn" | "tennessee" => Ok(State::Tennessee),
178 "tx" | "texas" => Ok(State::Texas),
179 "ut" | "utah" => Ok(State::Utah),
180 "vt" | "vermont" => Ok(State::Vermont),
181 "va" | "virginia" => Ok(State::Virginia),
182 "wa" | "washington" => Ok(State::Washington),
183 "wv" | "westvirginia" => Ok(State::WestVirginia),
184 "wi" | "wisconsin" => Ok(State::Wisconsin),
185 "wy" | "wyoming" => Ok(State::Wyoming),
186 "pr" | "puertorico" => Ok(State::PuertoRico),
187 _ => Err(ConversionError),
188 }
189 }
190}
191
192impl Display for State {
193 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
194 write!(
195 f,
196 "{}",
197 match self {
198 State::Alabama => "Alabama",
199 State::Alaska => "Alaska",
200 State::Arizona => "Arizona",
201 State::Arkansas => "Arkansas",
202 State::California => "California",
203 State::Colorado => "Colorado",
204 State::Connecticut => "Connecticut",
205 State::Delaware => "Delaware",
206 State::DistrictOfColumbia => "District of Columbia",
207 State::Florida => "Florida",
208 State::Georgia => "Georgia",
209 State::Hawaii => "Hawaii",
210 State::Idaho => "Idaho",
211 State::Illinois => "Illinois",
212 State::Indiana => "Indiana",
213 State::Iowa => "Iowa",
214 State::Kansas => "Kansas",
215 State::Kentucky => "Kentucky",
216 State::Louisiana => "Louisiana",
217 State::Maine => "Maine",
218 State::Maryland => "Maryland",
219 State::Massachusetts => "Massachusetts",
220 State::Michigan => "Michigan",
221 State::Minnesota => "Minnesota",
222 State::Mississippi => "Mississippi",
223 State::Missouri => "Missouri",
224 State::Montana => "Montana",
225 State::Nebraska => "Nebraska",
226 State::Nevada => "Nevada",
227 State::NewHampshire => "New Hampshire",
228 State::NewJersey => "New Jersey",
229 State::NewMexico => "New Mexico",
230 State::NewYork => "New York",
231 State::NorthCarolina => "North Carolina",
232 State::NorthDakota => "North Dakota",
233 State::Ohio => "Ohio",
234 State::Oklahoma => "Oklahoma",
235 State::Oregon => "Oregon",
236 State::Pennsylvania => "Pennsylvania",
237 State::RhodeIsland => "Rhode Island",
238 State::SouthCarolina => "South Carolina",
239 State::SouthDakota => "South Dakota",
240 State::Tennessee => "Tennessee",
241 State::Texas => "Texas",
242 State::Utah => "Utah",
243 State::Vermont => "Vermont",
244 State::Virginia => "Virginia",
245 State::Washington => "Washington",
246 State::WestVirginia => "West Virginia",
247 State::Wisconsin => "Wisconsin",
248 State::Wyoming => "Wyoming",
249 State::PuertoRico => "Puerto Rico",
250 }
251 )
252 }
253}
254
255#[cfg(all(feature = "serde", not(feature = "serde_abbreviation")))]
256impl serde::Serialize for State {
257 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
258 where
259 S: serde::Serializer,
260 {
261 serializer.serialize_str(&self.to_string())
262 }
263}
264
265#[cfg(feature = "serde_abbreviation")]
266impl serde::Serialize for State {
267 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
268 where
269 S: serde::Serializer,
270 {
271 serializer.serialize_str(self.abbreviation())
272 }
273}
274
275#[cfg(feature = "serde")]
276impl<'de> serde::Deserialize<'de> for State {
277 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
278 where
279 D: serde::Deserializer<'de>,
280 {
281 let s = String::deserialize(deserializer)?;
282
283 match s.clone().try_into() {
284 Ok(state) => Ok(state),
285 Err(_) => Err(serde::de::Error::unknown_variant(
286 &s,
287 &[
288 "AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "DC", "FL", "GA", "HI", "ID",
289 "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD", "MA", "MI", "MN", "MS", "MO",
290 "MT", "NE", "NV", "NH", "NJ", "NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA",
291 "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY",
292 ],
293 )),
294 }
295 }
296}