us_state_info/
states.rs

1use std::{convert::{TryFrom, TryInto}, fmt::Display};
2
3use crate::ConversionError;
4
5/// Enumeration of all states in the US.
6///
7/// ```
8/// use us_state_info::State;
9/// let iowa_state = State::Iowa;
10/// format!("{}-{}", iowa_state, iowa_state.abbreviation());
11///
12/// ```
13#[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    /// Returns the two letter abbreviation for the state.
72    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}