iso3166_static/
serde_.rs

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