mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-22 22:58:02 +00:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 60ab494226 | |||
| ac758ed3c8 | |||
| 236d40d73e | |||
| 92029a05c6 | |||
| c7b9997dd1 | |||
| 48309bfdd0 | |||
| f76d1ab10d | |||
| 45f552f006 | |||
| 4d42cfea53 | |||
| 7109e2d379 | |||
| ff214643ce | |||
| 04918a52eb | |||
| 5dd71600f7 | |||
| ea9ed22e3e | |||
| 1611daf802 | |||
| e24f52d3ae | |||
| bcc9e15b05 | |||
| af835a2699 | |||
| 5f2d306f9b | |||
| 36fb49b522 |
@@ -174,7 +174,7 @@ impl<K, V, I> MapVisitor for MapIteratorVisitor<I>
|
||||
```
|
||||
|
||||
Serializing structs follow this same pattern. In fact, structs are represented
|
||||
as a named map. It's visitor uses a simple state machine to iterate through all
|
||||
as a named map. Its visitor uses a simple state machine to iterate through all
|
||||
the fields:
|
||||
|
||||
```rust
|
||||
|
||||
+5
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde"
|
||||
version = "0.4.1"
|
||||
version = "0.4.3"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "A generic serialization/deserialization framework"
|
||||
@@ -11,3 +11,7 @@ keywords = ["serialization"]
|
||||
|
||||
[dependencies]
|
||||
num = "*"
|
||||
|
||||
[features]
|
||||
nightly = []
|
||||
|
||||
|
||||
+389
-271
@@ -1,4 +1,17 @@
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||
use std::borrow::Cow;
|
||||
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;
|
||||
@@ -8,12 +21,20 @@ use std::sync::Arc;
|
||||
|
||||
use num::FromPrimitive;
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
use core::nonzero::{NonZero, Zeroable};
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
use std::num::Zero;
|
||||
|
||||
use de::{
|
||||
Deserialize,
|
||||
Deserializer,
|
||||
EnumVisitor,
|
||||
Error,
|
||||
MapVisitor,
|
||||
SeqVisitor,
|
||||
VariantVisitor,
|
||||
Visitor,
|
||||
};
|
||||
|
||||
@@ -41,13 +62,13 @@ impl Deserialize for () {
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<(), D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.visit(UnitVisitor)
|
||||
deserializer.visit_unit(UnitVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct BoolVisitor;
|
||||
pub struct BoolVisitor;
|
||||
|
||||
impl Visitor for BoolVisitor {
|
||||
type Value = bool;
|
||||
@@ -73,7 +94,7 @@ impl Deserialize for bool {
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<bool, D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.visit(BoolVisitor)
|
||||
deserializer.visit_bool(BoolVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,30 +154,30 @@ impl<
|
||||
}
|
||||
|
||||
macro_rules! impl_deserialize_num {
|
||||
($ty:ty) => {
|
||||
($ty:ty, $method:ident) => {
|
||||
impl Deserialize for $ty {
|
||||
#[inline]
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<$ty, D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.visit(PrimitiveVisitor::new())
|
||||
deserializer.$method(PrimitiveVisitor::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_deserialize_num!(isize);
|
||||
impl_deserialize_num!(i8);
|
||||
impl_deserialize_num!(i16);
|
||||
impl_deserialize_num!(i32);
|
||||
impl_deserialize_num!(i64);
|
||||
impl_deserialize_num!(usize);
|
||||
impl_deserialize_num!(u8);
|
||||
impl_deserialize_num!(u16);
|
||||
impl_deserialize_num!(u32);
|
||||
impl_deserialize_num!(u64);
|
||||
impl_deserialize_num!(f32);
|
||||
impl_deserialize_num!(f64);
|
||||
impl_deserialize_num!(isize, visit_isize);
|
||||
impl_deserialize_num!(i8, visit_i8);
|
||||
impl_deserialize_num!(i16, visit_i16);
|
||||
impl_deserialize_num!(i32, visit_i32);
|
||||
impl_deserialize_num!(i64, visit_i64);
|
||||
impl_deserialize_num!(usize, visit_usize);
|
||||
impl_deserialize_num!(u8, visit_u8);
|
||||
impl_deserialize_num!(u16, visit_u16);
|
||||
impl_deserialize_num!(u32, visit_u32);
|
||||
impl_deserialize_num!(u64, visit_u64);
|
||||
impl_deserialize_num!(f32, visit_f32);
|
||||
impl_deserialize_num!(f64, visit_f64);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -194,7 +215,7 @@ impl Deserialize for char {
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<char, D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.visit(CharVisitor)
|
||||
deserializer.visit_char(CharVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,7 +261,7 @@ impl Deserialize for String {
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<String, D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.visit(StringVisitor)
|
||||
deserializer.visit_string(StringVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,159 +301,131 @@ impl<T> Deserialize for Option<T> where T: Deserialize {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub struct BTreeSetVisitor<T> {
|
||||
marker: PhantomData<T>,
|
||||
}
|
||||
macro_rules! set_impl {
|
||||
(
|
||||
$ty:ty,
|
||||
< $($constraints:ident),* >,
|
||||
$visitor_name:ident,
|
||||
$visitor:ident,
|
||||
$ctor:expr,
|
||||
$with_capacity:expr,
|
||||
$insert:expr
|
||||
) => {
|
||||
pub struct $visitor_name<T> {
|
||||
marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> BTreeSetVisitor<T> {
|
||||
pub fn new() -> Self {
|
||||
BTreeSetVisitor {
|
||||
marker: PhantomData,
|
||||
impl<T> $visitor_name<T> {
|
||||
pub fn new() -> Self {
|
||||
$visitor_name {
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Visitor for $visitor_name<T>
|
||||
where T: $($constraints +)*,
|
||||
{
|
||||
type Value = $ty;
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(&mut self) -> Result<$ty, E>
|
||||
where E: Error,
|
||||
{
|
||||
Ok($ctor)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_seq<V>(&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<T> Deserialize for $ty
|
||||
where T: $($constraints +)*,
|
||||
{
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<$ty, D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.visit_seq($visitor_name::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Visitor for BTreeSetVisitor<T>
|
||||
where T: Deserialize + Eq + Ord,
|
||||
{
|
||||
type Value = BTreeSet<T>;
|
||||
set_impl!(
|
||||
BinaryHeap<T>,
|
||||
<Deserialize, Ord>,
|
||||
BinaryHeapVisitor,
|
||||
visitor,
|
||||
BinaryHeap::new(),
|
||||
BinaryHeap::with_capacity(visitor.size_hint().0),
|
||||
BinaryHeap::push);
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(&mut self) -> Result<BTreeSet<T>, E>
|
||||
where E: Error,
|
||||
{
|
||||
Ok(BTreeSet::new())
|
||||
}
|
||||
set_impl!(
|
||||
BTreeSet<T>,
|
||||
<Deserialize, Eq, Ord>,
|
||||
BTreeSetVisitor,
|
||||
visitor,
|
||||
BTreeSet::new(),
|
||||
BTreeSet::new(),
|
||||
BTreeSet::insert);
|
||||
|
||||
#[inline]
|
||||
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<BTreeSet<T>, V::Error>
|
||||
where V: SeqVisitor,
|
||||
{
|
||||
let mut values = BTreeSet::new();
|
||||
#[cfg(feature = "nightly")]
|
||||
set_impl!(
|
||||
EnumSet<T>,
|
||||
<Deserialize, CLike>,
|
||||
EnumSetVisitor,
|
||||
visitor,
|
||||
EnumSet::new(),
|
||||
EnumSet::new(),
|
||||
EnumSet::insert);
|
||||
|
||||
while let Some(value) = try!(visitor.visit()) {
|
||||
values.insert(value);
|
||||
}
|
||||
set_impl!(
|
||||
LinkedList<T>,
|
||||
<Deserialize>,
|
||||
LinkedListVisitor,
|
||||
visitor,
|
||||
LinkedList::new(),
|
||||
LinkedList::new(),
|
||||
LinkedList::push_back);
|
||||
|
||||
try!(visitor.end());
|
||||
set_impl!(
|
||||
HashSet<T>,
|
||||
<Deserialize, Eq, Hash>,
|
||||
HashSetVisitor,
|
||||
visitor,
|
||||
HashSet::new(),
|
||||
HashSet::with_capacity(visitor.size_hint().0),
|
||||
HashSet::insert);
|
||||
|
||||
Ok(values)
|
||||
}
|
||||
}
|
||||
set_impl!(
|
||||
Vec<T>,
|
||||
<Deserialize>,
|
||||
VecVisitor,
|
||||
visitor,
|
||||
Vec::new(),
|
||||
Vec::with_capacity(visitor.size_hint().0),
|
||||
Vec::push);
|
||||
|
||||
impl<T> Deserialize for BTreeSet<T>
|
||||
where T: Deserialize + Eq + Ord,
|
||||
{
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<BTreeSet<T>, D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.visit(BTreeSetVisitor::new())
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub struct HashSetVisitor<T> {
|
||||
marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> HashSetVisitor<T> {
|
||||
pub fn new() -> Self {
|
||||
HashSetVisitor {
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Visitor for HashSetVisitor<T>
|
||||
where T: Deserialize + Eq + Hash,
|
||||
{
|
||||
type Value = HashSet<T>;
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(&mut self) -> Result<HashSet<T>, E>
|
||||
where E: Error,
|
||||
{
|
||||
Ok(HashSet::new())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<HashSet<T>, 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<T> Deserialize for HashSet<T>
|
||||
where T: Deserialize + Eq + Hash,
|
||||
{
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<HashSet<T>, D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.visit(HashSetVisitor::new())
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub struct VecVisitor<T> {
|
||||
marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> VecVisitor<T> {
|
||||
pub fn new() -> Self {
|
||||
VecVisitor {
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Visitor for VecVisitor<T> where T: Deserialize {
|
||||
type Value = Vec<T>;
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(&mut self) -> Result<Vec<T>, E>
|
||||
where E: Error,
|
||||
{
|
||||
Ok(Vec::new())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<Vec<T>, 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<T> Deserialize for Vec<T>
|
||||
where T: Deserialize,
|
||||
{
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<Vec<T>, D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.visit_seq(VecVisitor::new())
|
||||
}
|
||||
}
|
||||
set_impl!(
|
||||
VecDeque<T>,
|
||||
<Deserialize>,
|
||||
VecDequeVisitor,
|
||||
visitor,
|
||||
VecDeque::new(),
|
||||
VecDeque::with_capacity(visitor.size_hint().0),
|
||||
VecDeque::push_back);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -473,7 +466,7 @@ impl<T> Deserialize for [T; 0]
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<[T; 0], D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.visit(ArrayVisitor0::new())
|
||||
deserializer.visit_seq(ArrayVisitor0::new())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -518,7 +511,7 @@ macro_rules! array_impls {
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<[T; $len], D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.visit($visitor::new())
|
||||
deserializer.visit_seq($visitor::new())
|
||||
}
|
||||
}
|
||||
)+
|
||||
@@ -608,7 +601,7 @@ macro_rules! tuple_impls {
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<($($name,)+), D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.visit_seq($visitor { marker: PhantomData })
|
||||
deserializer.visit_tuple($visitor { marker: PhantomData })
|
||||
}
|
||||
}
|
||||
)+
|
||||
@@ -632,123 +625,96 @@ tuple_impls! {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub struct BTreeMapVisitor<K, V> {
|
||||
marker: PhantomData<BTreeMap<K, V>>,
|
||||
}
|
||||
macro_rules! map_impl {
|
||||
(
|
||||
$ty:ty,
|
||||
< $($constraints:ident),* >,
|
||||
$visitor_name:ident,
|
||||
$visitor:ident,
|
||||
$ctor:expr,
|
||||
$with_capacity:expr,
|
||||
$insert:expr
|
||||
) => {
|
||||
pub struct $visitor_name<K, V> {
|
||||
marker: PhantomData<$ty>,
|
||||
}
|
||||
|
||||
impl<K, V> BTreeMapVisitor<K, V> {
|
||||
#[inline]
|
||||
pub fn new() -> Self {
|
||||
BTreeMapVisitor {
|
||||
marker: PhantomData,
|
||||
impl<K, V> $visitor_name<K, V> {
|
||||
pub fn new() -> Self {
|
||||
$visitor_name {
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> Visitor for $visitor_name<K, V>
|
||||
where K: $($constraints +)*,
|
||||
V: Deserialize,
|
||||
{
|
||||
type Value = $ty;
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(&mut self) -> Result<$ty, E>
|
||||
where E: Error,
|
||||
{
|
||||
Ok($ctor)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_map<Visitor>(&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<K, V> Deserialize for $ty
|
||||
where K: $($constraints +)*,
|
||||
V: Deserialize,
|
||||
{
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<$ty, D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.visit_map($visitor_name::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> Visitor for BTreeMapVisitor<K, V>
|
||||
where K: Deserialize + Ord,
|
||||
V: Deserialize
|
||||
{
|
||||
type Value = BTreeMap<K, V>;
|
||||
map_impl!(
|
||||
BTreeMap<K, V>,
|
||||
<Deserialize, Eq, Ord>,
|
||||
BTreeMapVisitor,
|
||||
visitor,
|
||||
BTreeMap::new(),
|
||||
BTreeMap::new(),
|
||||
BTreeMap::insert);
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(&mut self) -> Result<BTreeMap<K, V>, E>
|
||||
where E: Error,
|
||||
{
|
||||
Ok(BTreeMap::new())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_map<Visitor>(&mut self, mut visitor: Visitor) -> Result<BTreeMap<K, V>, 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<K, V> Deserialize for BTreeMap<K, V>
|
||||
where K: Deserialize + Eq + Ord,
|
||||
V: Deserialize,
|
||||
{
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<BTreeMap<K, V>, D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.visit(BTreeMapVisitor::new())
|
||||
}
|
||||
}
|
||||
map_impl!(
|
||||
HashMap<K, V>,
|
||||
<Deserialize, Eq, Hash>,
|
||||
HashMapVisitor,
|
||||
visitor,
|
||||
HashMap::new(),
|
||||
HashMap::with_capacity(visitor.size_hint().0),
|
||||
HashMap::insert);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub struct HashMapVisitor<K, V> {
|
||||
marker: PhantomData<HashMap<K, V>>,
|
||||
}
|
||||
|
||||
impl<K, V> HashMapVisitor<K, V> {
|
||||
#[inline]
|
||||
pub fn new() -> Self {
|
||||
HashMapVisitor {
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> Visitor for HashMapVisitor<K, V>
|
||||
where K: Deserialize + Eq + Hash,
|
||||
V: Deserialize,
|
||||
{
|
||||
type Value = HashMap<K, V>;
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(&mut self) -> Result<HashMap<K, V>, E>
|
||||
where E: Error,
|
||||
{
|
||||
Ok(HashMap::new())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_map<V_>(&mut self, mut visitor: V_) -> Result<HashMap<K, V>, 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<K, V> Deserialize for HashMap<K, V>
|
||||
where K: Deserialize + Eq + Hash,
|
||||
V: Deserialize,
|
||||
{
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<HashMap<K, V>, D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.visit(HashMapVisitor::new())
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FIXME: `VecMap` is unstable.
|
||||
/*
|
||||
#[cfg(feature = "nightly")]
|
||||
pub struct VecMapVisitor<V> {
|
||||
marker: PhantomData<VecMap<V>>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
impl<V> VecMapVisitor<V> {
|
||||
#[inline]
|
||||
pub fn new() -> Self {
|
||||
@@ -758,6 +724,7 @@ impl<V> VecMapVisitor<V> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
impl<V> Visitor for VecMapVisitor<V>
|
||||
where V: Deserialize,
|
||||
{
|
||||
@@ -787,16 +754,16 @@ impl<V> Visitor for VecMapVisitor<V>
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
impl<V> Deserialize for VecMap<V>
|
||||
where V: Deserialize,
|
||||
{
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<VecMap<V>, D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.visit(VecMapVisitor::new())
|
||||
deserializer.visit_map(VecMapVisitor::new())
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -854,3 +821,154 @@ impl<T: Deserialize> Deserialize for Rc<T> {
|
||||
Ok(Rc::new(val))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> Deserialize for Cow<'a, T> where T: ToOwned, T::Owned: Deserialize, {
|
||||
#[inline]
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<Cow<'a, T>, D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
let val = try!(Deserialize::deserialize(deserializer));
|
||||
Ok(Cow::Owned(val))
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
impl<T> Deserialize for NonZero<T> where T: Deserialize + PartialEq + Zeroable + Zero {
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<NonZero<T>, D::Error> where D: Deserializer {
|
||||
let value = try!(Deserialize::deserialize(deserializer));
|
||||
if value == Zero::zero() {
|
||||
return Err(Error::syntax_error())
|
||||
}
|
||||
unsafe {
|
||||
Ok(NonZero::new(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
impl<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<Result<T, E>, D::Error>
|
||||
where D: Deserializer {
|
||||
enum Field {
|
||||
Field0,
|
||||
Field1,
|
||||
}
|
||||
|
||||
impl Deserialize for Field {
|
||||
#[inline]
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<Field, D::Error>
|
||||
where D: Deserializer {
|
||||
struct FieldVisitor<D> {
|
||||
phantom: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D> ::de::Visitor for FieldVisitor<D> where D: Deserializer {
|
||||
type Value = Field;
|
||||
|
||||
fn visit_str<E>(&mut self, value: &str) -> Result<Field, E> where E: Error {
|
||||
match value {
|
||||
"Ok" => Ok(Field::Field0),
|
||||
"Err" => Ok(Field::Field1),
|
||||
_ => Err(Error::unknown_field_error(value)),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(&mut self, value: &[u8]) -> Result<Field, E> where E: Error {
|
||||
match str::from_utf8(value) {
|
||||
Ok(s) => self.visit_str(s),
|
||||
_ => Err(Error::syntax_error()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.visit(FieldVisitor::<D> {
|
||||
phantom: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct Visitor<D, T, E>(PhantomData<D>, PhantomData<T>, PhantomData<E>)
|
||||
where D: Deserializer, T: Deserialize, E: Deserialize;
|
||||
|
||||
impl<D, T, E> EnumVisitor for Visitor<D, T, E> where D: Deserializer,
|
||||
T: Deserialize,
|
||||
E: Deserialize {
|
||||
type Value = Result<T, E>;
|
||||
|
||||
fn visit<V>(&mut self, mut visitor: V) -> Result<Result<T, E>, V::Error>
|
||||
where V: VariantVisitor {
|
||||
match match visitor.visit_variant() {
|
||||
Ok(val) => val,
|
||||
Err(err) => return Err(From::from(err)),
|
||||
} {
|
||||
Field::Field0 => {
|
||||
struct Visitor<D, T, E>(PhantomData<D>, PhantomData<T>, PhantomData<E>)
|
||||
where D: Deserializer,
|
||||
T: Deserialize,
|
||||
E: Deserialize;
|
||||
impl <D, T, E> ::de::Visitor for Visitor<D, T, E> where D: Deserializer,
|
||||
T: Deserialize,
|
||||
E: Deserialize {
|
||||
type Value = Result<T, E>;
|
||||
|
||||
fn visit_seq<V>(&mut self, mut visitor: V)
|
||||
-> Result<Result<T, E>, V::Error> where V: SeqVisitor {
|
||||
let field0 = match match visitor.visit() {
|
||||
Ok(val) => val,
|
||||
Err(err) => return Err(From::from(err)),
|
||||
} {
|
||||
Some(value) => value,
|
||||
None => return Err(Error::end_of_stream_error()),
|
||||
};
|
||||
match visitor.end() {
|
||||
Ok(val) => val,
|
||||
Err(err) => return Err(From::from(err)),
|
||||
};
|
||||
Ok(Result::Ok(field0))
|
||||
}
|
||||
}
|
||||
visitor.visit_seq(Visitor::<D, T, E>(PhantomData,
|
||||
PhantomData,
|
||||
PhantomData))
|
||||
}
|
||||
Field::Field1 => {
|
||||
struct Visitor<D, T, E>(PhantomData<D>, PhantomData<T>, PhantomData<E>)
|
||||
where D: Deserializer,
|
||||
T: Deserialize,
|
||||
E: Deserialize;
|
||||
impl <D, T, E> ::de::Visitor for Visitor<D, T, E> where D: Deserializer,
|
||||
T: Deserialize,
|
||||
E: Deserialize {
|
||||
type Value = Result<T, E>;
|
||||
|
||||
fn visit_seq<V>(&mut self, mut visitor: V)
|
||||
-> Result<Result<T, E>, V::Error> where V: SeqVisitor {
|
||||
let field0 = match match visitor.visit() {
|
||||
Ok(val) => val,
|
||||
Err(err) => return Err(From::from(err)),
|
||||
} {
|
||||
Some(value) => value,
|
||||
None => return Err(Error::end_of_stream_error()),
|
||||
};
|
||||
match visitor.end() {
|
||||
Ok(val) => val,
|
||||
Err(err) => return Err(From::from(err)),
|
||||
};
|
||||
Ok(Result::Err(field0))
|
||||
}
|
||||
}
|
||||
visitor.visit_seq(Visitor::<D, T, E>(PhantomData,
|
||||
PhantomData,
|
||||
PhantomData))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.visit_enum("Result",
|
||||
Visitor::<D, T, E>(PhantomData, PhantomData, PhantomData))
|
||||
}
|
||||
}
|
||||
|
||||
+177
-27
@@ -25,18 +25,164 @@ pub trait Deserialize {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// `Deserializer` is an abstract trait that can deserialize values into a `Visitor`.
|
||||
/// `Deserializer` is a trait that can deserialize values by threading a `Visitor` trait through a
|
||||
/// value. It supports two entry point styles which enables different kinds of deserialization.
|
||||
///
|
||||
/// 1) The `visit` method. File formats like JSON embed the type of it's construct in it's file
|
||||
/// format. This allows the `Deserializer` to deserialize into a generic type like
|
||||
/// `json::Value`, which can represent all JSON types.
|
||||
///
|
||||
/// 2) The `visit_*` methods. File formats like bincode do not embed in it's format how to decode
|
||||
/// it's values. It relies instead on the `Deserialize` type to hint to the `Deserializer` with
|
||||
/// the `visit_*` methods how it should parse the next value. One downside though to only
|
||||
/// supporting the `visit_*` types is that it does not allow for deserializing into a generic
|
||||
/// `json::Value`-esque type.
|
||||
pub trait Deserializer {
|
||||
type Error: Error;
|
||||
|
||||
/// The `visit` method walks a visitor through a value as it is being deserialized.
|
||||
/// This method walks a visitor through a value as it is being deserialized.
|
||||
fn visit<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor;
|
||||
|
||||
/// The `visit_option` method allows a `Deserialize` type to inform the `Deserializer` that
|
||||
/// it's expecting an optional value. This allows deserializers that encode an optional value
|
||||
/// as a nullable value to convert the null value into a `None`, and a regular value as
|
||||
/// `Some(value)`.
|
||||
/// This method hints that the `Deserialize` type is expecting a `bool` value.
|
||||
#[inline]
|
||||
fn visit_bool<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `usize` value.
|
||||
#[inline]
|
||||
fn visit_usize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `u8` value.
|
||||
#[inline]
|
||||
fn visit_u8<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `u16` value.
|
||||
#[inline]
|
||||
fn visit_u16<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `u32` value.
|
||||
#[inline]
|
||||
fn visit_u32<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `u64` value.
|
||||
#[inline]
|
||||
fn visit_u64<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `isize` value.
|
||||
#[inline]
|
||||
fn visit_isize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `i8` value.
|
||||
#[inline]
|
||||
fn visit_i8<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `i16` value.
|
||||
#[inline]
|
||||
fn visit_i16<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `i32` value.
|
||||
#[inline]
|
||||
fn visit_i32<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `i64` value.
|
||||
#[inline]
|
||||
fn visit_i64<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting a `f32` value.
|
||||
#[inline]
|
||||
fn visit_f32<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting a `f64` value.
|
||||
#[inline]
|
||||
fn visit_f64<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting a `char` value.
|
||||
#[inline]
|
||||
fn visit_char<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting a `&str` value.
|
||||
#[inline]
|
||||
fn visit_str<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting a `String` value.
|
||||
#[inline]
|
||||
fn visit_string<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit_str(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `unit` value.
|
||||
#[inline]
|
||||
fn visit_unit<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `Option` value. This allows
|
||||
/// deserializers that encode an optional value as a nullable value to convert the null value
|
||||
/// into a `None`, and a regular value as `Some(value)`.
|
||||
#[inline]
|
||||
fn visit_option<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
@@ -44,9 +190,8 @@ pub trait Deserializer {
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// The `visit_seq` method allows a `Deserialize` type to inform the `Deserializer` that it's
|
||||
/// expecting a sequence of values. This allows deserializers to parse sequences that aren't
|
||||
/// tagged as sequences.
|
||||
/// This method hints that the `Deserialize` type is expecting a sequence value. This allows
|
||||
/// deserializers to parse sequences that aren't tagged as sequences.
|
||||
#[inline]
|
||||
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
@@ -54,9 +199,8 @@ pub trait Deserializer {
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// The `visit_map` method allows a `Deserialize` type to inform the `Deserializer` that it's
|
||||
/// expecting a map of values. This allows deserializers to parse sequences that aren't tagged
|
||||
/// as maps.
|
||||
/// This method hints that the `Deserialize` type is expecting a map of values. This allows
|
||||
/// deserializers to parse sequences that aren't tagged as maps.
|
||||
#[inline]
|
||||
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
@@ -64,9 +208,8 @@ pub trait Deserializer {
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// The `visit_named_unit` method allows a `Deserialize` type to inform the `Deserializer` that
|
||||
/// it's expecting a named unit. This allows deserializers to a named unit that aren't tagged
|
||||
/// as a named unit.
|
||||
/// This method hints that the `Deserialize` type is expecting a named unit. This allows
|
||||
/// deserializers to a named unit that aren't tagged as a named unit.
|
||||
#[inline]
|
||||
fn visit_named_unit<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
@@ -74,9 +217,8 @@ pub trait Deserializer {
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// The `visit_named_seq` method allows a `Deserialize` type to inform the `Deserializer` that
|
||||
/// it's expecting a named sequence of values. This allows deserializers to parse sequences
|
||||
/// that aren't tagged as sequences.
|
||||
/// This method hints that the `Deserialize` type is expecting a named sequence.
|
||||
/// This allows deserializers to parse sequences that aren't tagged as sequences.
|
||||
#[inline]
|
||||
fn visit_named_seq<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
@@ -84,9 +226,8 @@ pub trait Deserializer {
|
||||
self.visit_seq(visitor)
|
||||
}
|
||||
|
||||
/// The `visit_named_map` method allows a `Deserialize` type to inform the `Deserializer` that
|
||||
/// it's expecting a map of values. This allows deserializers to parse sequences that aren't
|
||||
/// tagged as maps.
|
||||
/// This method hints that the `Deserialize` type is expecting a named map. This allows
|
||||
/// deserializers to parse sequences that aren't tagged as maps.
|
||||
#[inline]
|
||||
fn visit_named_map<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
@@ -94,9 +235,18 @@ pub trait Deserializer {
|
||||
self.visit_map(visitor)
|
||||
}
|
||||
|
||||
/// The `visit_enum` method allows a `Deserialize` type to inform the `Deserializer` that it's
|
||||
/// expecting an enum value. This allows deserializers that provide a custom enumeration
|
||||
/// serialization to properly deserialize the type.
|
||||
/// This method hints that the `Deserialize` type is expecting a tuple value. This allows
|
||||
/// deserializers that provide a custom tuple serialization to properly deserialize the type.
|
||||
#[inline]
|
||||
fn visit_tuple<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an enum value. This allows
|
||||
/// deserializers that provide a custom enumeration serialization to properly deserialize the
|
||||
/// type.
|
||||
#[inline]
|
||||
fn visit_enum<V>(&mut self, _enum: &str, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: EnumVisitor,
|
||||
@@ -104,9 +254,9 @@ pub trait Deserializer {
|
||||
Err(Error::syntax_error())
|
||||
}
|
||||
|
||||
/// The `visit_bytes` method allows a `Deserialize` type to inform the `Deserializer` that it's
|
||||
/// expecting a `Vec<u8>`. This allows deserializers that provide a custom byte vector
|
||||
/// serialization to properly deserialize the type.
|
||||
/// This method hints that the `Deserialize` type is expecting a `Vec<u8>`. This allows
|
||||
/// deserializers that provide a custom byte vector serialization to properly deserialize the
|
||||
/// type.
|
||||
#[inline]
|
||||
fn visit_bytes<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
|
||||
@@ -6,9 +6,16 @@
|
||||
//! leaving serde to perform roughly the same speed as a hand written serializer for a specific
|
||||
//! type.
|
||||
#![doc(html_root_url="http://erickt.github.io/rust-serde")]
|
||||
#![cfg_attr(feature = "nightly", feature(collections, core, enumset, nonzero, step_trait, vecmap, zero_one))]
|
||||
|
||||
extern crate num;
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
extern crate collections;
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
extern crate core;
|
||||
|
||||
pub use ser::{Serialize, Serializer};
|
||||
pub use de::{Deserialize, Deserializer, Error};
|
||||
|
||||
|
||||
+194
-9
@@ -1,9 +1,32 @@
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||
use std::borrow::Cow;
|
||||
use std::collections::{
|
||||
BinaryHeap,
|
||||
BTreeMap,
|
||||
BTreeSet,
|
||||
LinkedList,
|
||||
HashMap,
|
||||
HashSet,
|
||||
VecDeque,
|
||||
};
|
||||
#[cfg(feature = "nightly")]
|
||||
use collections::enum_set::{CLike, EnumSet};
|
||||
#[cfg(feature = "nightly")]
|
||||
use std::collections::vec_map::VecMap;
|
||||
use std::hash::Hash;
|
||||
#[cfg(feature = "nightly")]
|
||||
use std::iter;
|
||||
use std::marker::PhantomData;
|
||||
#[cfg(feature = "nightly")]
|
||||
use std::num;
|
||||
#[cfg(feature = "nightly")]
|
||||
use std::ops;
|
||||
use std::path;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
use core::nonzero::{NonZero, Zeroable};
|
||||
|
||||
use super::{
|
||||
Serialize,
|
||||
Serializer,
|
||||
@@ -119,7 +142,7 @@ impl<T, Iter> SeqVisitor for SeqIteratorVisitor<Iter>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
impl<'a, T> Serialize for &'a [T]
|
||||
impl<T> Serialize for [T]
|
||||
where T: Serialize,
|
||||
{
|
||||
#[inline]
|
||||
@@ -177,12 +200,16 @@ array_impls!(30);
|
||||
array_impls!(31);
|
||||
array_impls!(32);
|
||||
|
||||
impl<T> Serialize for Vec<T> where T: Serialize {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
impl<T> Serialize for BinaryHeap<T>
|
||||
where T: Serialize + Ord
|
||||
{
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||
where S: Serializer,
|
||||
{
|
||||
(&self[..]).serialize(serializer)
|
||||
serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,6 +224,18 @@ impl<T> Serialize for BTreeSet<T>
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
impl<T> Serialize for EnumSet<T>
|
||||
where T: Serialize + CLike
|
||||
{
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||
where S: Serializer,
|
||||
{
|
||||
serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Serialize for HashSet<T>
|
||||
where T: Serialize + Eq + Hash,
|
||||
{
|
||||
@@ -208,6 +247,49 @@ impl<T> Serialize for HashSet<T>
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Serialize for LinkedList<T>
|
||||
where T: Serialize,
|
||||
{
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||
where S: Serializer,
|
||||
{
|
||||
serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
impl<A> Serialize for ops::Range<A>
|
||||
where A: Serialize + Clone + iter::Step + num::One,
|
||||
for<'a> &'a A: ops::Add<&'a A, Output = A>,
|
||||
{
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||
where S: Serializer,
|
||||
{
|
||||
let len = iter::Step::steps_between(&self.start, &self.end, &A::one());
|
||||
serializer.visit_seq(SeqIteratorVisitor::new(self.clone(), len))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Serialize for Vec<T> where T: Serialize {
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||
where S: Serializer,
|
||||
{
|
||||
(&self[..]).serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Serialize for VecDeque<T> where T: Serialize {
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||
where S: Serializer,
|
||||
{
|
||||
serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
impl Serialize for () {
|
||||
@@ -257,7 +339,7 @@ macro_rules! tuple_impls {
|
||||
$(
|
||||
$state => {
|
||||
self.state += 1;
|
||||
Ok(Some(try!(serializer.visit_seq_elt(&e!(self.tuple.$idx)))))
|
||||
Ok(Some(try!(serializer.visit_tuple_elt(&e!(self.tuple.$idx)))))
|
||||
}
|
||||
)+
|
||||
_ => {
|
||||
@@ -276,7 +358,7 @@ macro_rules! tuple_impls {
|
||||
{
|
||||
#[inline]
|
||||
fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
|
||||
serializer.visit_seq($TupleVisitor::new(self))
|
||||
serializer.visit_tuple($TupleVisitor::new(self))
|
||||
}
|
||||
}
|
||||
)+
|
||||
@@ -457,8 +539,7 @@ impl<K, V> Serialize for HashMap<K, V>
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: `VecMap` is unstable.
|
||||
/*
|
||||
#[cfg(feature = "nightly")]
|
||||
impl<V> Serialize for VecMap<V>
|
||||
where V: Serialize,
|
||||
{
|
||||
@@ -469,7 +550,6 @@ impl<V> Serialize for VecMap<V>
|
||||
serializer.visit_map(MapIteratorVisitor::new(self.iter(), Some(self.len())))
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -518,6 +598,104 @@ impl<T> Serialize for Arc<T> where T: Serialize, {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> Serialize for Cow<'a, T> where T: Serialize + ToOwned, {
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||
where S: Serializer,
|
||||
{
|
||||
(**self).serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
impl<T, E> Serialize for Result<T, E> where T: Serialize, E: Serialize {
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
|
||||
match *self {
|
||||
Result::Ok(ref field0) => {
|
||||
struct Visitor<'a, T, E> where T: Serialize + 'a, E: Serialize + 'a {
|
||||
state: usize,
|
||||
value: (&'a T,),
|
||||
_structure_ty: PhantomData<&'a Result<T, E>>,
|
||||
}
|
||||
|
||||
impl<'a, T, E> SeqVisitor for Visitor<'a, T, E> where T: Serialize + 'a,
|
||||
E: Serialize + 'a {
|
||||
#[inline]
|
||||
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
|
||||
where S: Serializer {
|
||||
match self.state {
|
||||
0 => {
|
||||
self.state += 1;
|
||||
let v = match serializer.visit_seq_elt(&self.value.0) {
|
||||
Ok(val) => val,
|
||||
Err(err) => return Err(From::from(err)),
|
||||
};
|
||||
Ok(Some(v))
|
||||
}
|
||||
_ => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn len(&self) -> Option<usize> {
|
||||
Some(1)
|
||||
}
|
||||
}
|
||||
|
||||
let field0: &T = field0;
|
||||
let data: PhantomData<&Result<&T,E>> = PhantomData;
|
||||
let visitor = Visitor {
|
||||
value: (&field0,),
|
||||
state: 0,
|
||||
_structure_ty: data
|
||||
};
|
||||
serializer.visit_enum_seq("Result", "Ok", visitor)
|
||||
}
|
||||
Result::Err(ref field0) => {
|
||||
struct Visitor<'a, T, E> where T: Serialize + 'a, E: Serialize + 'a {
|
||||
state: usize,
|
||||
value: (&'a E,),
|
||||
_structure_ty: PhantomData<&'a Result<T, E>>,
|
||||
}
|
||||
|
||||
impl<'a, T, E> SeqVisitor for Visitor<'a, T, E> where T: Serialize + 'a,
|
||||
E: Serialize + 'a {
|
||||
#[inline]
|
||||
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
|
||||
where S: Serializer {
|
||||
match self.state {
|
||||
0 => {
|
||||
self.state += 1;
|
||||
let v = match serializer.visit_seq_elt(&self.value.0) {
|
||||
Ok(val) => val,
|
||||
Err(err) => return Err(From::from(err)),
|
||||
};
|
||||
Ok(Some(v))
|
||||
}
|
||||
_ => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn len(&self) -> Option<usize> {
|
||||
Some(1)
|
||||
}
|
||||
}
|
||||
|
||||
let field0: &E = field0;
|
||||
let data: PhantomData<&Result<T,&E>> = PhantomData;
|
||||
let visitor = Visitor {
|
||||
value: (&field0,),
|
||||
state: 0,
|
||||
_structure_ty: data
|
||||
};
|
||||
serializer.visit_enum_seq("Result", "Err", visitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
impl Serialize for path::Path {
|
||||
@@ -535,3 +713,10 @@ impl Serialize for path::PathBuf {
|
||||
self.to_str().unwrap().serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
impl<T> Serialize for NonZero<T> where T: Serialize + Zeroable {
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
|
||||
(**self).serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
+56
-12
@@ -132,13 +132,37 @@ pub trait Serializer {
|
||||
fn visit_seq<V>(&mut self, visitor: V) -> Result<(), Self::Error>
|
||||
where V: SeqVisitor;
|
||||
|
||||
fn visit_seq_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
|
||||
where T: Serialize;
|
||||
|
||||
#[inline]
|
||||
fn visit_tuple<V>(&mut self, visitor: V) -> Result<(), Self::Error>
|
||||
where V: SeqVisitor,
|
||||
{
|
||||
self.visit_seq(visitor)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_tuple_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
|
||||
where T: Serialize
|
||||
{
|
||||
self.visit_seq_elt(value)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_named_seq<V>(&mut self,
|
||||
_name: &'static str,
|
||||
visitor: V) -> Result<(), Self::Error>
|
||||
where V: SeqVisitor,
|
||||
{
|
||||
self.visit_seq(visitor)
|
||||
self.visit_tuple(visitor)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_named_seq_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
|
||||
where T: Serialize
|
||||
{
|
||||
self.visit_tuple_elt(value)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -148,15 +172,23 @@ pub trait Serializer {
|
||||
visitor: V) -> Result<(), Self::Error>
|
||||
where V: SeqVisitor,
|
||||
{
|
||||
self.visit_seq(visitor)
|
||||
self.visit_tuple(visitor)
|
||||
}
|
||||
|
||||
fn visit_seq_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
|
||||
where T: Serialize;
|
||||
#[inline]
|
||||
fn visit_enum_seq_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
|
||||
where T: Serialize
|
||||
{
|
||||
self.visit_tuple_elt(value)
|
||||
}
|
||||
|
||||
fn visit_map<V>(&mut self, visitor: V) -> Result<(), Self::Error>
|
||||
where V: MapVisitor;
|
||||
|
||||
fn visit_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), Self::Error>
|
||||
where K: Serialize,
|
||||
V: Serialize;
|
||||
|
||||
#[inline]
|
||||
fn visit_named_map<V>(&mut self,
|
||||
_name: &'static str,
|
||||
@@ -167,18 +199,30 @@ pub trait Serializer {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_enum_map<V>(&mut self,
|
||||
_name: &'static str,
|
||||
_variant: &'static str,
|
||||
visitor: V) -> Result<(), Self::Error>
|
||||
where V: MapVisitor,
|
||||
fn visit_named_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), Self::Error>
|
||||
where K: Serialize,
|
||||
V: Serialize,
|
||||
{
|
||||
self.visit_map(visitor)
|
||||
self.visit_map_elt(key, value)
|
||||
}
|
||||
|
||||
fn visit_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), Self::Error>
|
||||
#[inline]
|
||||
fn visit_enum_map<V>(&mut self,
|
||||
_name: &'static str,
|
||||
variant: &'static str,
|
||||
visitor: V) -> Result<(), Self::Error>
|
||||
where V: MapVisitor,
|
||||
{
|
||||
self.visit_named_map(variant, visitor)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_enum_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), Self::Error>
|
||||
where K: Serialize,
|
||||
V: Serialize;
|
||||
V: Serialize,
|
||||
{
|
||||
self.visit_named_map_elt(key, value)
|
||||
}
|
||||
|
||||
/// Specify a format string for the serializer.
|
||||
///
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_codegen"
|
||||
version = "0.4.1"
|
||||
version = "0.4.3"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "Macros to auto-generate implementations for the serde framework"
|
||||
|
||||
@@ -476,7 +476,7 @@ fn serialize_tuple_struct_visitor(
|
||||
quote_arm!(cx,
|
||||
$i => {
|
||||
self.state += 1;
|
||||
let v = try!(serializer.visit_seq_elt(&$expr));
|
||||
let v = try!(serializer.visit_named_seq_elt(&$expr));
|
||||
Ok(Some(v))
|
||||
}
|
||||
)
|
||||
@@ -559,7 +559,7 @@ fn serialize_struct_visitor<I>(
|
||||
Ok(
|
||||
Some(
|
||||
try!(
|
||||
serializer.visit_map_elt(
|
||||
serializer.visit_named_map_elt(
|
||||
$key_expr,
|
||||
$value_expr,
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_macros"
|
||||
version = "0.4.1"
|
||||
version = "0.4.4"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "Macros to auto-generate implementations for the serde framework"
|
||||
@@ -16,4 +16,4 @@ serde_codegen = { version = "*", path = "../serde_codegen", default-features = f
|
||||
[dev-dependencies]
|
||||
num = "*"
|
||||
rustc-serialize = "*"
|
||||
serde = { version = "*", path = "../serde" }
|
||||
serde = { version = "*", path = "../serde", features = ["nightly"] }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_tests"
|
||||
version = "0.4.1"
|
||||
version = "0.4.3"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "A generic serialization/deserialization framework"
|
||||
|
||||
@@ -50,7 +50,7 @@ impl rustc_serialize::Decodable for HttpProtocol {
|
||||
|
||||
impl FromStr for HttpProtocol {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<HttpProtocol, ()> { unimplemented!() }
|
||||
fn from_str(_s: &str) -> Result<HttpProtocol, ()> { unimplemented!() }
|
||||
}
|
||||
|
||||
impl FromPrimitive for HttpProtocol {
|
||||
@@ -104,7 +104,7 @@ enum HttpMethod {
|
||||
|
||||
impl FromStr for HttpMethod {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<HttpMethod, ()> { unimplemented!() }
|
||||
fn from_str(_s: &str) -> Result<HttpMethod, ()> { unimplemented!() }
|
||||
}
|
||||
|
||||
impl FromPrimitive for HttpMethod {
|
||||
@@ -174,7 +174,7 @@ enum CacheStatus {
|
||||
|
||||
impl FromStr for CacheStatus {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<CacheStatus, ()> { unimplemented!() }
|
||||
fn from_str(_s: &str) -> Result<CacheStatus, ()> { unimplemented!() }
|
||||
}
|
||||
|
||||
impl FromPrimitive for CacheStatus {
|
||||
@@ -244,7 +244,7 @@ enum OriginProtocol {
|
||||
|
||||
impl FromStr for OriginProtocol {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<OriginProtocol, ()> { unimplemented!() }
|
||||
fn from_str(_s: &str) -> Result<OriginProtocol, ()> { unimplemented!() }
|
||||
}
|
||||
|
||||
impl FromPrimitive for OriginProtocol {
|
||||
@@ -307,7 +307,7 @@ enum ZonePlan {
|
||||
|
||||
impl FromStr for ZonePlan {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<ZonePlan, ()> { unimplemented!() }
|
||||
fn from_str(_s: &str) -> Result<ZonePlan, ()> { unimplemented!() }
|
||||
}
|
||||
|
||||
impl FromPrimitive for ZonePlan {
|
||||
@@ -622,7 +622,7 @@ enum Country {
|
||||
|
||||
impl FromStr for Country {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<Country, ()> { unimplemented!() }
|
||||
fn from_str(_s: &str) -> Result<Country, ()> { unimplemented!() }
|
||||
}
|
||||
|
||||
impl FromPrimitive for Country {
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
/*
|
||||
mod test_annotations;
|
||||
mod test_bytes;
|
||||
mod test_de;
|
||||
mod test_json;
|
||||
mod test_json_builder;
|
||||
*/
|
||||
mod test_macros;
|
||||
/*
|
||||
mod test_ser;
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user