mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-24 22:47:58 +00:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ac758ed3c8 | |||
| 236d40d73e | |||
| 92029a05c6 | |||
| c7b9997dd1 | |||
| 48309bfdd0 | |||
| f76d1ab10d | |||
| 45f552f006 | |||
| 4d42cfea53 | |||
| 7109e2d379 | |||
| ff214643ce | |||
| 04918a52eb | |||
| 5dd71600f7 | |||
| ea9ed22e3e | |||
| 1611daf802 | |||
| e24f52d3ae | |||
| bcc9e15b05 | |||
| af835a2699 | |||
| 5f2d306f9b | |||
| 36fb49b522 | |||
| ed5b4d7319 | |||
| b09c0fc653 |
@@ -174,7 +174,7 @@ impl<K, V, I> MapVisitor for MapIteratorVisitor<I>
|
|||||||
```
|
```
|
||||||
|
|
||||||
Serializing structs follow this same pattern. In fact, structs are represented
|
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:
|
the fields:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
|||||||
+5
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "0.4.1"
|
version = "0.4.3"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "A generic serialization/deserialization framework"
|
description = "A generic serialization/deserialization framework"
|
||||||
@@ -11,3 +11,7 @@ keywords = ["serialization"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
num = "*"
|
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::hash::Hash;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::path;
|
use std::path;
|
||||||
@@ -8,12 +21,20 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use num::FromPrimitive;
|
use num::FromPrimitive;
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
|
use core::nonzero::{NonZero, Zeroable};
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
|
use std::num::Zero;
|
||||||
|
|
||||||
use de::{
|
use de::{
|
||||||
Deserialize,
|
Deserialize,
|
||||||
Deserializer,
|
Deserializer,
|
||||||
|
EnumVisitor,
|
||||||
Error,
|
Error,
|
||||||
MapVisitor,
|
MapVisitor,
|
||||||
SeqVisitor,
|
SeqVisitor,
|
||||||
|
VariantVisitor,
|
||||||
Visitor,
|
Visitor,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -41,13 +62,13 @@ impl Deserialize for () {
|
|||||||
fn deserialize<D>(deserializer: &mut D) -> Result<(), D::Error>
|
fn deserialize<D>(deserializer: &mut D) -> Result<(), D::Error>
|
||||||
where D: Deserializer,
|
where D: Deserializer,
|
||||||
{
|
{
|
||||||
deserializer.visit(UnitVisitor)
|
deserializer.visit_unit(UnitVisitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
struct BoolVisitor;
|
pub struct BoolVisitor;
|
||||||
|
|
||||||
impl Visitor for BoolVisitor {
|
impl Visitor for BoolVisitor {
|
||||||
type Value = bool;
|
type Value = bool;
|
||||||
@@ -73,7 +94,7 @@ impl Deserialize for bool {
|
|||||||
fn deserialize<D>(deserializer: &mut D) -> Result<bool, D::Error>
|
fn deserialize<D>(deserializer: &mut D) -> Result<bool, D::Error>
|
||||||
where D: Deserializer,
|
where D: Deserializer,
|
||||||
{
|
{
|
||||||
deserializer.visit(BoolVisitor)
|
deserializer.visit_bool(BoolVisitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,30 +154,30 @@ impl<
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_deserialize_num {
|
macro_rules! impl_deserialize_num {
|
||||||
($ty:ty) => {
|
($ty:ty, $method:ident) => {
|
||||||
impl Deserialize for $ty {
|
impl Deserialize for $ty {
|
||||||
#[inline]
|
#[inline]
|
||||||
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.visit(PrimitiveVisitor::new())
|
deserializer.$method(PrimitiveVisitor::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_deserialize_num!(isize);
|
impl_deserialize_num!(isize, visit_isize);
|
||||||
impl_deserialize_num!(i8);
|
impl_deserialize_num!(i8, visit_i8);
|
||||||
impl_deserialize_num!(i16);
|
impl_deserialize_num!(i16, visit_i16);
|
||||||
impl_deserialize_num!(i32);
|
impl_deserialize_num!(i32, visit_i32);
|
||||||
impl_deserialize_num!(i64);
|
impl_deserialize_num!(i64, visit_i64);
|
||||||
impl_deserialize_num!(usize);
|
impl_deserialize_num!(usize, visit_usize);
|
||||||
impl_deserialize_num!(u8);
|
impl_deserialize_num!(u8, visit_u8);
|
||||||
impl_deserialize_num!(u16);
|
impl_deserialize_num!(u16, visit_u16);
|
||||||
impl_deserialize_num!(u32);
|
impl_deserialize_num!(u32, visit_u32);
|
||||||
impl_deserialize_num!(u64);
|
impl_deserialize_num!(u64, visit_u64);
|
||||||
impl_deserialize_num!(f32);
|
impl_deserialize_num!(f32, visit_f32);
|
||||||
impl_deserialize_num!(f64);
|
impl_deserialize_num!(f64, visit_f64);
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -194,7 +215,7 @@ impl Deserialize for char {
|
|||||||
fn deserialize<D>(deserializer: &mut D) -> Result<char, D::Error>
|
fn deserialize<D>(deserializer: &mut D) -> Result<char, D::Error>
|
||||||
where D: Deserializer,
|
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>
|
fn deserialize<D>(deserializer: &mut D) -> Result<String, D::Error>
|
||||||
where D: Deserializer,
|
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> {
|
macro_rules! set_impl {
|
||||||
marker: PhantomData<T>,
|
(
|
||||||
}
|
$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> {
|
impl<T> $visitor_name<T> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
BTreeSetVisitor {
|
$visitor_name {
|
||||||
marker: PhantomData,
|
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>
|
set_impl!(
|
||||||
where T: Deserialize + Eq + Ord,
|
BinaryHeap<T>,
|
||||||
{
|
<Deserialize, Ord>,
|
||||||
type Value = BTreeSet<T>;
|
BinaryHeapVisitor,
|
||||||
|
visitor,
|
||||||
|
BinaryHeap::new(),
|
||||||
|
BinaryHeap::with_capacity(visitor.size_hint().0),
|
||||||
|
BinaryHeap::push);
|
||||||
|
|
||||||
#[inline]
|
set_impl!(
|
||||||
fn visit_unit<E>(&mut self) -> Result<BTreeSet<T>, E>
|
BTreeSet<T>,
|
||||||
where E: Error,
|
<Deserialize, Eq, Ord>,
|
||||||
{
|
BTreeSetVisitor,
|
||||||
Ok(BTreeSet::new())
|
visitor,
|
||||||
}
|
BTreeSet::new(),
|
||||||
|
BTreeSet::new(),
|
||||||
|
BTreeSet::insert);
|
||||||
|
|
||||||
#[inline]
|
#[cfg(feature = "nightly")]
|
||||||
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<BTreeSet<T>, V::Error>
|
set_impl!(
|
||||||
where V: SeqVisitor,
|
EnumSet<T>,
|
||||||
{
|
<Deserialize, CLike>,
|
||||||
let mut values = BTreeSet::new();
|
EnumSetVisitor,
|
||||||
|
visitor,
|
||||||
|
EnumSet::new(),
|
||||||
|
EnumSet::new(),
|
||||||
|
EnumSet::insert);
|
||||||
|
|
||||||
while let Some(value) = try!(visitor.visit()) {
|
set_impl!(
|
||||||
values.insert(value);
|
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>
|
set_impl!(
|
||||||
where T: Deserialize + Eq + Ord,
|
VecDeque<T>,
|
||||||
{
|
<Deserialize>,
|
||||||
fn deserialize<D>(deserializer: &mut D) -> Result<BTreeSet<T>, D::Error>
|
VecDequeVisitor,
|
||||||
where D: Deserializer,
|
visitor,
|
||||||
{
|
VecDeque::new(),
|
||||||
deserializer.visit(BTreeSetVisitor::new())
|
VecDeque::with_capacity(visitor.size_hint().0),
|
||||||
}
|
VecDeque::push_back);
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
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())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -473,7 +466,7 @@ impl<T> Deserialize for [T; 0]
|
|||||||
fn deserialize<D>(deserializer: &mut D) -> Result<[T; 0], D::Error>
|
fn deserialize<D>(deserializer: &mut D) -> Result<[T; 0], D::Error>
|
||||||
where D: Deserializer,
|
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>
|
fn deserialize<D>(deserializer: &mut D) -> Result<[T; $len], D::Error>
|
||||||
where D: Deserializer,
|
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>
|
fn deserialize<D>(deserializer: &mut D) -> Result<($($name,)+), D::Error>
|
||||||
where D: Deserializer,
|
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> {
|
macro_rules! map_impl {
|
||||||
marker: PhantomData<BTreeMap<K, V>>,
|
(
|
||||||
}
|
$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> {
|
impl<K, V> $visitor_name<K, V> {
|
||||||
#[inline]
|
pub fn new() -> Self {
|
||||||
pub fn new() -> Self {
|
$visitor_name {
|
||||||
BTreeMapVisitor {
|
marker: PhantomData,
|
||||||
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>
|
map_impl!(
|
||||||
where K: Deserialize + Ord,
|
BTreeMap<K, V>,
|
||||||
V: Deserialize
|
<Deserialize, Eq, Ord>,
|
||||||
{
|
BTreeMapVisitor,
|
||||||
type Value = BTreeMap<K, V>;
|
visitor,
|
||||||
|
BTreeMap::new(),
|
||||||
|
BTreeMap::new(),
|
||||||
|
BTreeMap::insert);
|
||||||
|
|
||||||
#[inline]
|
map_impl!(
|
||||||
fn visit_unit<E>(&mut self) -> Result<BTreeMap<K, V>, E>
|
HashMap<K, V>,
|
||||||
where E: Error,
|
<Deserialize, Eq, Hash>,
|
||||||
{
|
HashMapVisitor,
|
||||||
Ok(BTreeMap::new())
|
visitor,
|
||||||
}
|
HashMap::new(),
|
||||||
|
HashMap::with_capacity(visitor.size_hint().0),
|
||||||
#[inline]
|
HashMap::insert);
|
||||||
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())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
pub struct HashMapVisitor<K, V> {
|
#[cfg(feature = "nightly")]
|
||||||
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.
|
|
||||||
/*
|
|
||||||
pub struct VecMapVisitor<V> {
|
pub struct VecMapVisitor<V> {
|
||||||
marker: PhantomData<VecMap<V>>,
|
marker: PhantomData<VecMap<V>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
impl<V> VecMapVisitor<V> {
|
impl<V> VecMapVisitor<V> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
@@ -758,6 +724,7 @@ impl<V> VecMapVisitor<V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
impl<V> Visitor for VecMapVisitor<V>
|
impl<V> Visitor for VecMapVisitor<V>
|
||||||
where V: Deserialize,
|
where V: Deserialize,
|
||||||
{
|
{
|
||||||
@@ -787,16 +754,16 @@ impl<V> Visitor for VecMapVisitor<V>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
impl<V> Deserialize for VecMap<V>
|
impl<V> Deserialize for VecMap<V>
|
||||||
where V: Deserialize,
|
where V: Deserialize,
|
||||||
{
|
{
|
||||||
fn deserialize<D>(deserializer: &mut D) -> Result<VecMap<V>, D::Error>
|
fn deserialize<D>(deserializer: &mut D) -> Result<VecMap<V>, D::Error>
|
||||||
where D: Deserializer,
|
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))
|
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 {
|
pub trait Deserializer {
|
||||||
type Error: Error;
|
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>
|
fn visit<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where V: Visitor;
|
where V: Visitor;
|
||||||
|
|
||||||
/// The `visit_option` method allows a `Deserialize` type to inform the `Deserializer` that
|
/// This method hints that the `Deserialize` type is expecting a `bool` value.
|
||||||
/// it's expecting an optional value. This allows deserializers that encode an optional value
|
#[inline]
|
||||||
/// as a nullable value to convert the null value into a `None`, and a regular value as
|
fn visit_bool<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
/// `Some(value)`.
|
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]
|
#[inline]
|
||||||
fn visit_option<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
fn visit_option<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
@@ -44,9 +190,8 @@ pub trait Deserializer {
|
|||||||
self.visit(visitor)
|
self.visit(visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `visit_seq` method allows a `Deserialize` type to inform the `Deserializer` that it's
|
/// This method hints that the `Deserialize` type is expecting a sequence value. This allows
|
||||||
/// expecting a sequence of values. This allows deserializers to parse sequences that aren't
|
/// deserializers to parse sequences that aren't tagged as sequences.
|
||||||
/// tagged as sequences.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
@@ -54,9 +199,8 @@ pub trait Deserializer {
|
|||||||
self.visit(visitor)
|
self.visit(visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `visit_map` method allows a `Deserialize` type to inform the `Deserializer` that it's
|
/// This method hints that the `Deserialize` type is expecting a map of values. This allows
|
||||||
/// expecting a map of values. This allows deserializers to parse sequences that aren't tagged
|
/// deserializers to parse sequences that aren't tagged as maps.
|
||||||
/// as maps.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
@@ -64,9 +208,8 @@ pub trait Deserializer {
|
|||||||
self.visit(visitor)
|
self.visit(visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `visit_named_unit` method allows a `Deserialize` type to inform the `Deserializer` that
|
/// This method hints that the `Deserialize` type is expecting a named unit. This allows
|
||||||
/// it's expecting a named unit. This allows deserializers to a named unit that aren't tagged
|
/// deserializers to a named unit that aren't tagged as a named unit.
|
||||||
/// as a named unit.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_named_unit<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
|
fn visit_named_unit<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
@@ -74,9 +217,8 @@ pub trait Deserializer {
|
|||||||
self.visit(visitor)
|
self.visit(visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `visit_named_seq` method allows a `Deserialize` type to inform the `Deserializer` that
|
/// This method hints that the `Deserialize` type is expecting a named sequence.
|
||||||
/// it's expecting a named sequence of values. This allows deserializers to parse sequences
|
/// This allows deserializers to parse sequences that aren't tagged as sequences.
|
||||||
/// that aren't tagged as sequences.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_named_seq<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
|
fn visit_named_seq<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
@@ -84,9 +226,8 @@ pub trait Deserializer {
|
|||||||
self.visit_seq(visitor)
|
self.visit_seq(visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `visit_named_map` method allows a `Deserialize` type to inform the `Deserializer` that
|
/// This method hints that the `Deserialize` type is expecting a named map. This allows
|
||||||
/// it's expecting a map of values. This allows deserializers to parse sequences that aren't
|
/// deserializers to parse sequences that aren't tagged as maps.
|
||||||
/// tagged as maps.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_named_map<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
|
fn visit_named_map<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
@@ -94,9 +235,18 @@ pub trait Deserializer {
|
|||||||
self.visit_map(visitor)
|
self.visit_map(visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `visit_enum` method allows a `Deserialize` type to inform the `Deserializer` that it's
|
/// This method hints that the `Deserialize` type is expecting a tuple value. This allows
|
||||||
/// expecting an enum value. This allows deserializers that provide a custom enumeration
|
/// deserializers that provide a custom tuple serialization to properly deserialize the type.
|
||||||
/// 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]
|
#[inline]
|
||||||
fn visit_enum<V>(&mut self, _enum: &str, _visitor: V) -> Result<V::Value, Self::Error>
|
fn visit_enum<V>(&mut self, _enum: &str, _visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where V: EnumVisitor,
|
where V: EnumVisitor,
|
||||||
@@ -104,9 +254,9 @@ pub trait Deserializer {
|
|||||||
Err(Error::syntax_error())
|
Err(Error::syntax_error())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `visit_bytes` method allows a `Deserialize` type to inform the `Deserializer` that it's
|
/// This method hints that the `Deserialize` type is expecting a `Vec<u8>`. This allows
|
||||||
/// expecting a `Vec<u8>`. This allows deserializers that provide a custom byte vector
|
/// deserializers that provide a custom byte vector serialization to properly deserialize the
|
||||||
/// serialization to properly deserialize the type.
|
/// type.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_bytes<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
fn visit_bytes<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
|
|||||||
@@ -6,9 +6,16 @@
|
|||||||
//! leaving serde to perform roughly the same speed as a hand written serializer for a specific
|
//! leaving serde to perform roughly the same speed as a hand written serializer for a specific
|
||||||
//! type.
|
//! type.
|
||||||
#![doc(html_root_url="http://erickt.github.io/rust-serde")]
|
#![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;
|
extern crate num;
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
|
extern crate collections;
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
|
extern crate core;
|
||||||
|
|
||||||
pub use ser::{Serialize, Serializer};
|
pub use ser::{Serialize, Serializer};
|
||||||
pub use de::{Deserialize, Deserializer, Error};
|
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;
|
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::path;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
|
use core::nonzero::{NonZero, Zeroable};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
Serialize,
|
Serialize,
|
||||||
Serializer,
|
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,
|
where T: Serialize,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -177,12 +200,16 @@ array_impls!(30);
|
|||||||
array_impls!(31);
|
array_impls!(31);
|
||||||
array_impls!(32);
|
array_impls!(32);
|
||||||
|
|
||||||
impl<T> Serialize for Vec<T> where T: Serialize {
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
impl<T> Serialize for BinaryHeap<T>
|
||||||
|
where T: Serialize + Ord
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||||
where S: Serializer,
|
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>
|
impl<T> Serialize for HashSet<T>
|
||||||
where T: Serialize + Eq + Hash,
|
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 () {
|
impl Serialize for () {
|
||||||
@@ -257,7 +339,7 @@ macro_rules! tuple_impls {
|
|||||||
$(
|
$(
|
||||||
$state => {
|
$state => {
|
||||||
self.state += 1;
|
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]
|
#[inline]
|
||||||
fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
|
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>
|
impl<V> Serialize for VecMap<V>
|
||||||
where V: Serialize,
|
where V: Serialize,
|
||||||
{
|
{
|
||||||
@@ -469,7 +550,6 @@ impl<V> Serialize for VecMap<V>
|
|||||||
serializer.visit_map(MapIteratorVisitor::new(self.iter(), Some(self.len())))
|
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 {
|
impl Serialize for path::Path {
|
||||||
@@ -535,3 +713,10 @@ impl Serialize for path::PathBuf {
|
|||||||
self.to_str().unwrap().serialize(serializer)
|
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>
|
fn visit_seq<V>(&mut self, visitor: V) -> Result<(), Self::Error>
|
||||||
where V: SeqVisitor;
|
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]
|
#[inline]
|
||||||
fn visit_named_seq<V>(&mut self,
|
fn visit_named_seq<V>(&mut self,
|
||||||
_name: &'static str,
|
_name: &'static str,
|
||||||
visitor: V) -> Result<(), Self::Error>
|
visitor: V) -> Result<(), Self::Error>
|
||||||
where V: SeqVisitor,
|
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]
|
#[inline]
|
||||||
@@ -148,15 +172,23 @@ pub trait Serializer {
|
|||||||
visitor: V) -> Result<(), Self::Error>
|
visitor: V) -> Result<(), Self::Error>
|
||||||
where V: SeqVisitor,
|
where V: SeqVisitor,
|
||||||
{
|
{
|
||||||
self.visit_seq(visitor)
|
self.visit_tuple(visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_seq_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
|
#[inline]
|
||||||
where T: Serialize;
|
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>
|
fn visit_map<V>(&mut self, visitor: V) -> Result<(), Self::Error>
|
||||||
where V: MapVisitor;
|
where V: MapVisitor;
|
||||||
|
|
||||||
|
fn visit_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), Self::Error>
|
||||||
|
where K: Serialize,
|
||||||
|
V: Serialize;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_named_map<V>(&mut self,
|
fn visit_named_map<V>(&mut self,
|
||||||
_name: &'static str,
|
_name: &'static str,
|
||||||
@@ -167,18 +199,30 @@ pub trait Serializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_enum_map<V>(&mut self,
|
fn visit_named_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), Self::Error>
|
||||||
_name: &'static str,
|
where K: Serialize,
|
||||||
_variant: &'static str,
|
V: Serialize,
|
||||||
visitor: V) -> Result<(), Self::Error>
|
|
||||||
where V: MapVisitor,
|
|
||||||
{
|
{
|
||||||
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,
|
where K: Serialize,
|
||||||
V: Serialize;
|
V: Serialize,
|
||||||
|
{
|
||||||
|
self.visit_named_map_elt(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
/// Specify a format string for the serializer.
|
/// Specify a format string for the serializer.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_codegen"
|
name = "serde_codegen"
|
||||||
version = "0.4.1"
|
version = "0.4.3"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "Macros to auto-generate implementations for the serde framework"
|
description = "Macros to auto-generate implementations for the serde framework"
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ fn deserialize_tuple_struct(
|
|||||||
impl_generics,
|
impl_generics,
|
||||||
vec![deserializer_ty_param(builder)],
|
vec![deserializer_ty_param(builder)],
|
||||||
vec![deserializer_ty_arg(builder)],
|
vec![deserializer_ty_arg(builder)],
|
||||||
);
|
);
|
||||||
|
|
||||||
let visit_seq_expr = deserialize_seq(
|
let visit_seq_expr = deserialize_seq(
|
||||||
cx,
|
cx,
|
||||||
|
|||||||
+55
-28
@@ -55,7 +55,10 @@ pub fn expand_derive_serialize(
|
|||||||
&builder,
|
&builder,
|
||||||
&item,
|
&item,
|
||||||
&impl_generics,
|
&impl_generics,
|
||||||
ty.clone(),
|
builder.ty()
|
||||||
|
.ref_()
|
||||||
|
.lifetime("'__a")
|
||||||
|
.build_ty(ty.clone()),
|
||||||
);
|
);
|
||||||
|
|
||||||
let where_clause = &impl_generics.where_clause;
|
let where_clause = &impl_generics.where_clause;
|
||||||
@@ -98,6 +101,7 @@ fn serialize_body(
|
|||||||
builder,
|
builder,
|
||||||
item.ident,
|
item.ident,
|
||||||
impl_generics,
|
impl_generics,
|
||||||
|
ty,
|
||||||
enum_def,
|
enum_def,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -176,15 +180,11 @@ fn serialize_tuple_struct(
|
|||||||
ty: P<ast::Ty>,
|
ty: P<ast::Ty>,
|
||||||
fields: usize,
|
fields: usize,
|
||||||
) -> P<ast::Expr> {
|
) -> P<ast::Expr> {
|
||||||
let value_ty = builder.ty()
|
|
||||||
.ref_()
|
|
||||||
.lifetime("'__a")
|
|
||||||
.build_ty(ty);
|
|
||||||
|
|
||||||
let (visitor_struct, visitor_impl) = serialize_tuple_struct_visitor(
|
let (visitor_struct, visitor_impl) = serialize_tuple_struct_visitor(
|
||||||
cx,
|
cx,
|
||||||
builder,
|
builder,
|
||||||
value_ty,
|
ty.clone(),
|
||||||
|
ty,
|
||||||
fields,
|
fields,
|
||||||
impl_generics,
|
impl_generics,
|
||||||
);
|
);
|
||||||
@@ -197,6 +197,7 @@ fn serialize_tuple_struct(
|
|||||||
serializer.visit_named_seq($type_name, Visitor {
|
serializer.visit_named_seq($type_name, Visitor {
|
||||||
value: self,
|
value: self,
|
||||||
state: 0,
|
state: 0,
|
||||||
|
_structure_ty: ::std::marker::PhantomData,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -210,15 +211,11 @@ fn serialize_struct(
|
|||||||
struct_def: &StructDef,
|
struct_def: &StructDef,
|
||||||
fields: Vec<Ident>,
|
fields: Vec<Ident>,
|
||||||
) -> P<ast::Expr> {
|
) -> P<ast::Expr> {
|
||||||
let value_ty = builder.ty()
|
|
||||||
.ref_()
|
|
||||||
.lifetime("'__a")
|
|
||||||
.build_ty(ty.clone());
|
|
||||||
|
|
||||||
let (visitor_struct, visitor_impl) = serialize_struct_visitor(
|
let (visitor_struct, visitor_impl) = serialize_struct_visitor(
|
||||||
cx,
|
cx,
|
||||||
builder,
|
builder,
|
||||||
value_ty,
|
ty.clone(),
|
||||||
|
ty,
|
||||||
struct_def,
|
struct_def,
|
||||||
impl_generics,
|
impl_generics,
|
||||||
fields.iter().map(|field| quote_expr!(cx, &self.value.$field)),
|
fields.iter().map(|field| quote_expr!(cx, &self.value.$field)),
|
||||||
@@ -232,6 +229,7 @@ fn serialize_struct(
|
|||||||
serializer.visit_named_map($type_name, Visitor {
|
serializer.visit_named_map($type_name, Visitor {
|
||||||
value: self,
|
value: self,
|
||||||
state: 0,
|
state: 0,
|
||||||
|
_structure_ty: ::std::marker::PhantomData,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -241,6 +239,7 @@ fn serialize_item_enum(
|
|||||||
builder: &aster::AstBuilder,
|
builder: &aster::AstBuilder,
|
||||||
type_ident: Ident,
|
type_ident: Ident,
|
||||||
impl_generics: &ast::Generics,
|
impl_generics: &ast::Generics,
|
||||||
|
ty: P<ast::Ty>,
|
||||||
enum_def: &ast::EnumDef,
|
enum_def: &ast::EnumDef,
|
||||||
) -> P<ast::Expr> {
|
) -> P<ast::Expr> {
|
||||||
let arms: Vec<ast::Arm> = enum_def.variants.iter()
|
let arms: Vec<ast::Arm> = enum_def.variants.iter()
|
||||||
@@ -250,6 +249,7 @@ fn serialize_item_enum(
|
|||||||
builder,
|
builder,
|
||||||
type_ident,
|
type_ident,
|
||||||
impl_generics,
|
impl_generics,
|
||||||
|
ty.clone(),
|
||||||
variant,
|
variant,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -267,6 +267,7 @@ fn serialize_variant(
|
|||||||
builder: &aster::AstBuilder,
|
builder: &aster::AstBuilder,
|
||||||
type_ident: Ident,
|
type_ident: Ident,
|
||||||
generics: &ast::Generics,
|
generics: &ast::Generics,
|
||||||
|
ty: P<ast::Ty>,
|
||||||
variant: &ast::Variant,
|
variant: &ast::Variant,
|
||||||
) -> ast::Arm {
|
) -> ast::Arm {
|
||||||
let type_name = builder.expr().str(type_ident);
|
let type_name = builder.expr().str(type_ident);
|
||||||
@@ -305,6 +306,7 @@ fn serialize_variant(
|
|||||||
type_name,
|
type_name,
|
||||||
variant_name,
|
variant_name,
|
||||||
generics,
|
generics,
|
||||||
|
ty,
|
||||||
args,
|
args,
|
||||||
fields,
|
fields,
|
||||||
);
|
);
|
||||||
@@ -340,6 +342,7 @@ fn serialize_variant(
|
|||||||
type_name,
|
type_name,
|
||||||
variant_name,
|
variant_name,
|
||||||
generics,
|
generics,
|
||||||
|
ty,
|
||||||
struct_def,
|
struct_def,
|
||||||
fields,
|
fields,
|
||||||
);
|
);
|
||||||
@@ -355,10 +358,11 @@ fn serialize_tuple_variant(
|
|||||||
type_name: P<ast::Expr>,
|
type_name: P<ast::Expr>,
|
||||||
variant_name: P<ast::Expr>,
|
variant_name: P<ast::Expr>,
|
||||||
generics: &ast::Generics,
|
generics: &ast::Generics,
|
||||||
|
structure_ty: P<ast::Ty>,
|
||||||
args: &[ast::VariantArg],
|
args: &[ast::VariantArg],
|
||||||
fields: Vec<Ident>,
|
fields: Vec<Ident>,
|
||||||
) -> P<ast::Expr> {
|
) -> P<ast::Expr> {
|
||||||
let value_ty = builder.ty().tuple()
|
let variant_ty = builder.ty().tuple()
|
||||||
.with_tys(
|
.with_tys(
|
||||||
args.iter().map(|arg| {
|
args.iter().map(|arg| {
|
||||||
builder.ty()
|
builder.ty()
|
||||||
@@ -369,6 +373,15 @@ fn serialize_tuple_variant(
|
|||||||
)
|
)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
let (visitor_struct, visitor_impl) = serialize_tuple_struct_visitor(
|
||||||
|
cx,
|
||||||
|
builder,
|
||||||
|
structure_ty,
|
||||||
|
variant_ty,
|
||||||
|
args.len(),
|
||||||
|
generics,
|
||||||
|
);
|
||||||
|
|
||||||
let value_expr = builder.expr().tuple()
|
let value_expr = builder.expr().tuple()
|
||||||
.with_exprs(
|
.with_exprs(
|
||||||
fields.iter().map(|field| {
|
fields.iter().map(|field| {
|
||||||
@@ -379,20 +392,13 @@ fn serialize_tuple_variant(
|
|||||||
)
|
)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let (visitor_struct, visitor_impl) = serialize_tuple_struct_visitor(
|
|
||||||
cx,
|
|
||||||
builder,
|
|
||||||
value_ty,
|
|
||||||
args.len(),
|
|
||||||
generics,
|
|
||||||
);
|
|
||||||
|
|
||||||
quote_expr!(cx, {
|
quote_expr!(cx, {
|
||||||
$visitor_struct
|
$visitor_struct
|
||||||
$visitor_impl
|
$visitor_impl
|
||||||
serializer.visit_enum_seq($type_name, $variant_name, Visitor {
|
serializer.visit_enum_seq($type_name, $variant_name, Visitor {
|
||||||
value: $value_expr,
|
value: $value_expr,
|
||||||
state: 0,
|
state: 0,
|
||||||
|
_structure_ty: ::std::marker::PhantomData,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -403,6 +409,7 @@ fn serialize_struct_variant(
|
|||||||
type_name: P<ast::Expr>,
|
type_name: P<ast::Expr>,
|
||||||
variant_name: P<ast::Expr>,
|
variant_name: P<ast::Expr>,
|
||||||
generics: &ast::Generics,
|
generics: &ast::Generics,
|
||||||
|
structure_ty: P<ast::Ty>,
|
||||||
struct_def: &ast::StructDef,
|
struct_def: &ast::StructDef,
|
||||||
fields: Vec<Ident>,
|
fields: Vec<Ident>,
|
||||||
) -> P<ast::Expr> {
|
) -> P<ast::Expr> {
|
||||||
@@ -430,6 +437,7 @@ fn serialize_struct_variant(
|
|||||||
let (visitor_struct, visitor_impl) = serialize_struct_visitor(
|
let (visitor_struct, visitor_impl) = serialize_struct_visitor(
|
||||||
cx,
|
cx,
|
||||||
builder,
|
builder,
|
||||||
|
structure_ty,
|
||||||
value_ty,
|
value_ty,
|
||||||
struct_def,
|
struct_def,
|
||||||
generics,
|
generics,
|
||||||
@@ -446,6 +454,7 @@ fn serialize_struct_variant(
|
|||||||
serializer.visit_enum_map($type_name, $variant_name, Visitor {
|
serializer.visit_enum_map($type_name, $variant_name, Visitor {
|
||||||
value: $value_expr,
|
value: $value_expr,
|
||||||
state: 0,
|
state: 0,
|
||||||
|
_structure_ty: ::std::marker::PhantomData,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -453,7 +462,8 @@ fn serialize_struct_variant(
|
|||||||
fn serialize_tuple_struct_visitor(
|
fn serialize_tuple_struct_visitor(
|
||||||
cx: &ExtCtxt,
|
cx: &ExtCtxt,
|
||||||
builder: &aster::AstBuilder,
|
builder: &aster::AstBuilder,
|
||||||
value_ty: P<ast::Ty>,
|
structure_ty: P<ast::Ty>,
|
||||||
|
variant_ty: P<ast::Ty>,
|
||||||
fields: usize,
|
fields: usize,
|
||||||
generics: &ast::Generics
|
generics: &ast::Generics
|
||||||
) -> (P<ast::Item>, P<ast::Item>) {
|
) -> (P<ast::Item>, P<ast::Item>) {
|
||||||
@@ -466,7 +476,7 @@ fn serialize_tuple_struct_visitor(
|
|||||||
quote_arm!(cx,
|
quote_arm!(cx,
|
||||||
$i => {
|
$i => {
|
||||||
self.state += 1;
|
self.state += 1;
|
||||||
let v = try!(serializer.visit_seq_elt(&$expr));
|
let v = try!(serializer.visit_named_seq_elt(&$expr));
|
||||||
Ok(Some(v))
|
Ok(Some(v))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -484,11 +494,19 @@ fn serialize_tuple_struct_visitor(
|
|||||||
.strip_bounds()
|
.strip_bounds()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
// Variants don't necessarily reference all generic lifetimes and type parameters,
|
||||||
|
// so to avoid a compilation failure, we'll just add a phantom type to capture these
|
||||||
|
// unused values.
|
||||||
|
let structure_ty = builder.ty()
|
||||||
|
.phantom_data()
|
||||||
|
.build(structure_ty);
|
||||||
|
|
||||||
(
|
(
|
||||||
quote_item!(cx,
|
quote_item!(cx,
|
||||||
struct Visitor $visitor_impl_generics $where_clause {
|
struct Visitor $visitor_impl_generics $where_clause {
|
||||||
state: usize,
|
state: usize,
|
||||||
value: $value_ty,
|
value: $variant_ty,
|
||||||
|
_structure_ty: $structure_ty,
|
||||||
}
|
}
|
||||||
).unwrap(),
|
).unwrap(),
|
||||||
|
|
||||||
@@ -518,7 +536,8 @@ fn serialize_tuple_struct_visitor(
|
|||||||
fn serialize_struct_visitor<I>(
|
fn serialize_struct_visitor<I>(
|
||||||
cx: &ExtCtxt,
|
cx: &ExtCtxt,
|
||||||
builder: &aster::AstBuilder,
|
builder: &aster::AstBuilder,
|
||||||
value_ty: P<ast::Ty>,
|
structure_ty: P<ast::Ty>,
|
||||||
|
variant_ty: P<ast::Ty>,
|
||||||
struct_def: &StructDef,
|
struct_def: &StructDef,
|
||||||
generics: &ast::Generics,
|
generics: &ast::Generics,
|
||||||
value_exprs: I,
|
value_exprs: I,
|
||||||
@@ -540,7 +559,7 @@ fn serialize_struct_visitor<I>(
|
|||||||
Ok(
|
Ok(
|
||||||
Some(
|
Some(
|
||||||
try!(
|
try!(
|
||||||
serializer.visit_map_elt(
|
serializer.visit_named_map_elt(
|
||||||
$key_expr,
|
$key_expr,
|
||||||
$value_expr,
|
$value_expr,
|
||||||
)
|
)
|
||||||
@@ -563,11 +582,19 @@ fn serialize_struct_visitor<I>(
|
|||||||
.strip_bounds()
|
.strip_bounds()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
// Variants don't necessarily reference all generic lifetimes and type parameters,
|
||||||
|
// so to avoid a compilation failure, we'll just add a phantom type to capture these
|
||||||
|
// unused values.
|
||||||
|
let structure_ty = builder.ty()
|
||||||
|
.phantom_data()
|
||||||
|
.build(structure_ty);
|
||||||
|
|
||||||
(
|
(
|
||||||
quote_item!(cx,
|
quote_item!(cx,
|
||||||
struct Visitor $visitor_impl_generics $where_clause {
|
struct Visitor $visitor_impl_generics $where_clause {
|
||||||
state: usize,
|
state: usize,
|
||||||
value: $value_ty,
|
value: $variant_ty,
|
||||||
|
_structure_ty: $structure_ty,
|
||||||
}
|
}
|
||||||
).unwrap(),
|
).unwrap(),
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_macros"
|
name = "serde_macros"
|
||||||
version = "0.4.1"
|
version = "0.4.3"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "Macros to auto-generate implementations for the serde framework"
|
description = "Macros to auto-generate implementations for the serde framework"
|
||||||
@@ -10,6 +10,9 @@ repository = "https://github.com/erickt/rust-serde"
|
|||||||
name = "serde_macros"
|
name = "serde_macros"
|
||||||
plugin = true
|
plugin = true
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["serde/nightly"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde_codegen = { version = "*", path = "../serde_codegen", default-features = false, features = ["nightly"] }
|
serde_codegen = { version = "*", path = "../serde_codegen", default-features = false, features = ["nightly"] }
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_tests"
|
name = "serde_tests"
|
||||||
version = "0.4.1"
|
version = "0.4.3"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "A generic serialization/deserialization framework"
|
description = "A generic serialization/deserialization framework"
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ impl rustc_serialize::Decodable for HttpProtocol {
|
|||||||
|
|
||||||
impl FromStr for HttpProtocol {
|
impl FromStr for HttpProtocol {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
fn from_str(s: &str) -> Result<HttpProtocol, ()> { unimplemented!() }
|
fn from_str(_s: &str) -> Result<HttpProtocol, ()> { unimplemented!() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromPrimitive for HttpProtocol {
|
impl FromPrimitive for HttpProtocol {
|
||||||
@@ -104,7 +104,7 @@ enum HttpMethod {
|
|||||||
|
|
||||||
impl FromStr for HttpMethod {
|
impl FromStr for HttpMethod {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
fn from_str(s: &str) -> Result<HttpMethod, ()> { unimplemented!() }
|
fn from_str(_s: &str) -> Result<HttpMethod, ()> { unimplemented!() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromPrimitive for HttpMethod {
|
impl FromPrimitive for HttpMethod {
|
||||||
@@ -174,7 +174,7 @@ enum CacheStatus {
|
|||||||
|
|
||||||
impl FromStr for CacheStatus {
|
impl FromStr for CacheStatus {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
fn from_str(s: &str) -> Result<CacheStatus, ()> { unimplemented!() }
|
fn from_str(_s: &str) -> Result<CacheStatus, ()> { unimplemented!() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromPrimitive for CacheStatus {
|
impl FromPrimitive for CacheStatus {
|
||||||
@@ -244,7 +244,7 @@ enum OriginProtocol {
|
|||||||
|
|
||||||
impl FromStr for OriginProtocol {
|
impl FromStr for OriginProtocol {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
fn from_str(s: &str) -> Result<OriginProtocol, ()> { unimplemented!() }
|
fn from_str(_s: &str) -> Result<OriginProtocol, ()> { unimplemented!() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromPrimitive for OriginProtocol {
|
impl FromPrimitive for OriginProtocol {
|
||||||
@@ -307,7 +307,7 @@ enum ZonePlan {
|
|||||||
|
|
||||||
impl FromStr for ZonePlan {
|
impl FromStr for ZonePlan {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
fn from_str(s: &str) -> Result<ZonePlan, ()> { unimplemented!() }
|
fn from_str(_s: &str) -> Result<ZonePlan, ()> { unimplemented!() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromPrimitive for ZonePlan {
|
impl FromPrimitive for ZonePlan {
|
||||||
@@ -622,7 +622,7 @@ enum Country {
|
|||||||
|
|
||||||
impl FromStr for Country {
|
impl FromStr for Country {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
fn from_str(s: &str) -> Result<Country, ()> { unimplemented!() }
|
fn from_str(_s: &str) -> Result<Country, ()> { unimplemented!() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromPrimitive for Country {
|
impl FromPrimitive for Country {
|
||||||
|
|||||||
@@ -123,6 +123,14 @@ enum DeEnum<B, C: /* Trait */, D> /* where D: Trait */ {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
enum Lifetimes<'a> {
|
||||||
|
LifetimeSeq(&'a i32),
|
||||||
|
NoLifetimeSeq(i32),
|
||||||
|
LifetimeMap { a: &'a i32 },
|
||||||
|
NoLifetimeMap { a: i32 },
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_named_unit() {
|
fn test_named_unit() {
|
||||||
let named_unit = NamedUnit;
|
let named_unit = NamedUnit;
|
||||||
@@ -438,3 +446,32 @@ fn test_de_enum_map() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_lifetimes() {
|
||||||
|
let value = 5;
|
||||||
|
let lifetime = Lifetimes::LifetimeSeq(&value);
|
||||||
|
assert_eq!(
|
||||||
|
json::to_string(&lifetime).unwrap(),
|
||||||
|
"{\"LifetimeSeq\":[5]}"
|
||||||
|
);
|
||||||
|
|
||||||
|
let lifetime = Lifetimes::NoLifetimeSeq(5);
|
||||||
|
assert_eq!(
|
||||||
|
json::to_string(&lifetime).unwrap(),
|
||||||
|
"{\"NoLifetimeSeq\":[5]}"
|
||||||
|
);
|
||||||
|
|
||||||
|
let value = 5;
|
||||||
|
let lifetime = Lifetimes::LifetimeMap { a: &value };
|
||||||
|
assert_eq!(
|
||||||
|
json::to_string(&lifetime).unwrap(),
|
||||||
|
"{\"LifetimeMap\":{\"a\":5}}"
|
||||||
|
);
|
||||||
|
|
||||||
|
let lifetime = Lifetimes::NoLifetimeMap { a: 5 };
|
||||||
|
assert_eq!(
|
||||||
|
json::to_string(&lifetime).unwrap(),
|
||||||
|
"{\"NoLifetimeMap\":{\"a\":5}}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user