De/serialize for HashMap<K, V, S>
This commit is contained in:
parent
84a573c926
commit
46a1860601
@ -32,7 +32,7 @@ use collections::enum_set::{CLike, EnumSet};
|
|||||||
#[cfg(all(feature = "nightly", feature = "collections"))]
|
#[cfg(all(feature = "nightly", feature = "collections"))]
|
||||||
use collections::borrow::ToOwned;
|
use collections::borrow::ToOwned;
|
||||||
|
|
||||||
use core::hash::Hash;
|
use core::hash::{Hash, BuildHasher};
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::net;
|
use std::net;
|
||||||
@ -726,31 +726,26 @@ tuple_impls! {
|
|||||||
macro_rules! map_impl {
|
macro_rules! map_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
|
|
||||||
) => {
|
) => {
|
||||||
/// A visitor that produces a map.
|
/// A visitor that produces a map.
|
||||||
pub struct $visitor_name<K, V> {
|
pub struct $visitor_ty<$($typaram),*> {
|
||||||
marker: PhantomData<$ty>,
|
marker: PhantomData<$ty>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K, V> $visitor_name<K, V> {
|
impl<$($typaram : $bound1 $(+ $bound2)*),*> $visitor_ty<$($typaram),*> {
|
||||||
/// Construct a `MapVisitor*<T>`.
|
/// Construct a `MapVisitor*<T>`.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
$visitor_name {
|
$visitor_ty {
|
||||||
marker: PhantomData,
|
marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K, V> Visitor for $visitor_name<K, V>
|
impl<$($typaram : $bound1 $(+ $bound2)*),*> Visitor for $visitor_ty<$($typaram),*> {
|
||||||
where K: $($constraints +)*,
|
|
||||||
V: Deserialize,
|
|
||||||
{
|
|
||||||
type Value = $ty;
|
type Value = $ty;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -767,7 +762,7 @@ macro_rules! map_impl {
|
|||||||
let mut values = $with_capacity;
|
let mut values = $with_capacity;
|
||||||
|
|
||||||
while let Some((key, value)) = try!($visitor.visit()) {
|
while let Some((key, value)) = try!($visitor.visit()) {
|
||||||
$insert(&mut values, key, value);
|
values.insert(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
try!($visitor.end());
|
try!($visitor.end());
|
||||||
@ -776,14 +771,11 @@ macro_rules! map_impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K, V> Deserialize for $ty
|
impl<$($typaram : $bound1 $(+ $bound2)*),*> Deserialize for $ty {
|
||||||
where K: $($constraints +)*,
|
|
||||||
V: Deserialize,
|
|
||||||
{
|
|
||||||
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_map($visitor_name::new())
|
deserializer.deserialize_map($visitor_ty::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -792,22 +784,21 @@ macro_rules! map_impl {
|
|||||||
#[cfg(any(feature = "std", feature = "collections"))]
|
#[cfg(any(feature = "std", feature = "collections"))]
|
||||||
map_impl!(
|
map_impl!(
|
||||||
BTreeMap<K, V>,
|
BTreeMap<K, V>,
|
||||||
<Deserialize, Eq, Ord>,
|
BTreeMapVisitor<K: Deserialize + Eq + Ord,
|
||||||
BTreeMapVisitor,
|
V: Deserialize>,
|
||||||
visitor,
|
visitor,
|
||||||
BTreeMap::new(),
|
BTreeMap::new(),
|
||||||
BTreeMap::new(),
|
BTreeMap::new());
|
||||||
BTreeMap::insert);
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
map_impl!(
|
map_impl!(
|
||||||
HashMap<K, V>,
|
HashMap<K, V, S>,
|
||||||
<Deserialize, Eq, Hash>,
|
HashMapVisitor<K: Deserialize + Eq + Hash,
|
||||||
HashMapVisitor,
|
V: Deserialize,
|
||||||
|
S: BuildHasher + Default>,
|
||||||
visitor,
|
visitor,
|
||||||
HashMap::new(),
|
HashMap::with_hasher(S::default()),
|
||||||
HashMap::with_capacity(visitor.size_hint().0),
|
HashMap::with_capacity_and_hasher(visitor.size_hint().0, S::default()));
|
||||||
HashMap::insert);
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ use collections::enum_set::{CLike, EnumSet};
|
|||||||
#[cfg(all(feature = "nightly", feature = "collections"))]
|
#[cfg(all(feature = "nightly", feature = "collections"))]
|
||||||
use collections::borrow::ToOwned;
|
use collections::borrow::ToOwned;
|
||||||
|
|
||||||
use core::hash::Hash;
|
use core::hash::{Hash, BuildHasher};
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
use core::iter;
|
use core::iter;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -651,9 +651,10 @@ impl<K, V> Serialize for BTreeMap<K, V>
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<K, V> Serialize for HashMap<K, V>
|
impl<K, V, H> Serialize for HashMap<K, V, H>
|
||||||
where K: Serialize + Eq + Hash,
|
where K: Serialize + Eq + Hash,
|
||||||
V: Serialize,
|
V: Serialize,
|
||||||
|
H: BuildHasher,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||||
|
@ -19,6 +19,7 @@ syntex_syntax = { version = "^0.35.0" }
|
|||||||
serde_codegen = { version = "*", path = "../serde_codegen", features = ["with-syntex"] }
|
serde_codegen = { version = "*", path = "../serde_codegen", features = ["with-syntex"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
fnv = "1.0"
|
||||||
rustc-serialize = "^0.3.16"
|
rustc-serialize = "^0.3.16"
|
||||||
serde = { version = "*", path = "../serde" }
|
serde = { version = "*", path = "../serde" }
|
||||||
syntex = "^0.35.0"
|
syntex = "^0.35.0"
|
||||||
|
@ -75,5 +75,13 @@ macro_rules! hashmap {
|
|||||||
$(map.insert($key, $value);)+
|
$(map.insert($key, $value);)+
|
||||||
map
|
map
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
($hasher:ident @ $($key:expr => $value:expr),+) => {
|
||||||
|
{
|
||||||
|
use std::hash::BuildHasherDefault;
|
||||||
|
let mut map = HashMap::with_hasher(BuildHasherDefault::<$hasher>::default());
|
||||||
|
$(map.insert($key, $value);)+
|
||||||
|
map
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,9 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
|||||||
use std::net;
|
use std::net;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
extern crate fnv;
|
||||||
|
use self::fnv::FnvHasher;
|
||||||
|
|
||||||
use token::{
|
use token::{
|
||||||
Error,
|
Error,
|
||||||
Token,
|
Token,
|
||||||
@ -532,6 +535,17 @@ declare_tests! {
|
|||||||
Token::StructStart("Anything", Some(0)),
|
Token::StructStart("Anything", Some(0)),
|
||||||
Token::MapEnd,
|
Token::MapEnd,
|
||||||
],
|
],
|
||||||
|
hashmap![FnvHasher @ 1 => 2, 3 => 4] => vec![
|
||||||
|
Token::MapStart(Some(2)),
|
||||||
|
Token::MapSep,
|
||||||
|
Token::I32(1),
|
||||||
|
Token::I32(2),
|
||||||
|
|
||||||
|
Token::MapSep,
|
||||||
|
Token::I32(3),
|
||||||
|
Token::I32(4),
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
}
|
}
|
||||||
test_struct {
|
test_struct {
|
||||||
Struct { a: 1, b: 2, c: 0 } => vec![
|
Struct { a: 1, b: 2, c: 0 } => vec![
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use std::net;
|
use std::net;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
use token::{self, Token};
|
use token::{self, Token};
|
||||||
|
|
||||||
|
extern crate fnv;
|
||||||
|
use self::fnv::FnvHasher;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
@ -204,6 +207,19 @@ declare_ser_tests! {
|
|||||||
Token::MapEnd,
|
Token::MapEnd,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
test_hashmap {
|
||||||
|
hashmap![FnvHasher @ 1 => 2, 3 => 4] => &[
|
||||||
|
Token::MapStart(Some(2)),
|
||||||
|
Token::MapSep,
|
||||||
|
Token::I32(1),
|
||||||
|
Token::I32(2),
|
||||||
|
|
||||||
|
Token::MapSep,
|
||||||
|
Token::I32(3),
|
||||||
|
Token::I32(4),
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
}
|
||||||
test_unit_struct {
|
test_unit_struct {
|
||||||
UnitStruct => &[Token::UnitStruct("UnitStruct")],
|
UnitStruct => &[Token::UnitStruct("UnitStruct")],
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user