world_region/
impl_serde.rs

1// ---------------- [ File: src/impl_serde.rs ]
2crate::ix!();
3
4// Serialization/Deserialization
5// We'll store as a map: {"continent": "<ContinentName>", "country": "<CountryName>" [,"region": "<SubregionName>"]}
6#[cfg(not(feature = "serde_abbreviation"))]
7impl Serialize for WorldRegion {
8    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
9    where S: Serializer {
10        let continent_str = match self {
11            WorldRegion::Africa(_)                     => "Africa",
12            WorldRegion::Asia(_)                       => "Asia",
13            WorldRegion::Europe(_)                     => "Europe",
14            WorldRegion::NorthAmerica(_)               => "North America",
15            WorldRegion::SouthAmerica(_)               => "South America",
16            WorldRegion::CentralAmerica(_)             => "Central America",
17            WorldRegion::AustraliaOceaniaAntarctica(_) => "Australia/Oceania/Antarctica",
18        };
19
20        // Start by creating a Serializer map
21        let mut map = serializer.serialize_map(None)?;
22        map.serialize_entry("continent", continent_str)?;
23
24        // Now serialize the inner region separately and insert its keys
25        let inner_json = match self {
26            WorldRegion::Africa(r)                     => serde_json::to_value(r).map_err(serde::ser::Error::custom)?,
27            WorldRegion::Asia(r)                       => serde_json::to_value(r).map_err(serde::ser::Error::custom)?,
28            WorldRegion::Europe(r)                     => serde_json::to_value(r).map_err(serde::ser::Error::custom)?,
29            WorldRegion::NorthAmerica(r)               => serde_json::to_value(r).map_err(serde::ser::Error::custom)?,
30            WorldRegion::SouthAmerica(r)               => serde_json::to_value(r).map_err(serde::ser::Error::custom)?,
31            WorldRegion::CentralAmerica(r)             => serde_json::to_value(r).map_err(serde::ser::Error::custom)?,
32            WorldRegion::AustraliaOceaniaAntarctica(r) => serde_json::to_value(r).map_err(serde::ser::Error::custom)?,
33        };
34
35        // If the inner serialization produced an object, insert its keys into our map
36        if let Some(obj) = inner_json.as_object() {
37            for (k, v) in obj {
38                map.serialize_entry(k, v).map_err(serde::ser::Error::custom)?;
39            }
40        }
41
42        map.end()
43    }
44}
45
46#[cfg(feature = "serde_abbreviation")]
47impl Serialize for WorldRegion {
48    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
49    where S: Serializer {
50        // If abbreviation feature is used, just serialize abbreviation:
51        serializer.serialize_str(self.abbreviation())
52    }
53}
54
55impl<'de> Deserialize<'de> for WorldRegion {
56    fn deserialize<D>(deserializer: D) -> Result<WorldRegion, D::Error>
57    where D: Deserializer<'de> {
58        use serde_json::Value;
59        let v = Value::deserialize(deserializer)?;
60
61        let continent = v.get("continent").and_then(Value::as_str)
62            .ok_or_else(|| DeError::missing_field("continent"))?;
63
64        // We'll remove "continent" from the object and then try deserializing into the appropriate region enum.
65        let mut map = v.as_object().cloned().ok_or_else(|| DeError::custom("Expected a map"))?;
66        map.remove("continent");
67
68        let value_without_continent = Value::Object(map);
69
70        match continent {
71            "Africa"                       => Ok(WorldRegion::Africa(serde_json::from_value(value_without_continent).map_err(DeError::custom)?)),
72            "Asia"                         => Ok(WorldRegion::Asia(serde_json::from_value(value_without_continent).map_err(DeError::custom)?)),
73            "Europe"                       => Ok(WorldRegion::Europe(serde_json::from_value(value_without_continent).map_err(DeError::custom)?)),
74            "North America"                => Ok(WorldRegion::NorthAmerica(serde_json::from_value(value_without_continent).map_err(DeError::custom)?)),
75            "South America"                => Ok(WorldRegion::SouthAmerica(serde_json::from_value(value_without_continent).map_err(DeError::custom)?)),
76            "Central America"              => Ok(WorldRegion::CentralAmerica(serde_json::from_value(value_without_continent).map_err(DeError::custom)?)),
77            "Australia/Oceania/Antarctica" => Ok(WorldRegion::AustraliaOceaniaAntarctica(serde_json::from_value(value_without_continent).map_err(DeError::custom)?)),
78            other                          => Err(DeError::unknown_variant(other, &[
79                "Africa","Asia","Europe","North America","South America","Central America","Australia/Oceania/Antarctica"
80            ]))
81        }
82    }
83}