Skip to main content

iso4217_static/
lib.rs

1//! Static ISO 4217 Data
2
3#![doc = include_str!("../README.md")]
4#![no_std]
5
6#[cfg(feature = "serde")]
7pub mod serde;
8
9use core::str::FromStr;
10use iso3166_static::{Alpha2, Alpha3, Numeric};
11
12iso4217_macros::generate!(xml = "list-one.xml", zerocopy = true);
13
14impl Error {
15    /// Whether this error is of the `InvalidCode` variant.
16    #[must_use]
17    pub const fn is_invalid_code(&self) -> bool {
18        matches!(self, Self::InvalidCode)
19    }
20
21    /// Whether this error is of the `InvalidLength` variant.
22    #[must_use]
23    pub const fn is_invalid_length(&self) -> bool {
24        matches!(self, Self::InvalidLength)
25    }
26
27    /// Whether this error is of the `InvalidCharset` variant.
28    #[must_use]
29    pub const fn is_invalid_charset(&self) -> bool {
30        matches!(self, Self::InvalidCharset)
31    }
32
33    /// Whether this error is of the `InvalidCharset` variant.
34    #[must_use]
35    pub const fn is_no_universal_currency(&self) -> bool {
36        matches!(self, Self::NoUniversalCurrency)
37    }
38}
39
40impl AsRef<str> for Currency {
41    fn as_ref(&self) -> &str {
42        self.as_str()
43    }
44}
45
46impl FromStr for Currency {
47    type Err = Error;
48
49    fn from_str(s: &str) -> Result<Self, Self::Err> {
50        Self::try_from(s)
51    }
52}
53
54impl TryFrom<u16> for Currency {
55    type Error = Error;
56
57    fn try_from(value: u16) -> Result<Self, Self::Error> {
58        Self::from_u16(value)
59    }
60}
61
62impl TryFrom<&str> for Currency {
63    type Error = Error;
64
65    fn try_from(value: &str) -> Result<Self, Self::Error> {
66        Self::from_str_slice(value)
67    }
68}
69
70impl TryFrom<Numeric> for Currency {
71    type Error = Error;
72
73    fn try_from(value: Numeric) -> Result<Self, Self::Error> {
74        Self::from_numeric_country(value).ok_or(Error::NoUniversalCurrency)
75    }
76}
77
78impl TryFrom<Alpha2> for Currency {
79    type Error = Error;
80
81    fn try_from(value: Alpha2) -> Result<Self, Self::Error> {
82        Self::from_alpha2_country(value).ok_or(Error::NoUniversalCurrency)
83    }
84}
85
86impl TryFrom<Alpha3> for Currency {
87    type Error = Error;
88
89    fn try_from(value: Alpha3) -> Result<Self, Self::Error> {
90        Self::from_alpha3_country(value).ok_or(Error::NoUniversalCurrency)
91    }
92}
93
94#[cfg(test)]
95mod test {
96    use super::*;
97    use iso3166_static::{Alpha2, Alpha3, Numeric};
98
99    #[test]
100    fn for_country() {
101        const NO_CURRENCY: &[Numeric] = &[
102            Numeric::Antarctica,
103            Numeric::SouthGeorgiaAndTheSouthSandwichIslands,
104            Numeric::Palestine,
105        ];
106
107        for i in 1..=899 {
108            // if the numeric code is valid, and it's not user-assigned.
109            if let Ok(numeric) = Numeric::from_u16(i)
110                && let Ok(alpha2) = Alpha2::from_numeric(numeric)
111                && let Ok(alpha3) = Alpha3::from_numeric(numeric)
112            {
113                let numeric_currency = Currency::try_from(numeric);
114                let alpha2_currency = Currency::try_from(alpha2);
115                let alpha3_currency = Currency::try_from(alpha3);
116
117                if NO_CURRENCY.contains(&numeric) {
118                    assert_eq!(
119                        Error::NoUniversalCurrency,
120                        numeric_currency.expect_err("no currency")
121                    );
122                    assert_eq!(
123                        Error::NoUniversalCurrency,
124                        alpha2_currency.expect_err("no currency")
125                    );
126                    assert_eq!(
127                        Error::NoUniversalCurrency,
128                        alpha3_currency.expect_err("no currency")
129                    );
130                } else {
131                    assert!(numeric_currency.is_ok());
132                    assert!(alpha2_currency.is_ok());
133                    assert!(alpha3_currency.is_ok());
134                }
135            }
136        }
137    }
138}