1extern 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}