Savior

More complex custom (de-)serialization in Serde

Feb 14th, 2020
703
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. extern crate serde_derive;
  2. extern crate serde_json;
  3.  
  4. use serde::de::{self, MapAccess, SeqAccess, Visitor};
  5. use serde::ser::SerializeSeq;
  6. use serde::{Deserialize, Deserializer, Serialize, Serializer};
  7.  
  8. use std::error::Error;
  9. use std::{cmp, fmt, marker::PhantomData};
  10.  
  11. #[derive(Debug, Deserialize, Serialize)]
  12. struct City<'a> {
  13.    name: &'a str,
  14.     location: Location,
  15.     color: Color,
  16.     #[serde(deserialize_with = "deserialize_seq_to_max")]
  17.     #[serde(rename(deserialize = "temperature"))]
  18.     max_temperature: i32,
  19. }
  20.  
  21. #[derive(Debug)]
  22. struct Location {
  23.     latitude: f64,
  24.     longitude: f64,
  25. }
  26.  
  27. #[derive(Debug)]
  28. struct Color {
  29.     red: u8,
  30.     green: u8,
  31.     blue: u8,
  32. }
  33.  
  34. impl<'de> Deserialize<'de> for Location {
  35.     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
  36.     where
  37.         D: Deserializer<'de>,
  38.    {
  39.        enum Field {
  40.            Latitude,
  41.            Longitude,
  42.        };
  43.  
  44.        impl<'de> Deserialize<'de> for Field {
  45.            fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
  46.            where
  47.                D: Deserializer<'de>,
  48.             {
  49.                 struct FieldVisitor;
  50.  
  51.                 impl<'de> Visitor<'de> for FieldVisitor {
  52.                     type Value = Field;
  53.  
  54.                     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
  55.                         formatter.write_str("`latitude` or `longitude`")
  56.                     }
  57.  
  58.                     fn visit_str<E>(self, value: &str) -> Result<Field, E>
  59.                     where
  60.                         E: de::Error,
  61.                     {
  62.                         match value {
  63.                             "latitude" | "lat" => Ok(Field::Latitude),
  64.                             "longitude" | "lng" => Ok(Field::Longitude),
  65.                             _ => Err(de::Error::unknown_field(value, FIELDS)),
  66.                         }
  67.                     }
  68.                 }
  69.  
  70.                 deserializer.deserialize_identifier(FieldVisitor)
  71.             }
  72.         }
  73.  
  74.         struct LocationVisitor;
  75.  
  76.         impl<'de> Visitor<'de> for LocationVisitor {
  77.             type Value = Location;
  78.  
  79.             fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
  80.                 formatter.write_str(
  81.                     "a tuple of 2 values or a struct with fields 'latitude' and 'longitude'",
  82.                 )
  83.             }
  84.  
  85.             fn visit_seq<V>(self, mut seq: V) -> Result<Location, V::Error>
  86.             where
  87.                 V: SeqAccess<'de>,
  88.            {
  89.                let latitude = seq
  90.                    .next_element()?
  91.                    .ok_or_else(|| de::Error::invalid_length(0, &self))?;
  92.                let longitude = seq
  93.                    .next_element()?
  94.                    .ok_or_else(|| de::Error::invalid_length(1, &self))?;
  95.  
  96.                Ok(Location {
  97.                    latitude,
  98.                    longitude,
  99.                })
  100.            }
  101.  
  102.            fn visit_map<V>(self, mut map: V) -> Result<Location, V::Error>
  103.            where
  104.                V: MapAccess<'de>,
  105.             {
  106.                 let mut latitude = None;
  107.                 let mut longitude = None;
  108.  
  109.                 while let Some(key) = map.next_key()? {
  110.                     match key {
  111.                         Field::Latitude => {
  112.                             if latitude.is_some() {
  113.                                 return Err(de::Error::duplicate_field("latitude"));
  114.                             }
  115.                             latitude = Some(map.next_value()?);
  116.                         }
  117.                         Field::Longitude => {
  118.                             if longitude.is_some() {
  119.                                 return Err(de::Error::duplicate_field("longitude"));
  120.                             }
  121.                             longitude = Some(map.next_value()?);
  122.                         }
  123.                     }
  124.                 }
  125.  
  126.                 let latitude = latitude.ok_or_else(|| de::Error::missing_field("latitude"))?;
  127.                 let longitude = longitude.ok_or_else(|| de::Error::missing_field("longitude"))?;
  128.                 Ok(Location {
  129.                     latitude,
  130.                     longitude,
  131.                 })
  132.             }
  133.         }
  134.  
  135.         const FIELDS: &[&str] = &["latitude", "longitude"];
  136.         deserializer.deserialize_struct("Location", FIELDS, LocationVisitor)
  137.     }
  138. }
  139.  
  140. impl Serialize for Location {
  141.     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
  142.     where
  143.         S: Serializer,
  144.     {
  145.         let mut seq = serializer.serialize_seq(Some(2))?;
  146.         seq.serialize_element(&self.latitude)?;
  147.         seq.serialize_element(&self.longitude)?;
  148.         seq.end()
  149.     }
  150. }
  151.  
  152. impl std::str::FromStr for Color {
  153.     type Err = ();
  154.  
  155.     fn from_str(hex_value: &str) -> Result<Self, Self::Err> {
  156.         let (red, green, blue) = match hex_value.len() {
  157.             6 => (
  158.                 u8::from_str_radix(&hex_value[..2], 16).map_err(|_| ()),
  159.                 u8::from_str_radix(&hex_value[2..4], 16).map_err(|_| ()),
  160.                 u8::from_str_radix(&hex_value[4..], 16).map_err(|_| ()),
  161.             ),
  162.             3 => (
  163.                 u8::from_str_radix(&hex_value[..1], 16)
  164.                     .map(|v| (v << 4) + v)
  165.                     .map_err(|_| ()),
  166.                 u8::from_str_radix(&hex_value[1..2], 16)
  167.                     .map(|v| (v << 4) + v)
  168.                     .map_err(|_| ()),
  169.                 u8::from_str_radix(&hex_value[2..], 16)
  170.                     .map(|v| (v << 4) + v)
  171.                     .map_err(|_| ()),
  172.             ),
  173.             _ => return Err(()),
  174.         };
  175.  
  176.         Ok(Self {
  177.             red: red?,
  178.             green: green?,
  179.             blue: blue?,
  180.         })
  181.     }
  182. }
  183.  
  184. impl<'de> Deserialize<'de> for Color {
  185.     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
  186.     where
  187.         D: Deserializer<'de>,
  188.    {
  189.        enum Field {
  190.            Red,
  191.            Green,
  192.            Blue,
  193.        };
  194.  
  195.        impl<'de> Deserialize<'de> for Field {
  196.            fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
  197.            where
  198.                D: Deserializer<'de>,
  199.             {
  200.                 struct FieldVisitor;
  201.  
  202.                 impl<'de> Visitor<'de> for FieldVisitor {
  203.                     type Value = Field;
  204.  
  205.                     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
  206.                         formatter.write_str("`red`, `green` or `blue`")
  207.                     }
  208.  
  209.                     fn visit_str<E>(self, value: &str) -> Result<Field, E>
  210.                     where
  211.                         E: de::Error,
  212.                     {
  213.                         match value {
  214.                             "red" | "r" => Ok(Field::Red),
  215.                             "green" | "g" => Ok(Field::Green),
  216.                             "blue" | "b" => Ok(Field::Blue),
  217.                             _ => Err(de::Error::unknown_field(value, FIELDS)),
  218.                         }
  219.                     }
  220.                 }
  221.  
  222.                 deserializer.deserialize_identifier(FieldVisitor)
  223.             }
  224.         }
  225.  
  226.         struct ColorVisitor;
  227.  
  228.         impl<'de> Visitor<'de> for ColorVisitor {
  229.             type Value = Color;
  230.  
  231.             fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
  232.                 formatter.write_str("a hexadecimal string, a tuple of 3 values or a struct with fields 'red', 'green' and 'blue'")
  233.             }
  234.  
  235.             fn visit_str<E>(self, mut value: &str) -> Result<Color, E>
  236.             where
  237.                 E: de::Error,
  238.             {
  239.                 if value.starts_with('#') {
  240.                     value = &value[1..];
  241.                 }
  242.  
  243.                 value.parse().map_err(|_| {
  244.                     de::Error::custom("invalid format, expected (?:[0-9a-fA-F]{3}){1,2}")
  245.                 })
  246.             }
  247.  
  248.             fn visit_seq<V>(self, mut seq: V) -> Result<Color, V::Error>
  249.             where
  250.                 V: SeqAccess<'de>,
  251.            {
  252.                let red = seq
  253.                    .next_element()?
  254.                    .ok_or_else(|| de::Error::invalid_length(0, &self))?;
  255.                let green = seq
  256.                    .next_element()?
  257.                    .ok_or_else(|| de::Error::invalid_length(1, &self))?;
  258.                let blue = seq
  259.                    .next_element()?
  260.                    .ok_or_else(|| de::Error::invalid_length(2, &self))?;
  261.  
  262.                Ok(Color { red, green, blue })
  263.            }
  264.  
  265.            fn visit_map<V>(self, mut map: V) -> Result<Color, V::Error>
  266.            where
  267.                V: MapAccess<'de>,
  268.             {
  269.                 let mut red = None;
  270.                 let mut green = None;
  271.                 let mut blue = None;
  272.  
  273.                 while let Some(key) = map.next_key()? {
  274.                     match key {
  275.                         Field::Red => {
  276.                             if red.is_some() {
  277.                                 return Err(de::Error::duplicate_field("red"));
  278.                             }
  279.                             red = Some(map.next_value()?);
  280.                         }
  281.                         Field::Green => {
  282.                             if green.is_some() {
  283.                                 return Err(de::Error::duplicate_field("green"));
  284.                             }
  285.                             green = Some(map.next_value()?);
  286.                         }
  287.                         Field::Blue => {
  288.                             if blue.is_some() {
  289.                                 return Err(de::Error::duplicate_field("blue"));
  290.                             }
  291.                             blue = Some(map.next_value()?);
  292.                         }
  293.                     }
  294.                 }
  295.  
  296.                 let red = red.ok_or_else(|| de::Error::missing_field("red"))?;
  297.                 let green = green.ok_or_else(|| de::Error::missing_field("green"))?;
  298.                 let blue = blue.ok_or_else(|| de::Error::missing_field("blue"))?;
  299.                 Ok(Color { red, green, blue })
  300.             }
  301.         }
  302.  
  303.         const FIELDS: &[&str] = &["red", "green", "blue"];
  304.         deserializer.deserialize_any(ColorVisitor)
  305.     }
  306. }
  307.  
  308. impl Serialize for Color {
  309.     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
  310.     where
  311.         S: Serializer,
  312.     {
  313.         // use serde::ser::SerializeMap;
  314.  
  315.         // let mut map = serializer.serialize_map(Some(3))?;
  316.         // map.serialize_entry("r", &self.red)?;
  317.         // map.serialize_entry("g", &self.green)?;
  318.         // map.serialize_entry("b", &self.blue)?;
  319.         // map.end()
  320.  
  321.         serializer.serialize_str(&format!("rgb({}, {}, {})", self.red, self.green, self.blue))
  322.     }
  323. }
  324.  
  325. fn deserialize_seq_to_max<'de, T, D>(deserializer: D) -> Result<T, D::Error>
  326. where
  327.    T: Deserialize<'de> + Ord,
  328.     D: Deserializer<'de>,
  329. {
  330.    struct MaxVisitor<T>(PhantomData<fn() -> T>);
  331.  
  332.    impl<'de, T> Visitor<'de> for MaxVisitor<T>
  333.    where
  334.        T: Deserialize<'de> + Ord,
  335.     {
  336.         type Value = T;
  337.  
  338.         fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
  339.             formatter.write_str(
  340.                 "either a non-empty sequence or a non-empty associative array (keys are ignored)",
  341.             )
  342.         }
  343.  
  344.         fn visit_seq<S>(self, mut seq: S) -> Result<T, S::Error>
  345.         where
  346.             S: SeqAccess<'de>,
  347.        {
  348.            let mut max = seq
  349.                .next_element()?
  350.                .ok_or_else(|| de::Error::custom("the sequence is empty"))?;
  351.  
  352.            while let Some(value) = seq.next_element()? {
  353.                max = cmp::max(max, value);
  354.            }
  355.  
  356.            Ok(max)
  357.        }
  358.  
  359.        fn visit_map<M>(self, mut map: M) -> Result<T, M::Error>
  360.        where
  361.            M: MapAccess<'de>,
  362.         {
  363.             let mut max;
  364.             if map.next_key::<&'de str>()?.is_some() {
  365.                max = map.next_value()?;
  366.            } else {
  367.                return Err(de::Error::custom("the associative array is empty"));
  368.            }
  369.  
  370.            while let Some(_) = map.next_key::<&'de str>()? {
  371.                 max = cmp::max(max, map.next_value()?);
  372.             }
  373.  
  374.             Ok(max)
  375.         }
  376.     }
  377.  
  378.     deserializer.deserialize_any(MaxVisitor(PhantomData))
  379. }
  380.  
  381. fn main() -> Result<(), Box<dyn Error>> {
  382.     let json = [
  383.         r##"{
  384.    "name": "London",
  385.    "location": [51.509865, -0.118092],
  386.    "color": "#ffffff",
  387.    "temperature": {
  388.        "2020-02-15": 13,
  389.        "2020-02-16": 14,
  390.        "2020-02-17": 10
  391.    }
  392. }"##,
  393.         r##"{
  394.    "name": "Tokyo",
  395.    "location": {
  396.        "latitude": 35.652832,
  397.        "lng": 139.839478
  398.    },
  399.    "color": "#a00",
  400.    "temperature": [17, 15, 17]
  401. }"##,
  402.         r#"{
  403.    "name": "Moscow",
  404.    "location": {
  405.        "latitude": 55.751244,
  406.        "longitude": 37.618423
  407.    },
  408.    "color": [100, 100, 100],
  409.    "temperature": [1, 1, 5]
  410. }"#,
  411.         r#"{
  412.    "name": "Paris",
  413.    "location": {
  414.        "lat": 48.864716,
  415.        "lng": 2.349014
  416.    },
  417.    "color": {
  418.        "red": 40,
  419.        "green": 160,
  420.        "blue": 0
  421.    },
  422.    "temperature": [15, 17, 11]
  423. }"#,
  424.     ];
  425.     println!("Source JSON: [{}]", json.join(",\n"));
  426.  
  427.     let cities: Vec<_> = json
  428.         .iter()
  429.         .filter_map(|json| {
  430.             // use std::time::Instant;
  431.  
  432.             // let now = Instant::now();
  433.             // serde_json::from_str(json)
  434.             //     .map(|v: City| (v, Instant::now() - now))
  435.             //     .ok()
  436.             serde_json::from_str::<City>(json).ok()
  437.         })
  438.         .collect();
  439.  
  440.     println!("\nDeserialized: {:#?}", cities);
  441.  
  442.     let serialized: Vec<_> = cities
  443.         .iter()
  444.         .filter_map(|city| {
  445.             // use std::time::Instant;
  446.  
  447.             // let now = Instant::now();
  448.             // serde_json::to_string_pretty(&city)
  449.             //     .map(|v| format!("({}, {:#?})", v, Instant::now() - now))
  450.             //     .ok()
  451.  
  452.             serde_json::to_string_pretty(&city).ok()
  453.         })
  454.         .collect();
  455.  
  456.     println!("\nSerialized: [{}]", serialized.join(",\n"));
  457.     Ok(())
  458. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×