serde_mappable_seq/
hashmap.rs

1//! Functions for (de)serializing to and from BTreeMaps.
2//!
3//! See the crate-level documentation for more information.
4
5use std::{
6    collections::HashMap,
7    hash::Hash,
8};
9use serde::{
10    de::{Deserialize, Deserializer},
11    ser::{Serialize, Serializer},
12};
13use super::Key;
14
15/// Serialize a HashMap.
16///
17/// See the crate-level documentation for more information.
18pub fn serialize<'a, S: Serializer, T: Serialize, U: Eq + Hash>(
19    map: &HashMap<U, T>,
20    serializer: S,
21) -> Result<S::Ok, S::Error> {
22    serializer.collect_seq(map.values())
23}
24
25/// Deserialize a HashMap.
26///
27/// See the crate-level documentation for more information.
28pub fn deserialize<'a, D, T, U>(
29    deserializer: D,
30) -> Result<HashMap<U, T>, D::Error>
31    where D: Deserializer<'a>,
32          T: Key<'a, U> + Deserialize<'a>,
33          U: Deserialize<'a> + Eq + Hash + Serialize {
34    let items = Vec::<T>::deserialize(deserializer)?;
35    let mut map = HashMap::with_capacity(items.len());
36
37    for item in items {
38        map.insert(item.key(), item);
39    }
40
41    Ok(map)
42}
43
44#[cfg(test)]
45mod tests {
46    use serde_derive::{Deserialize, Serialize};
47    use serde_test::Token;
48    use std::collections::HashMap;
49    use super::Key;
50
51    #[derive(Debug, Deserialize, Eq, PartialEq, Serialize)]
52    struct Item {
53        id: u8,
54        name: String,
55    }
56
57    impl Key<'_, u8> for Item {
58        fn key(&self) -> u8 {
59            self.id
60        }
61    }
62
63    #[derive(Debug, Deserialize, Eq, PartialEq, Serialize)]
64    struct Items {
65        #[serde(with = "crate")]
66        items: HashMap<u8, Item>,
67    }
68
69    #[test]
70    fn test_de() {
71        let mut item_map = HashMap::new();
72        item_map.insert(1, Item {
73            id: 1,
74            name: "foo".to_owned(),
75        });
76
77        let items = Items {
78            items: item_map,
79        };
80
81        serde_test::assert_tokens(&items, &[
82            Token::Struct { name: "Items", len: 1 },
83            Token::Str("items"),
84            Token::Seq { len: Some(1) },
85            Token::Struct { name: "Item", len: 2 },
86            Token::Str("id"),
87            Token::U8(1),
88            Token::Str("name"),
89            Token::Str("foo"),
90            Token::StructEnd,
91            Token::SeqEnd,
92            Token::StructEnd,
93        ]);
94    }
95}