summaryrefslogtreecommitdiff
path: root/vendor/multimap/src/serde.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/multimap/src/serde.rs')
-rw-r--r--vendor/multimap/src/serde.rs149
1 files changed, 149 insertions, 0 deletions
diff --git a/vendor/multimap/src/serde.rs b/vendor/multimap/src/serde.rs
new file mode 100644
index 00000000..51ccae66
--- /dev/null
+++ b/vendor/multimap/src/serde.rs
@@ -0,0 +1,149 @@
+// Copyright (c) 2016 multimap developers
+//
+// Licensed under the Apache License, Version 2.0
+// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0> or the MIT
+// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. All files in the project carrying such notice may not be copied,
+// modified, or distributed except according to those terms.
+
+//! Serde trait implementations for MultiMap
+
+extern crate serde;
+
+use std::fmt;
+use std::hash::{BuildHasher, Hash};
+use std::marker::PhantomData;
+
+use self::serde::de::{MapAccess, Visitor};
+use self::serde::{Deserialize, Deserializer, Serialize, Serializer};
+
+use MultiMap;
+
+impl<K, V, BS> Serialize for MultiMap<K, V, BS>
+where
+ K: Serialize + Eq + Hash,
+ V: Serialize,
+ BS: BuildHasher,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.inner.serialize(serializer)
+ }
+}
+
+impl<K, V, S> MultiMapVisitor<K, V, S>
+where
+ K: Hash + Eq,
+{
+ fn new() -> Self {
+ MultiMapVisitor {
+ marker: PhantomData,
+ }
+ }
+}
+
+struct MultiMapVisitor<K, V, S> {
+ marker: PhantomData<MultiMap<K, V, S>>,
+}
+
+impl<'a, K, V, S> Visitor<'a> for MultiMapVisitor<K, V, S>
+where
+ K: Deserialize<'a> + Eq + Hash,
+ V: Deserialize<'a>,
+ S: BuildHasher + Default,
+{
+ type Value = MultiMap<K, V, S>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("expected a map")
+ }
+
+ fn visit_map<M>(self, mut visitor: M) -> Result<Self::Value, M::Error>
+ where
+ M: MapAccess<'a>,
+ {
+ let mut values =
+ MultiMap::with_capacity_and_hasher(visitor.size_hint().unwrap_or(0), S::default());
+
+ while let Some((key, value)) = visitor.next_entry()? {
+ values.inner.insert(key, value);
+ }
+
+ Ok(values)
+ }
+}
+
+impl<'a, K, V, S> Deserialize<'a> for MultiMap<K, V, S>
+where
+ K: Deserialize<'a> + Eq + Hash,
+ V: Deserialize<'a>,
+ S: BuildHasher + Default,
+{
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'a>,
+ {
+ deserializer.deserialize_map(MultiMapVisitor::<K, V, S>::new())
+ }
+}
+
+#[cfg(test)]
+mod tests {
+
+ extern crate serde_test;
+
+ use self::serde_test::{assert_tokens, Token};
+
+ use super::*;
+
+ #[test]
+ fn test_empty() {
+ let map = MultiMap::<char, u8>::new();
+
+ assert_tokens(&map, &[Token::Map { len: Some(0) }, Token::MapEnd]);
+ }
+
+ #[test]
+ fn test_single() {
+ let mut map = MultiMap::<char, u8>::new();
+ map.insert('x', 1);
+
+ assert_tokens(
+ &map,
+ &[
+ Token::Map { len: Some(1) },
+ Token::Char('x'),
+ Token::Seq { len: Some(1) },
+ Token::U8(1),
+ Token::SeqEnd,
+ Token::MapEnd,
+ ],
+ );
+ }
+
+ #[test]
+ fn test_multiple() {
+ let mut map = MultiMap::<char, u8>::new();
+ map.insert('x', 1);
+ map.insert('x', 3);
+ map.insert('x', 1);
+ map.insert('x', 5);
+
+ assert_tokens(
+ &map,
+ &[
+ Token::Map { len: Some(1) },
+ Token::Char('x'),
+ Token::Seq { len: Some(4) },
+ Token::U8(1),
+ Token::U8(3),
+ Token::U8(1),
+ Token::U8(5),
+ Token::SeqEnd,
+ Token::MapEnd,
+ ],
+ );
+ }
+}