Advertisement
Savior

Serde: deserialize into a Vec of Rc<RefCell<_>>

Feb 16th, 2020
815
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 6.26 KB | None | 0 0
  1. use std::cell::RefCell;
  2. use std::rc::Rc;
  3.  
  4. use serde::de::{self, MapAccess, SeqAccess, Visitor};
  5. use serde::{Deserialize, Deserializer, Serialize};
  6.  
  7. #[derive(Debug, Serialize)]
  8. struct Response<'a> {
  9.    categories: Vec<Category<'a>>,
  10. }
  11.  
  12. type RefItem<'a> = Rc<RefCell<Item<'a>>>;
  13.  
  14. #[derive(Debug, Serialize)]
  15. struct Category<'a> {
  16.    id: &'a str,
  17.     name: &'a str,
  18.    items: Vec<RefItem<'a>>,
  19. }
  20.  
  21. #[derive(Debug, Deserialize, Serialize)]
  22. struct Item<'a> {
  23.    id: &'a str,
  24.     name: &'a str,
  25. }
  26.  
  27. impl<'de> Deserialize<'de> for Response<'de> {
  28.     fn deserialize<D>(deserializer: D) -> Result<Response<'de>, D::Error>
  29.    where
  30.        D: Deserializer<'de>,
  31.     {
  32.         use std::collections::BTreeMap as Map;
  33.  
  34.         #[derive(Deserialize)]
  35.         #[serde(field_identifier, rename_all = "lowercase")]
  36.         enum Field {
  37.             Categories,
  38.             Items,
  39.         };
  40.  
  41.         #[derive(Debug, Deserialize)]
  42.         struct RawCategory<'a> {
  43.            id: &'a str,
  44.             name: &'a str,
  45.            item_ids: Vec<&'a str>,
  46.         }
  47.  
  48.         // struct ItemsMap<'a>(Vec<RefItem<'a>>);
  49.         struct ItemsMap<'a>(Map<&'a str, RefItem<'a>>);
  50.  
  51.        impl<'de> Deserialize<'de> for ItemsMap<'de> {
  52.             fn deserialize<D>(deserializer: D) -> Result<ItemsMap<'de>, D::Error>
  53.            where
  54.                D: Deserializer<'de>,
  55.             {
  56.                 struct ItemsMapVisitor;
  57.  
  58.                 impl<'de> Visitor<'de> for ItemsMapVisitor {
  59.                     type Value = ItemsMap<'de>;
  60.  
  61.                    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
  62.                        formatter.write_str("struct Item")
  63.                    }
  64.  
  65.                    fn visit_seq<V>(self, mut seq: V) -> Result<ItemsMap<'de>, V::Error>
  66.                     where
  67.                         V: SeqAccess<'de>,
  68.                    {
  69.                        let mut map = Map::new();
  70.                        while let Some(item) = seq.next_element::<Item<'de>>()? {
  71.                             map.insert(item.id, Rc::new(RefCell::new(item)));
  72.                         }
  73.  
  74.                         Ok(ItemsMap(map))
  75.  
  76.                         // let mut vec = Vec::new();
  77.                         // while let Some(item) = seq.next_element::<Item<'de>>()? {
  78.                         //     vec.push(Rc::new(RefCell::new(item)));
  79.                         // }
  80.  
  81.                         // Ok(ItemsMap(vec))
  82.                     }
  83.                 }
  84.  
  85.                 deserializer.deserialize_seq(ItemsMapVisitor)
  86.             }
  87.         }
  88.  
  89.         struct ResponseVisitor;
  90.  
  91.         impl<'de> Visitor<'de> for ResponseVisitor {
  92.             type Value = Response<'de>;
  93.  
  94.            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
  95.                formatter.write_str("struct Response")
  96.            }
  97.  
  98.            fn visit_map<V>(self, mut map: V) -> Result<Response<'de>, V::Error>
  99.             where
  100.                 V: MapAccess<'de>,
  101.            {
  102.                let mut raw_categories: Option<Vec<RawCategory<'de>>> = None;
  103.                 let mut items_map: Option<ItemsMap<'de>> = None;
  104.  
  105.                while let Some(key) = map.next_key()? {
  106.                    match key {
  107.                        Field::Categories => {
  108.                            if raw_categories.is_some() {
  109.                                return Err(de::Error::duplicate_field("categories"));
  110.                            }
  111.                            raw_categories = Some(map.next_value()?);
  112.                        }
  113.                        Field::Items => {
  114.                            if items_map.is_some() {
  115.                                return Err(de::Error::duplicate_field("items"));
  116.                            }
  117.                            items_map = Some(map.next_value()?);
  118.                        }
  119.                    }
  120.                }
  121.                let raw_categories =
  122.                    raw_categories.ok_or_else(|| de::Error::missing_field("categories"))?;
  123.                let items_map = items_map.ok_or_else(|| de::Error::missing_field("items"))?;
  124.  
  125.                let categories: Vec<_> = raw_categories
  126.                    .iter()
  127.                    .map(|category| {
  128.                        let items: Vec<_> = category
  129.                            .item_ids
  130.                            .iter()
  131.                            .map(|id| {
  132.                                items_map
  133.                                    .0
  134.                                    .get(id)
  135.                                    .map(|rc| rc.clone())
  136.                                    .ok_or_else(|| de::Error::custom("can't find item"))
  137.                            })
  138.                            // .map(|id| {
  139.                            //     items_map
  140.                            //         .0
  141.                            //         .iter()
  142.                            //         .find(|item| &item.borrow().id == id)
  143.                            //         .map(|rc| rc.clone())
  144.                            //         .ok_or_else(|| de::Error::custom("can't find item"))
  145.                            // })
  146.                            .collect::<Result<Vec<_>, _>>()?;
  147.  
  148.                        Ok(Category {
  149.                            id: category.id,
  150.                            name: category.name,
  151.                            items,
  152.                        })
  153.                    })
  154.                    .collect::<Result<Vec<_>, _>>()?;
  155.  
  156.                Ok(Response { categories })
  157.            }
  158.        }
  159.  
  160.        deserializer.deserialize_struct("Response", &["categories", "items"], ResponseVisitor)
  161.    }
  162. }
  163.  
  164. fn main() {
  165.    let json = r##"{
  166.    "items": [{
  167.        "id": "1",
  168.        "name": "1"
  169.    }, {
  170.        "id": "2",
  171.        "name": "2"
  172.    }, {
  173.        "id": "3",
  174.        "name": "3"
  175.    }],
  176.    "categories": [{
  177.        "id": "1",
  178.        "name": "1",
  179.        "item_ids": []
  180.    }, {
  181.        "id": "2",
  182.        "name": "2",
  183.        "item_ids": ["1", "2"]
  184.    }, {
  185.        "id": "3",
  186.        "name": "3",
  187.        "item_ids": ["2", "3"]
  188.    }]
  189. }"##;
  190.    
  191.    let deserialized: Response = serde_json::from_str(&json).unwrap();
  192.    println!("{:#?}", deserialized);
  193. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement