Skip to main content

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