Skip to main content

ixa_fips/
states.rs

1//! An enum for U.S. states as represented by FIPS Geographic Region Codes. This is a minimal subset of FIPS state codes
2//! which have been stable for every FIPS standard revision so far.
3//! See <https://www.census.gov/library/reference/code-lists/ansi.html#states>.
4//!
5//! Note that the `FIPSCode` encoded type only uses six bits to encode the state code, which can accommodate codes <= 63.
6//! Thus, it is best to only use `FIPSCode` for these states.
7
8use strum::{AsRefStr, FromRepr};
9
10use crate::errors::FIPSError;
11use crate::StateCode;
12
13#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, AsRefStr, FromRepr)]
14#[repr(u8)]
15pub enum USState {
16    AL = 1,
17    AK = 2,
18    AZ = 4,
19    AR = 5,
20    CA = 6,
21    CO = 8,
22    CT = 9,
23    DE = 10,
24    DC = 11, // District of Columbia
25    FL = 12,
26    GA = 13,
27    HI = 15,
28    ID = 16,
29    IL = 17,
30    IN = 18,
31    IA = 19,
32    KS = 20,
33    KY = 21,
34    LA = 22,
35    ME = 23,
36    MD = 24,
37    MA = 25,
38    MI = 26,
39    MN = 27,
40    MS = 28,
41    MO = 29,
42    MT = 30,
43    NE = 31,
44    NV = 32,
45    NH = 33,
46    NJ = 34,
47    NM = 35,
48    NY = 36,
49    NC = 37,
50    ND = 38,
51    OH = 39,
52    OK = 40,
53    OR = 41,
54    PA = 42,
55    RI = 44,
56    SC = 45,
57    SD = 46,
58    TN = 47,
59    TX = 48,
60    UT = 49,
61    VT = 50,
62    VA = 51,
63    WA = 53,
64    WV = 54,
65    WI = 55,
66    WY = 56,
67}
68
69impl USState {
70    /// Returns true if `self` is a state or District of Columbia
71    #[must_use]
72    pub fn is_state(&self) -> bool {
73        USState::is_state_code(*self as StateCode)
74    }
75
76    /// Returns true if the given state code is a state or District of Columbia
77    #[must_use]
78    pub fn is_state_code(value: StateCode) -> bool {
79        value <= 56u8 && ![3u8, 7, 14, 43, 52].contains(&value)
80    }
81
82    /// Returns the numeric FIPS code for this state.
83    #[must_use]
84    pub fn encode(&self) -> StateCode {
85        *self as StateCode
86    }
87
88    /// Returns the state for the given numeric FIPS code.
89    /// Returns `Err(FIPSError)` if the code is invalid.
90    pub fn decode(value: StateCode) -> Result<USState, FIPSError> {
91        Self::from_repr(value).ok_or(FIPSError::from_us_state(value))
92    }
93}
94
95impl From<USState> for StateCode {
96    fn from(value: USState) -> Self {
97        value.encode()
98    }
99}
100
101#[cfg(test)]
102mod tests {
103    use super::*;
104
105    #[test]
106    fn test_display() {
107        assert_eq!(USState::AK.as_ref(), "AK");
108    }
109
110    #[test]
111    fn test_is_state() {
112        assert!(USState::AK.is_state());
113        assert!(USState::DC.is_state());
114    }
115
116    #[test]
117    fn test_decode() {
118        assert_eq!(USState::DC, USState::decode(11).unwrap());
119        assert_eq!(USState::MN, USState::decode(27).unwrap());
120
121        assert!(USState::decode(99).is_err());
122        assert!(USState::decode(62).is_err());
123        assert!(USState::decode(63).is_err());
124        assert!(USState::decode(80).is_err());
125        assert!(USState::decode(90).is_err());
126        assert!(USState::decode(0).is_err());
127    }
128
129    #[test]
130    fn test_encode() {
131        assert_eq!(USState::DC.encode(), 11u8);
132        assert_eq!(USState::MN.encode(), 27u8);
133    }
134}