diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 2d28af46..615654c4 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -1,5 +1,17 @@ use std::borrow::Cow; -use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; +use std::collections::{ + BinaryHeap, + BTreeMap, + BTreeSet, + LinkedList, + HashMap, + HashSet, + VecDeque, +}; +#[cfg(feature = "nightly")] +use collections::enum_set::{CLike, EnumSet}; +#[cfg(feature = "nightly")] +use collections::vec_map::VecMap; use std::hash::Hash; use std::marker::PhantomData; use std::path; @@ -289,159 +301,131 @@ impl Deserialize for Option where T: Deserialize { /////////////////////////////////////////////////////////////////////////////// -pub struct BTreeSetVisitor { - marker: PhantomData, -} +macro_rules! set_impl { + ( + $ty:ty, + < $($constraints:ident),* >, + $visitor_name:ident, + $visitor:ident, + $ctor:expr, + $with_capacity:expr, + $insert:expr + ) => { + pub struct $visitor_name { + marker: PhantomData, + } -impl BTreeSetVisitor { - pub fn new() -> Self { - BTreeSetVisitor { - marker: PhantomData, + impl $visitor_name { + pub fn new() -> Self { + $visitor_name { + marker: PhantomData, + } + } + } + + impl Visitor for $visitor_name + where T: $($constraints +)*, + { + type Value = $ty; + + #[inline] + fn visit_unit(&mut self) -> Result<$ty, E> + where E: Error, + { + Ok($ctor) + } + + #[inline] + fn visit_seq(&mut self, mut $visitor: V) -> Result<$ty, V::Error> + where V: SeqVisitor, + { + let mut values = $with_capacity; + + while let Some(value) = try!($visitor.visit()) { + $insert(&mut values, value); + } + + try!($visitor.end()); + + Ok(values) + } + } + + impl Deserialize for $ty + where T: $($constraints +)*, + { + fn deserialize(deserializer: &mut D) -> Result<$ty, D::Error> + where D: Deserializer, + { + deserializer.visit($visitor_name::new()) + } } } } -impl Visitor for BTreeSetVisitor - where T: Deserialize + Eq + Ord, -{ - type Value = BTreeSet; +set_impl!( + BinaryHeap, + , + BinaryHeapVisitor, + visitor, + BinaryHeap::new(), + BinaryHeap::with_capacity(visitor.size_hint().0), + BinaryHeap::push); - #[inline] - fn visit_unit(&mut self) -> Result, E> - where E: Error, - { - Ok(BTreeSet::new()) - } +set_impl!( + BTreeSet, + , + BTreeSetVisitor, + visitor, + BTreeSet::new(), + BTreeSet::new(), + BTreeSet::insert); - #[inline] - fn visit_seq(&mut self, mut visitor: V) -> Result, V::Error> - where V: SeqVisitor, - { - let mut values = BTreeSet::new(); +#[cfg(feature = "nightly")] +set_impl!( + EnumSet, + , + EnumSetVisitor, + visitor, + EnumSet::new(), + EnumSet::new(), + EnumSet::insert); - while let Some(value) = try!(visitor.visit()) { - values.insert(value); - } +set_impl!( + LinkedList, + , + LinkedListVisitor, + visitor, + LinkedList::new(), + LinkedList::new(), + LinkedList::push_back); - try!(visitor.end()); +set_impl!( + HashSet, + , + HashSetVisitor, + visitor, + HashSet::new(), + HashSet::with_capacity(visitor.size_hint().0), + HashSet::insert); - Ok(values) - } -} +set_impl!( + Vec, + , + VecVisitor, + visitor, + Vec::new(), + Vec::with_capacity(visitor.size_hint().0), + Vec::push); -impl Deserialize for BTreeSet - where T: Deserialize + Eq + Ord, -{ - fn deserialize(deserializer: &mut D) -> Result, D::Error> - where D: Deserializer, - { - deserializer.visit(BTreeSetVisitor::new()) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -pub struct HashSetVisitor { - marker: PhantomData, -} - -impl HashSetVisitor { - pub fn new() -> Self { - HashSetVisitor { - marker: PhantomData, - } - } -} - -impl Visitor for HashSetVisitor - where T: Deserialize + Eq + Hash, -{ - type Value = HashSet; - - #[inline] - fn visit_unit(&mut self) -> Result, E> - where E: Error, - { - Ok(HashSet::new()) - } - - #[inline] - fn visit_seq(&mut self, mut visitor: V) -> Result, V::Error> - where V: SeqVisitor, - { - let (len, _) = visitor.size_hint(); - let mut values = HashSet::with_capacity(len); - - while let Some(value) = try!(visitor.visit()) { - values.insert(value); - } - - try!(visitor.end()); - - Ok(values) - } -} - -impl Deserialize for HashSet - where T: Deserialize + Eq + Hash, -{ - fn deserialize(deserializer: &mut D) -> Result, D::Error> - where D: Deserializer, - { - deserializer.visit(HashSetVisitor::new()) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -pub struct VecVisitor { - marker: PhantomData, -} - -impl VecVisitor { - pub fn new() -> Self { - VecVisitor { - marker: PhantomData, - } - } -} - -impl Visitor for VecVisitor where T: Deserialize { - type Value = Vec; - - #[inline] - fn visit_unit(&mut self) -> Result, E> - where E: Error, - { - Ok(Vec::new()) - } - - #[inline] - fn visit_seq(&mut self, mut visitor: V) -> Result, V::Error> - where V: SeqVisitor, - { - let (len, _) = visitor.size_hint(); - let mut values = Vec::with_capacity(len); - - while let Some(value) = try!(visitor.visit()) { - values.push(value); - } - - try!(visitor.end()); - - Ok(values) - } -} - -impl Deserialize for Vec - where T: Deserialize, -{ - fn deserialize(deserializer: &mut D) -> Result, D::Error> - where D: Deserializer, - { - deserializer.visit_seq(VecVisitor::new()) - } -} +set_impl!( + VecDeque, + , + VecDequeVisitor, + visitor, + VecDeque::new(), + VecDeque::with_capacity(visitor.size_hint().0), + VecDeque::push_back); /////////////////////////////////////////////////////////////////////////////// @@ -641,123 +625,96 @@ tuple_impls! { /////////////////////////////////////////////////////////////////////////////// -pub struct BTreeMapVisitor { - marker: PhantomData>, -} +macro_rules! map_impl { + ( + $ty:ty, + < $($constraints:ident),* >, + $visitor_name:ident, + $visitor:ident, + $ctor:expr, + $with_capacity:expr, + $insert:expr + ) => { + pub struct $visitor_name { + marker: PhantomData<$ty>, + } -impl BTreeMapVisitor { - #[inline] - pub fn new() -> Self { - BTreeMapVisitor { - marker: PhantomData, + impl $visitor_name { + pub fn new() -> Self { + $visitor_name { + marker: PhantomData, + } + } + } + + impl Visitor for $visitor_name + where K: $($constraints +)*, + V: Deserialize, + { + type Value = $ty; + + #[inline] + fn visit_unit(&mut self) -> Result<$ty, E> + where E: Error, + { + Ok($ctor) + } + + #[inline] + fn visit_map(&mut self, mut $visitor: Visitor) -> Result<$ty, Visitor::Error> + where Visitor: MapVisitor, + { + let mut values = $with_capacity; + + while let Some((key, value)) = try!($visitor.visit()) { + $insert(&mut values, key, value); + } + + try!($visitor.end()); + + Ok(values) + } + } + + impl Deserialize for $ty + where K: $($constraints +)*, + V: Deserialize, + { + fn deserialize(deserializer: &mut D) -> Result<$ty, D::Error> + where D: Deserializer, + { + deserializer.visit($visitor_name::new()) + } } } } -impl Visitor for BTreeMapVisitor - where K: Deserialize + Ord, - V: Deserialize -{ - type Value = BTreeMap; +map_impl!( + BTreeMap, + , + BTreeMapVisitor, + visitor, + BTreeMap::new(), + BTreeMap::new(), + BTreeMap::insert); - #[inline] - fn visit_unit(&mut self) -> Result, E> - where E: Error, - { - Ok(BTreeMap::new()) - } - - #[inline] - fn visit_map(&mut self, mut visitor: Visitor) -> Result, Visitor::Error> - where Visitor: MapVisitor, - { - let mut values = BTreeMap::new(); - - while let Some((key, value)) = try!(visitor.visit()) { - values.insert(key, value); - } - - try!(visitor.end()); - - Ok(values) - } -} - -impl Deserialize for BTreeMap - where K: Deserialize + Eq + Ord, - V: Deserialize, -{ - fn deserialize(deserializer: &mut D) -> Result, D::Error> - where D: Deserializer, - { - deserializer.visit(BTreeMapVisitor::new()) - } -} +map_impl!( + HashMap, + , + HashMapVisitor, + visitor, + HashMap::new(), + HashMap::with_capacity(visitor.size_hint().0), + HashMap::insert); /////////////////////////////////////////////////////////////////////////////// -pub struct HashMapVisitor { - marker: PhantomData>, -} - -impl HashMapVisitor { - #[inline] - pub fn new() -> Self { - HashMapVisitor { - marker: PhantomData, - } - } -} - -impl Visitor for HashMapVisitor - where K: Deserialize + Eq + Hash, - V: Deserialize, -{ - type Value = HashMap; - - #[inline] - fn visit_unit(&mut self) -> Result, E> - where E: Error, - { - Ok(HashMap::new()) - } - - #[inline] - fn visit_map(&mut self, mut visitor: V_) -> Result, V_::Error> - where V_: MapVisitor, - { - let (len, _) = visitor.size_hint(); - let mut values = HashMap::with_capacity(len); - - while let Some((key, value)) = try!(visitor.visit()) { - values.insert(key, value); - } - - try!(visitor.end()); - - Ok(values) - } -} - -impl Deserialize for HashMap - where K: Deserialize + Eq + Hash, - V: Deserialize, -{ - fn deserialize(deserializer: &mut D) -> Result, D::Error> - where D: Deserializer, - { - deserializer.visit(HashMapVisitor::new()) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -// FIXME: `VecMap` is unstable. -/* +#[cfg(feature = "nightly")] pub struct VecMapVisitor { marker: PhantomData>, } +#[cfg(feature = "nightly")] impl VecMapVisitor { #[inline] pub fn new() -> Self { @@ -767,6 +724,7 @@ impl VecMapVisitor { } } +#[cfg(feature = "nightly")] impl Visitor for VecMapVisitor where V: Deserialize, { @@ -796,6 +754,7 @@ impl Visitor for VecMapVisitor } } +#[cfg(feature = "nightly")] impl Deserialize for VecMap where V: Deserialize, { @@ -805,7 +764,6 @@ impl Deserialize for VecMap deserializer.visit(VecMapVisitor::new()) } } -*/ ///////////////////////////////////////////////////////////////////////////////