multimap/
serde.rs

1// Copyright (c) 2016 multimap developers
2//
3// Licensed under the Apache License, Version 2.0
4// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0> or the MIT
5// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. All files in the project carrying such notice may not be copied,
7// modified, or distributed except according to those terms.
8
9//! Serde trait implementations for MultiMap
10
11extern crate serde;
12
13use std::fmt;
14use std::hash::{BuildHasher, Hash};
15use std::marker::PhantomData;
16
17use self::serde::de::{MapAccess, Visitor};
18use self::serde::{Deserialize, Deserializer, Serialize, Serializer};
19
20use MultiMap;
21
22impl<K, V, BS> Serialize for MultiMap<K, V, BS>
23where
24    K: Serialize + Eq + Hash,
25    V: Serialize,
26    BS: BuildHasher,
27{
28    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
29    where
30        S: Serializer,
31    {
32        self.inner.serialize(serializer)
33    }
34}
35
36impl<K, V, S> MultiMapVisitor<K, V, S>
37where
38    K: Hash + Eq,
39{
40    fn new() -> Self {
41        MultiMapVisitor {
42            marker: PhantomData,
43        }
44    }
45}
46
47struct MultiMapVisitor<K, V, S> {
48    marker: PhantomData<MultiMap<K, V, S>>,
49}
50
51impl<'a, K, V, S> Visitor<'a> for MultiMapVisitor<K, V, S>
52where
53    K: Deserialize<'a> + Eq + Hash,
54    V: Deserialize<'a>,
55    S: BuildHasher + Default,
56{
57    type Value = MultiMap<K, V, S>;
58
59    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
60        formatter.write_str("expected a map")
61    }
62
63    fn visit_map<M>(self, mut visitor: M) -> Result<Self::Value, M::Error>
64    where
65        M: MapAccess<'a>,
66    {
67        let mut values =
68            MultiMap::with_capacity_and_hasher(visitor.size_hint().unwrap_or(0), S::default());
69
70        while let Some((key, value)) = visitor.next_entry()? {
71            values.inner.insert(key, value);
72        }
73
74        Ok(values)
75    }
76}
77
78impl<'a, K, V, S> Deserialize<'a> for MultiMap<K, V, S>
79where
80    K: Deserialize<'a> + Eq + Hash,
81    V: Deserialize<'a>,
82    S: BuildHasher + Default,
83{
84    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
85    where
86        D: Deserializer<'a>,
87    {
88        deserializer.deserialize_map(MultiMapVisitor::<K, V, S>::new())
89    }
90}
91
92#[cfg(test)]
93mod tests {
94
95    extern crate serde_test;
96
97    use self::serde_test::{assert_tokens, Token};
98
99    use super::*;
100
101    #[test]
102    fn test_empty() {
103        let map = MultiMap::<char, u8>::new();
104
105        assert_tokens(&map, &[Token::Map { len: Some(0) }, Token::MapEnd]);
106    }
107
108    #[test]
109    fn test_single() {
110        let mut map = MultiMap::<char, u8>::new();
111        map.insert('x', 1);
112
113        assert_tokens(
114            &map,
115            &[
116                Token::Map { len: Some(1) },
117                Token::Char('x'),
118                Token::Seq { len: Some(1) },
119                Token::U8(1),
120                Token::SeqEnd,
121                Token::MapEnd,
122            ],
123        );
124    }
125
126    #[test]
127    fn test_multiple() {
128        let mut map = MultiMap::<char, u8>::new();
129        map.insert('x', 1);
130        map.insert('x', 3);
131        map.insert('x', 1);
132        map.insert('x', 5);
133
134        assert_tokens(
135            &map,
136            &[
137                Token::Map { len: Some(1) },
138                Token::Char('x'),
139                Token::Seq { len: Some(4) },
140                Token::U8(1),
141                Token::U8(3),
142                Token::U8(1),
143                Token::U8(5),
144                Token::SeqEnd,
145                Token::MapEnd,
146            ],
147        );
148    }
149}