De/serialize for HashSet<T, S>

This commit is contained in:
David Tolnay 2016-06-11 09:59:29 -07:00
parent 322d7a90db
commit decc571988
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
5 changed files with 64 additions and 30 deletions

View File

@ -381,29 +381,30 @@ impl<T> Deserialize for PhantomData<T> where T: Deserialize {
macro_rules! seq_impl { macro_rules! seq_impl {
( (
$ty:ty, $ty:ty,
< $($constraints:ident),* >, $visitor_ty:ident < $($typaram:ident : $bound1:ident $(+ $bound2:ident)*),* >,
$visitor_name:ident,
$visitor:ident, $visitor:ident,
$ctor:expr, $ctor:expr,
$with_capacity:expr, $with_capacity:expr,
$insert:expr $insert:expr
) => { ) => {
/// A visitor that produces a sequence. /// A visitor that produces a sequence.
pub struct $visitor_name<T> { pub struct $visitor_ty<$($typaram),*> {
marker: PhantomData<T>, marker: PhantomData<$ty>,
} }
impl<T> $visitor_name<T> { impl<$($typaram),*> $visitor_ty<$($typaram),*>
where $($typaram: $bound1 $(+ $bound2)*),*
{
/// Construct a new sequence visitor. /// Construct a new sequence visitor.
pub fn new() -> Self { pub fn new() -> Self {
$visitor_name { $visitor_ty {
marker: PhantomData, marker: PhantomData,
} }
} }
} }
impl<T> Visitor for $visitor_name<T> impl<$($typaram),*> Visitor for $visitor_ty<$($typaram),*>
where T: $($constraints +)*, where $($typaram: $bound1 $(+ $bound2)*),*
{ {
type Value = $ty; type Value = $ty;
@ -430,13 +431,13 @@ macro_rules! seq_impl {
} }
} }
impl<T> Deserialize for $ty impl<$($typaram),*> Deserialize for $ty
where T: $($constraints +)*, where $($typaram: $bound1 $(+ $bound2)*),*
{ {
fn deserialize<D>(deserializer: &mut D) -> Result<$ty, D::Error> fn deserialize<D>(deserializer: &mut D) -> Result<$ty, D::Error>
where D: Deserializer, where D: Deserializer,
{ {
deserializer.deserialize_seq($visitor_name::new()) deserializer.deserialize_seq($visitor_ty::new())
} }
} }
} }
@ -445,8 +446,7 @@ macro_rules! seq_impl {
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
seq_impl!( seq_impl!(
BinaryHeap<T>, BinaryHeap<T>,
<Deserialize, Ord>, BinaryHeapVisitor<T: Deserialize + Ord>,
BinaryHeapVisitor,
visitor, visitor,
BinaryHeap::new(), BinaryHeap::new(),
BinaryHeap::with_capacity(visitor.size_hint().0), BinaryHeap::with_capacity(visitor.size_hint().0),
@ -455,8 +455,7 @@ seq_impl!(
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
seq_impl!( seq_impl!(
BTreeSet<T>, BTreeSet<T>,
<Deserialize, Eq, Ord>, BTreeSetVisitor<T: Deserialize + Eq + Ord>,
BTreeSetVisitor,
visitor, visitor,
BTreeSet::new(), BTreeSet::new(),
BTreeSet::new(), BTreeSet::new(),
@ -465,8 +464,7 @@ seq_impl!(
#[cfg(all(feature = "nightly", feature = "collections"))] #[cfg(all(feature = "nightly", feature = "collections"))]
seq_impl!( seq_impl!(
EnumSet<T>, EnumSet<T>,
<Deserialize, CLike>, EnumSetVisitor<T: Deserialize + CLike>,
EnumSetVisitor,
visitor, visitor,
EnumSet::new(), EnumSet::new(),
EnumSet::new(), EnumSet::new(),
@ -475,8 +473,7 @@ seq_impl!(
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
seq_impl!( seq_impl!(
LinkedList<T>, LinkedList<T>,
<Deserialize>, LinkedListVisitor<T: Deserialize>,
LinkedListVisitor,
visitor, visitor,
LinkedList::new(), LinkedList::new(),
LinkedList::new(), LinkedList::new(),
@ -484,19 +481,18 @@ seq_impl!(
#[cfg(feature = "std")] #[cfg(feature = "std")]
seq_impl!( seq_impl!(
HashSet<T>, HashSet<T, S>,
<Deserialize, Eq, Hash>, HashSetVisitor<T: Deserialize + Eq + Hash,
HashSetVisitor, S: BuildHasher + Default>,
visitor, visitor,
HashSet::new(), HashSet::with_hasher(S::default()),
HashSet::with_capacity(visitor.size_hint().0), HashSet::with_capacity_and_hasher(visitor.size_hint().0, S::default()),
HashSet::insert); HashSet::insert);
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
seq_impl!( seq_impl!(
Vec<T>, Vec<T>,
<Deserialize>, VecVisitor<T: Deserialize>,
VecVisitor,
visitor, visitor,
Vec::new(), Vec::new(),
Vec::with_capacity(visitor.size_hint().0), Vec::with_capacity(visitor.size_hint().0),
@ -505,8 +501,7 @@ seq_impl!(
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
seq_impl!( seq_impl!(
VecDeque<T>, VecDeque<T>,
<Deserialize>, VecDequeVisitor<T: Deserialize>,
VecDequeVisitor,
visitor, visitor,
VecDeque::new(), VecDeque::new(),
VecDeque::with_capacity(visitor.size_hint().0), VecDeque::with_capacity(visitor.size_hint().0),

View File

@ -330,8 +330,9 @@ impl<T> Serialize for EnumSet<T>
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl<T> Serialize for HashSet<T> impl<T, H> Serialize for HashSet<T, H>
where T: Serialize + Eq + Hash, where T: Serialize + Eq + Hash,
H: BuildHasher,
{ {
#[inline] #[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>

View File

@ -62,6 +62,14 @@ macro_rules! hashset {
$(set.insert($value);)+ $(set.insert($value);)+
set set
} }
};
($hasher:ident @ $($value:expr),+) => {
{
use std::hash::BuildHasherDefault;
let mut set = HashSet::with_hasher(BuildHasherDefault::<$hasher>::default());
$(set.insert($value);)+
set
}
} }
} }

View File

@ -287,6 +287,18 @@ declare_tests! {
Token::TupleStructStart("Anything", Some(0)), Token::TupleStructStart("Anything", Some(0)),
Token::SeqEnd, Token::SeqEnd,
], ],
hashset![FnvHasher @ 1, 2, 3] => vec![
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::I32(1),
Token::SeqSep,
Token::I32(2),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
],
} }
test_vec { test_vec {
Vec::<isize>::new() => vec![ Vec::<isize>::new() => vec![

View File

@ -1,4 +1,4 @@
use std::collections::{BTreeMap, HashMap}; use std::collections::{BTreeMap, HashMap, HashSet};
use std::net; use std::net;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::str; use std::str;
@ -147,6 +147,24 @@ declare_ser_tests! {
Token::SeqEnd, Token::SeqEnd,
], ],
} }
test_hashset {
HashSet::<isize>::new() => &[
Token::SeqStart(Some(0)),
Token::SeqEnd,
],
hashset![1] => &[
Token::SeqStart(Some(1)),
Token::SeqSep,
Token::I32(1),
Token::SeqEnd,
],
hashset![FnvHasher @ 1] => &[
Token::SeqStart(Some(1)),
Token::SeqSep,
Token::I32(1),
Token::SeqEnd,
],
}
test_tuple { test_tuple {
(1,) => &[ (1,) => &[
Token::TupleStart(1), Token::TupleStart(1),