iso3166_static/
serde_.rs

1//! Serialization support for our types
2
3#[cfg(feature = "serde")]
4use crate::Numeric;
5use crate::{Alpha2, Alpha3};
6use core::{
7    fmt::{Display, Formatter, Result as FmtResult},
8    marker::PhantomData,
9    str::FromStr,
10};
11use serde::{
12    Deserialize, Serialize,
13    de::{Error, Visitor},
14};
15
16#[cfg(feature = "serde")]
17impl Serialize for Alpha2 {
18    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
19    where
20        S: serde::Serializer,
21    {
22        serializer.serialize_str(self.as_str())
23    }
24}
25
26#[cfg(feature = "serde")]
27impl<'de> Deserialize<'de> for Alpha2 {
28    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
29    where
30        D: serde::Deserializer<'de>,
31    {
32        deserializer.deserialize_str(StrVisitor::<Self>::default())
33    }
34}
35
36#[cfg(feature = "serde")]
37impl Serialize for Alpha3 {
38    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
39    where
40        S: serde::Serializer,
41    {
42        serializer.serialize_str(self.as_str())
43    }
44}
45
46#[cfg(feature = "serde")]
47impl<'de> Deserialize<'de> for Alpha3 {
48    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
49    where
50        D: serde::Deserializer<'de>,
51    {
52        deserializer.deserialize_str(StrVisitor::<Self>::default())
53    }
54}
55
56#[cfg(feature = "serde")]
57impl Serialize for Numeric {
58    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
59    where
60        S: serde::Serializer,
61    {
62        serializer.serialize_u16(self.as_u16())
63    }
64}
65
66#[cfg(feature = "serde")]
67impl<'de> Deserialize<'de> for Numeric {
68    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
69    where
70        D: serde::Deserializer<'de>,
71    {
72        deserializer.deserialize_u16(NumericVisitor)
73    }
74}
75
76struct NumericVisitor;
77
78impl Visitor<'_> for NumericVisitor {
79    type Value = Numeric;
80
81    fn expecting(&self, f: &mut Formatter<'_>) -> FmtResult {
82        f.write_str("An ISO3166 numeric code")
83    }
84
85    fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
86    where
87        E: Error,
88    {
89        let value = u16::try_from(v).map_err(E::custom)?;
90        Numeric::from_u16(value).map_err(E::custom)
91    }
92
93    fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
94    where
95        E: Error,
96    {
97        let value = u16::try_from(v).map_err(E::custom)?;
98        Numeric::from_u16(value).map_err(E::custom)
99    }
100
101    fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
102    where
103        E: Error,
104    {
105        let value = u16::try_from(v).map_err(E::custom)?;
106        Numeric::from_u16(value).map_err(E::custom)
107    }
108
109    fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
110    where
111        E: Error,
112    {
113        let value = u16::try_from(v).map_err(E::custom)?;
114        Numeric::from_u16(value).map_err(E::custom)
115    }
116
117    fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
118    where
119        E: Error,
120    {
121        let value = u16::try_from(v).map_err(E::custom)?;
122        Numeric::from_u16(value).map_err(E::custom)
123    }
124
125    fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
126    where
127        E: Error,
128    {
129        let value = u16::try_from(v).map_err(E::custom)?;
130        Numeric::from_u16(value).map_err(E::custom)
131    }
132
133    fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
134    where
135        E: Error,
136    {
137        let value = u16::try_from(v).map_err(E::custom)?;
138        Numeric::from_u16(value).map_err(E::custom)
139    }
140
141    fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
142    where
143        E: Error,
144    {
145        Numeric::from_u16(v).map_err(E::custom)
146    }
147}
148
149struct StrVisitor<T> {
150    _phantom: PhantomData<T>,
151}
152
153impl<T> Default for StrVisitor<T> {
154    fn default() -> Self {
155        Self {
156            _phantom: PhantomData,
157        }
158    }
159}
160
161impl<'de, T> Visitor<'de> for StrVisitor<T>
162where
163    T: FromStr,
164    T::Err: Display,
165{
166    type Value = T;
167
168    fn expecting(&self, f: &mut Formatter<'_>) -> FmtResult {
169        f.write_str("An ISO Alpha2 string code")
170    }
171
172    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
173    where
174        E: Error,
175    {
176        Self::Value::from_str(v).map_err(|err| E::custom(err))
177    }
178}
179
180#[cfg(test)]
181mod test {
182    use crate::{Alpha2, Alpha3, Numeric};
183
184    const NUMERIC: Numeric = Numeric::UnitedStatesOfAmerica;
185    const NUMERIC_JSON: &str = "840";
186
187    const ALPHA2: Alpha2 = Alpha2::from_numeric(NUMERIC);
188    const ALPHA2_JSON: &str = "\"US\"";
189
190    const ALPHA3: Alpha3 = Alpha3::from_numeric(NUMERIC);
191    const ALPHA3_JSON: &str = "\"USA\"";
192
193    #[test]
194    fn numeric() {
195        let json = serde_json::to_string(&NUMERIC).expect("numeric serialization");
196        assert_eq!(NUMERIC_JSON, json);
197
198        let actual = serde_json::from_str::<Numeric>(&json).expect("numeric deserialization");
199        assert_eq!(NUMERIC, actual);
200    }
201
202    #[test]
203    fn alpha2() {
204        let json = serde_json::to_string(&ALPHA2).expect("alpha2 serialization");
205        assert_eq!(ALPHA2_JSON, json);
206
207        let actual = serde_json::from_str::<Alpha2>(&json).expect("alpha2 deserialization");
208        assert_eq!(ALPHA2, actual);
209    }
210
211    #[test]
212    fn alpha3() {
213        let json = serde_json::to_string(&ALPHA3).expect("alpha2 serialization");
214        assert_eq!(ALPHA3_JSON, json);
215
216        let actual = serde_json::from_str::<Alpha3>(&json).expect("alpha2 deserialization");
217        assert_eq!(ALPHA3, actual);
218    }
219}