mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-23 08:18:03 +00:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9acb17ab54 | |||
| f15ff1868e | |||
| 86f0d0382f | |||
| 8595b25763 | |||
| 49aca521f1 | |||
| 4c38bd0180 | |||
| 02c4ff7b7e | |||
| a8d1c0253a | |||
| bb5370b746 | |||
| 536e78a146 | |||
| 21c9446890 | |||
| 1b42f3f594 | |||
| cafa02d9b4 | |||
| a9b6cbb8b3 | |||
| 1d719b542c | |||
| 532b950971 | |||
| f93b4e91e6 | |||
| 94e2ccc94e | |||
| cbe6b4c97c | |||
| a46a4e27dd | |||
| 4919a3184d | |||
| 0b19608d85 | |||
| 99bddddd8e | |||
| 85c95040b3 | |||
| 339c0f5493 | |||
| b4d5c26f4e | |||
| f4e1ffa2cb | |||
| ef5d09e144 | |||
| e547a06639 |
+3
-11
@@ -1,17 +1,11 @@
|
||||
sudo: false
|
||||
language: rust
|
||||
rust:
|
||||
- 1.10.0
|
||||
- 1.11.0
|
||||
- stable
|
||||
- nightly
|
||||
- 1.8.0
|
||||
- 1.9.0
|
||||
- beta
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libcurl4-openssl-dev
|
||||
- libelf-dev
|
||||
- libdw-dev
|
||||
- nightly
|
||||
before_script:
|
||||
- pip install 'travis-cargo<0.2' --user
|
||||
- export PATH=$HOME/.local/bin:$PATH
|
||||
@@ -28,8 +22,6 @@ script:
|
||||
- (cd examples/serde-syntex-example && travis-cargo --skip nightly run)
|
||||
- (cd examples/serde-syntex-example && travis-cargo --only nightly run -- --no-default-features --features unstable)
|
||||
- (cd serde && travis-cargo --only stable doc)
|
||||
after_success:
|
||||
- (cd testing && travis-cargo --only stable coveralls --no-sudo)
|
||||
env:
|
||||
global:
|
||||
- TRAVIS_CARGO_NIGHTLY_FEATURE=""
|
||||
|
||||
@@ -15,7 +15,7 @@ You may be looking for:
|
||||
## Serde in action
|
||||
|
||||
```rust
|
||||
#![feature(rustc_macro)]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![cfg_attr(feature = "serde_derive", feature(rustc_macro))]
|
||||
#![cfg_attr(feature = "serde_derive", feature(proc_macro))]
|
||||
|
||||
#[cfg(feature = "serde_derive")]
|
||||
#[macro_use]
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde"
|
||||
version = "0.8.11"
|
||||
version = "0.8.15"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "A generic serialization/deserialization framework"
|
||||
|
||||
+69
-98
@@ -512,27 +512,26 @@ seq_impl!(
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct ArrayVisitor0<T> {
|
||||
marker: PhantomData<T>,
|
||||
struct ArrayVisitor<A> {
|
||||
marker: PhantomData<A>,
|
||||
}
|
||||
|
||||
impl<T> ArrayVisitor0<T> {
|
||||
/// Construct a `ArrayVisitor0<T>`.
|
||||
impl<A> ArrayVisitor<A> {
|
||||
pub fn new() -> Self {
|
||||
ArrayVisitor0 {
|
||||
ArrayVisitor {
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Visitor for ArrayVisitor0<T> where T: Deserialize + Default {
|
||||
impl<T> Visitor for ArrayVisitor<[T; 0]> where T: Deserialize {
|
||||
type Value = [T; 0];
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(&mut self) -> Result<[T; 0], E>
|
||||
where E: Error,
|
||||
{
|
||||
Ok([T::default(); 0])
|
||||
Ok([])
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -540,37 +539,24 @@ impl<T> Visitor for ArrayVisitor0<T> where T: Deserialize + Default {
|
||||
where V: SeqVisitor,
|
||||
{
|
||||
try!(visitor.end());
|
||||
Ok([T::default(); 0])
|
||||
Ok([])
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deserialize for [T; 0]
|
||||
where T: Deserialize + Default
|
||||
where T: Deserialize
|
||||
{
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<[T; 0], D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.deserialize_seq(ArrayVisitor0::new())
|
||||
deserializer.deserialize_seq_fixed_size(0, ArrayVisitor::<[T; 0]>::new())
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! array_impls {
|
||||
($($visitor:ident, $len:expr => ($($name:ident),+),)+) => {
|
||||
($($len:expr => ($($name:ident)+))+) => {
|
||||
$(
|
||||
struct $visitor<T> {
|
||||
marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> $visitor<T> {
|
||||
/// Construct a `ArrayVisitor*<T>`.
|
||||
pub fn new() -> Self {
|
||||
$visitor {
|
||||
marker: PhantomData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Visitor for $visitor<T> where T: Deserialize {
|
||||
impl<T> Visitor for ArrayVisitor<[T; $len]> where T: Deserialize {
|
||||
type Value = [T; $len];
|
||||
|
||||
#[inline]
|
||||
@@ -580,13 +566,13 @@ macro_rules! array_impls {
|
||||
$(
|
||||
let $name = match try!(visitor.visit()) {
|
||||
Some(val) => val,
|
||||
None => { return Err(Error::end_of_stream()); }
|
||||
None => return Err(Error::end_of_stream()),
|
||||
};
|
||||
)+;
|
||||
)+
|
||||
|
||||
try!(visitor.end());
|
||||
|
||||
Ok([$($name,)+])
|
||||
Ok([$($name),+])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -596,7 +582,7 @@ macro_rules! array_impls {
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<[T; $len], D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.deserialize_seq_fixed_size($len, $visitor::new())
|
||||
deserializer.deserialize_seq_fixed_size($len, ArrayVisitor::<[T; $len]>::new())
|
||||
}
|
||||
}
|
||||
)+
|
||||
@@ -604,71 +590,58 @@ macro_rules! array_impls {
|
||||
}
|
||||
|
||||
array_impls! {
|
||||
ArrayVisitor1, 1 => (a),
|
||||
ArrayVisitor2, 2 => (a, b),
|
||||
ArrayVisitor3, 3 => (a, b, c),
|
||||
ArrayVisitor4, 4 => (a, b, c, d),
|
||||
ArrayVisitor5, 5 => (a, b, c, d, e),
|
||||
ArrayVisitor6, 6 => (a, b, c, d, e, f),
|
||||
ArrayVisitor7, 7 => (a, b, c, d, e, f, g),
|
||||
ArrayVisitor8, 8 => (a, b, c, d, e, f, g, h),
|
||||
ArrayVisitor9, 9 => (a, b, c, d, e, f, g, h, i),
|
||||
ArrayVisitor10, 10 => (a, b, c, d, e, f, g, h, i, j),
|
||||
ArrayVisitor11, 11 => (a, b, c, d, e, f, g, h, i, j, k),
|
||||
ArrayVisitor12, 12 => (a, b, c, d, e, f, g, h, i, j, k, l),
|
||||
ArrayVisitor13, 13 => (a, b, c, d, e, f, g, h, i, j, k, l, m),
|
||||
ArrayVisitor14, 14 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n),
|
||||
ArrayVisitor15, 15 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o),
|
||||
ArrayVisitor16, 16 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p),
|
||||
ArrayVisitor17, 17 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q),
|
||||
ArrayVisitor18, 18 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r),
|
||||
ArrayVisitor19, 19 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s),
|
||||
ArrayVisitor20, 20 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s ,t),
|
||||
ArrayVisitor21, 21 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u),
|
||||
ArrayVisitor22, 22 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v),
|
||||
ArrayVisitor23, 23 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w),
|
||||
ArrayVisitor24, 24 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x),
|
||||
ArrayVisitor25, 25 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x,
|
||||
y),
|
||||
ArrayVisitor26, 26 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x,
|
||||
y, z),
|
||||
ArrayVisitor27, 27 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x,
|
||||
y, z, aa),
|
||||
ArrayVisitor28, 28 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x,
|
||||
y, z, aa, ab),
|
||||
ArrayVisitor29, 29 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x,
|
||||
y, z, aa, ab, ac),
|
||||
ArrayVisitor30, 30 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x,
|
||||
y, z, aa, ab, ac, ad),
|
||||
ArrayVisitor31, 31 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x,
|
||||
y, z, aa, ab, ac, ad, ae),
|
||||
ArrayVisitor32, 32 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x,
|
||||
y, z, aa, ab, ac, ad, ae, af),
|
||||
1 => (a)
|
||||
2 => (a b)
|
||||
3 => (a b c)
|
||||
4 => (a b c d)
|
||||
5 => (a b c d e)
|
||||
6 => (a b c d e f)
|
||||
7 => (a b c d e f g)
|
||||
8 => (a b c d e f g h)
|
||||
9 => (a b c d e f g h i)
|
||||
10 => (a b c d e f g h i j)
|
||||
11 => (a b c d e f g h i j k)
|
||||
12 => (a b c d e f g h i j k l)
|
||||
13 => (a b c d e f g h i j k l m)
|
||||
14 => (a b c d e f g h i j k l m n)
|
||||
15 => (a b c d e f g h i j k l m n o)
|
||||
16 => (a b c d e f g h i j k l m n o p)
|
||||
17 => (a b c d e f g h i j k l m n o p q)
|
||||
18 => (a b c d e f g h i j k l m n o p q r)
|
||||
19 => (a b c d e f g h i j k l m n o p q r s)
|
||||
20 => (a b c d e f g h i j k l m n o p q r s t)
|
||||
21 => (a b c d e f g h i j k l m n o p q r s t u)
|
||||
22 => (a b c d e f g h i j k l m n o p q r s t u v)
|
||||
23 => (a b c d e f g h i j k l m n o p q r s t u v w)
|
||||
24 => (a b c d e f g h i j k l m n o p q r s t u v w x)
|
||||
25 => (a b c d e f g h i j k l m n o p q r s t u v w x y)
|
||||
26 => (a b c d e f g h i j k l m n o p q r s t u v w x y z)
|
||||
27 => (a b c d e f g h i j k l m n o p q r s t u v w x y z aa)
|
||||
28 => (a b c d e f g h i j k l m n o p q r s t u v w x y z aa ab)
|
||||
29 => (a b c d e f g h i j k l m n o p q r s t u v w x y z aa ab ac)
|
||||
30 => (a b c d e f g h i j k l m n o p q r s t u v w x y z aa ab ac ad)
|
||||
31 => (a b c d e f g h i j k l m n o p q r s t u v w x y z aa ab ac ad ae)
|
||||
32 => (a b c d e f g h i j k l m n o p q r s t u v w x y z aa ab ac ad ae af)
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
macro_rules! tuple_impls {
|
||||
($($len:expr => $visitor:ident => ($($name:ident),+),)+) => {
|
||||
($($len:expr => $visitor:ident => ($($name:ident)+))+) => {
|
||||
$(
|
||||
/// Construct a tuple visitor.
|
||||
pub struct $visitor<$($name,)+> {
|
||||
marker: PhantomData<($($name,)+)>,
|
||||
}
|
||||
|
||||
impl<
|
||||
$($name: Deserialize,)+
|
||||
> $visitor<$($name,)+> {
|
||||
impl<$($name: Deserialize,)+> $visitor<$($name,)+> {
|
||||
/// Construct a `TupleVisitor*<T>`.
|
||||
pub fn new() -> Self {
|
||||
$visitor { marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<
|
||||
$($name: Deserialize,)+
|
||||
> Visitor for $visitor<$($name,)+> {
|
||||
impl<$($name: Deserialize),+> Visitor for $visitor<$($name,)+> {
|
||||
type Value = ($($name,)+);
|
||||
|
||||
#[inline]
|
||||
@@ -679,9 +652,9 @@ macro_rules! tuple_impls {
|
||||
$(
|
||||
let $name = match try!(visitor.visit()) {
|
||||
Some(value) => value,
|
||||
None => { return Err(Error::end_of_stream()); }
|
||||
None => return Err(Error::end_of_stream()),
|
||||
};
|
||||
)+;
|
||||
)+
|
||||
|
||||
try!(visitor.end());
|
||||
|
||||
@@ -689,9 +662,7 @@ macro_rules! tuple_impls {
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
$($name: Deserialize),+
|
||||
> Deserialize for ($($name,)+) {
|
||||
impl<$($name: Deserialize),+> Deserialize for ($($name,)+) {
|
||||
#[inline]
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<($($name,)+), D::Error>
|
||||
where D: Deserializer,
|
||||
@@ -704,22 +675,22 @@ macro_rules! tuple_impls {
|
||||
}
|
||||
|
||||
tuple_impls! {
|
||||
1 => TupleVisitor1 => (T0),
|
||||
2 => TupleVisitor2 => (T0, T1),
|
||||
3 => TupleVisitor3 => (T0, T1, T2),
|
||||
4 => TupleVisitor4 => (T0, T1, T2, T3),
|
||||
5 => TupleVisitor5 => (T0, T1, T2, T3, T4),
|
||||
6 => TupleVisitor6 => (T0, T1, T2, T3, T4, T5),
|
||||
7 => TupleVisitor7 => (T0, T1, T2, T3, T4, T5, T6),
|
||||
8 => TupleVisitor8 => (T0, T1, T2, T3, T4, T5, T6, T7),
|
||||
9 => TupleVisitor9 => (T0, T1, T2, T3, T4, T5, T6, T7, T8),
|
||||
10 => TupleVisitor10 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9),
|
||||
11 => TupleVisitor11 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10),
|
||||
12 => TupleVisitor12 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11),
|
||||
13 => TupleVisitor13 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12),
|
||||
14 => TupleVisitor14 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13),
|
||||
15 => TupleVisitor15 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14),
|
||||
16 => TupleVisitor16 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15),
|
||||
1 => TupleVisitor1 => (T0)
|
||||
2 => TupleVisitor2 => (T0 T1)
|
||||
3 => TupleVisitor3 => (T0 T1 T2)
|
||||
4 => TupleVisitor4 => (T0 T1 T2 T3)
|
||||
5 => TupleVisitor5 => (T0 T1 T2 T3 T4)
|
||||
6 => TupleVisitor6 => (T0 T1 T2 T3 T4 T5)
|
||||
7 => TupleVisitor7 => (T0 T1 T2 T3 T4 T5 T6)
|
||||
8 => TupleVisitor8 => (T0 T1 T2 T3 T4 T5 T6 T7)
|
||||
9 => TupleVisitor9 => (T0 T1 T2 T3 T4 T5 T6 T7 T8)
|
||||
10 => TupleVisitor10 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9)
|
||||
11 => TupleVisitor11 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10)
|
||||
12 => TupleVisitor12 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11)
|
||||
13 => TupleVisitor13 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12)
|
||||
14 => TupleVisitor14 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13)
|
||||
15 => TupleVisitor15 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14)
|
||||
16 => TupleVisitor16 => (T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15)
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -313,11 +313,6 @@ impl Serialize for () {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FIXME(rust #19630) Remove this work-around
|
||||
macro_rules! e {
|
||||
($e:expr) => { $e }
|
||||
}
|
||||
|
||||
macro_rules! tuple_impls {
|
||||
($(
|
||||
$TupleVisitor:ident ($len:expr, $($T:ident),+) {
|
||||
@@ -334,7 +329,7 @@ macro_rules! tuple_impls {
|
||||
{
|
||||
let mut state = try!(serializer.serialize_tuple($len));
|
||||
$(
|
||||
try!(serializer.serialize_tuple_elt(&mut state, &e!(self.$idx)));
|
||||
try!(serializer.serialize_tuple_elt(&mut state, &self.$idx));
|
||||
)+
|
||||
serializer.serialize_tuple_end(state)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_codegen"
|
||||
version = "0.8.11"
|
||||
version = "0.8.15"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "Macros to auto-generate implementations for the serde framework"
|
||||
@@ -22,8 +22,9 @@ with-syn = []
|
||||
|
||||
[dependencies]
|
||||
clippy = { version = "^0.*", optional = true }
|
||||
quote = "0.2"
|
||||
serde_codegen_internals = { version = "=0.9.0", default-features = false, path = "../serde_codegen_internals" }
|
||||
syn = { version = "0.8", features = ["aster", "visit"] }
|
||||
syntex = { version = "^0.44.0", optional = true }
|
||||
syntex_syntax = { version = "^0.44.0", optional = true }
|
||||
post-expansion = "0.1.0"
|
||||
quote = "0.3"
|
||||
serde_codegen_internals = { version = "=0.10.0", default-features = false, path = "../serde_codegen_internals" }
|
||||
syn = { version = "0.9", features = ["aster", "visit"] }
|
||||
syntex = { version = "^0.45.0", optional = true }
|
||||
syntex_syntax = { version = "^0.45.0", optional = true }
|
||||
|
||||
+20
-27
@@ -185,17 +185,17 @@ fn deserialize_visitor(generics: &syn::Generics) -> (Tokens, Tokens, Tokens) {
|
||||
let ty_param_idents = if ty_param_idents.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(quote!(::<#(ty_param_idents),*>))
|
||||
Some(quote!(::<#(#ty_param_idents),*>))
|
||||
};
|
||||
|
||||
let phantom_exprs = iter::repeat(quote!(::std::marker::PhantomData)).take(num_phantoms);
|
||||
|
||||
(
|
||||
quote! {
|
||||
struct __Visitor #generics ( #(phantom_types),* ) #where_clause;
|
||||
struct __Visitor #generics ( #(#phantom_types),* ) #where_clause;
|
||||
},
|
||||
quote!(__Visitor <#(all_params),*> ),
|
||||
quote!(__Visitor #ty_param_idents ( #(phantom_exprs),* )),
|
||||
quote!(__Visitor <#(#all_params),*> ),
|
||||
quote!(__Visitor #ty_param_idents ( #(#phantom_exprs),* )),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -358,17 +358,17 @@ fn deserialize_seq(
|
||||
quote!(#ident: #value)
|
||||
});
|
||||
quote! {
|
||||
#type_path { #(args),* }
|
||||
#type_path { #(#args),* }
|
||||
}
|
||||
} else {
|
||||
let args = (0..fields.len()).map(|i| aster::id(format!("__field{}", i)));
|
||||
quote! {
|
||||
#type_path ( #(args),* )
|
||||
#type_path ( #(#args),* )
|
||||
}
|
||||
};
|
||||
|
||||
quote! {
|
||||
#(let_values)*
|
||||
#(#let_values)*
|
||||
|
||||
try!(visitor.end());
|
||||
|
||||
@@ -505,7 +505,7 @@ fn deserialize_item_enum(
|
||||
let variant_names = variants.iter().map(|variant| variant.ident.to_string());
|
||||
|
||||
let variants_stmt = quote! {
|
||||
const VARIANTS: &'static [&'static str] = &[ #(variant_names),* ];
|
||||
const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
|
||||
};
|
||||
|
||||
let ignored_arm = if item_attrs.deny_unknown_fields() {
|
||||
@@ -551,7 +551,7 @@ fn deserialize_item_enum(
|
||||
where __V: _serde::de::VariantVisitor,
|
||||
{
|
||||
match try!(visitor.visit_variant()) {
|
||||
#(variant_arms)*
|
||||
#(#variant_arms)*
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -678,7 +678,7 @@ fn deserialize_field_visitor(
|
||||
|
||||
let index_body = quote! {
|
||||
match value {
|
||||
#(index_field_arms)*
|
||||
#(#index_field_arms)*
|
||||
_ => #fallthrough_index_arm_expr
|
||||
}
|
||||
};
|
||||
@@ -704,7 +704,7 @@ fn deserialize_field_visitor(
|
||||
|
||||
let str_body = quote! {
|
||||
match value {
|
||||
#(str_field_arms)*
|
||||
#(#str_field_arms)*
|
||||
_ => #fallthrough_str_arm_expr
|
||||
}
|
||||
};
|
||||
@@ -732,20 +732,18 @@ fn deserialize_field_visitor(
|
||||
|
||||
let bytes_body = quote! {
|
||||
match value {
|
||||
#(bytes_field_arms)*
|
||||
#(#bytes_field_arms)*
|
||||
_ => #fallthrough_bytes_arm_expr
|
||||
}
|
||||
};
|
||||
|
||||
let field_enum = quote! {
|
||||
quote! {
|
||||
#[allow(non_camel_case_types)]
|
||||
enum __Field {
|
||||
#(field_idents,)*
|
||||
#(#field_idents,)*
|
||||
#ignore_variant
|
||||
}
|
||||
};
|
||||
|
||||
let impl_item = quote! {
|
||||
impl _serde::de::Deserialize for __Field {
|
||||
#[inline]
|
||||
fn deserialize<__D>(deserializer: &mut __D) -> ::std::result::Result<__Field, __D::Error>
|
||||
@@ -778,11 +776,6 @@ fn deserialize_field_visitor(
|
||||
deserializer.deserialize_struct_field(__FieldVisitor)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
quote! {
|
||||
#field_enum
|
||||
#impl_item
|
||||
}
|
||||
}
|
||||
|
||||
@@ -816,7 +809,7 @@ fn deserialize_struct_visitor(
|
||||
});
|
||||
|
||||
let fields_stmt = quote! {
|
||||
const FIELDS: &'static [&'static str] = &[ #(field_names),* ];
|
||||
const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
|
||||
};
|
||||
|
||||
(field_visitor, fields_stmt, visit_map)
|
||||
@@ -929,21 +922,21 @@ fn deserialize_map(
|
||||
});
|
||||
|
||||
quote! {
|
||||
#(let_values)*
|
||||
#(#let_values)*
|
||||
|
||||
while let Some(key) = try!(visitor.visit_key::<__Field>()) {
|
||||
match key {
|
||||
#(value_arms)*
|
||||
#(skipped_arms)*
|
||||
#(#value_arms)*
|
||||
#(#skipped_arms)*
|
||||
#ignored_arm
|
||||
}
|
||||
}
|
||||
|
||||
try!(visitor.end());
|
||||
|
||||
#(extract_values)*
|
||||
#(#extract_values)*
|
||||
|
||||
Ok(#struct_path { #(result),* })
|
||||
Ok(#struct_path { #(#result),* })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,9 @@ extern crate syn;
|
||||
#[macro_use]
|
||||
extern crate quote;
|
||||
|
||||
#[cfg(feature = "with-syn")]
|
||||
extern crate post_expansion;
|
||||
|
||||
#[cfg(feature = "with-syntex")]
|
||||
use std::path::Path;
|
||||
|
||||
@@ -169,8 +172,8 @@ macro_rules! shim {
|
||||
use syntax::parse;
|
||||
let name = stringify!($name).to_string();
|
||||
let cfg = Vec::new();
|
||||
let sess = parse::ParseSess::new();
|
||||
let impl_item = parse::parse_item_from_source_str(name, expanded, cfg, &sess);
|
||||
let sess = cx.parse_sess;
|
||||
let impl_item = parse::parse_item_from_source_str(name, expanded, cfg, sess);
|
||||
push(::syntax::ext::base::Annotatable::Item(impl_item.unwrap().unwrap()));
|
||||
}
|
||||
};
|
||||
@@ -193,7 +196,7 @@ pub fn expand_single_item(item: &str) -> Result<String, String> {
|
||||
} else {
|
||||
None::<quote::Tokens>
|
||||
};
|
||||
let syn_item = strip_serde_attrs(syn_item);
|
||||
let syn_item = post_expansion::strip_attrs_later(syn_item, &["serde"], "serde");
|
||||
return Ok(quote!(#expanded_ser #expanded_de #syn_item).to_string());
|
||||
|
||||
fn strip_serde_derives(item: syn::MacroInput) -> (bool, bool, syn::MacroInput) {
|
||||
@@ -201,7 +204,7 @@ pub fn expand_single_item(item: &str) -> Result<String, String> {
|
||||
let mut de = false;
|
||||
let item = syn::MacroInput {
|
||||
attrs: item.attrs.into_iter().flat_map(|attr| {
|
||||
if attr.is_sugared_doc {
|
||||
if attr.is_sugared_doc || attr.style != syn::AttrStyle::Outer {
|
||||
return Some(attr);
|
||||
}
|
||||
let (name, nested) = match attr.value {
|
||||
@@ -210,6 +213,7 @@ pub fn expand_single_item(item: &str) -> Result<String, String> {
|
||||
};
|
||||
if name != "derive" {
|
||||
return Some(syn::Attribute {
|
||||
style: syn::AttrStyle::Outer,
|
||||
value: syn::MetaItem::List(name, nested),
|
||||
is_sugared_doc: false,
|
||||
});
|
||||
@@ -231,6 +235,7 @@ pub fn expand_single_item(item: &str) -> Result<String, String> {
|
||||
None
|
||||
} else {
|
||||
Some(syn::Attribute {
|
||||
style: syn::AttrStyle::Outer,
|
||||
value: syn::MetaItem::List(name, rest),
|
||||
is_sugared_doc: false,
|
||||
})
|
||||
@@ -240,54 +245,4 @@ pub fn expand_single_item(item: &str) -> Result<String, String> {
|
||||
};
|
||||
(ser, de, item)
|
||||
}
|
||||
|
||||
fn strip_serde_attrs(item: syn::MacroInput) -> syn::MacroInput {
|
||||
syn::MacroInput {
|
||||
attrs: strip_serde_from_attrs(item.attrs),
|
||||
body: match item.body {
|
||||
syn::Body::Enum(variants) => syn::Body::Enum(
|
||||
variants.into_iter().map(|variant| {
|
||||
syn::Variant {
|
||||
ident: variant.ident,
|
||||
attrs: strip_serde_from_attrs(variant.attrs),
|
||||
data: strip_serde_from_variant_data(variant.data),
|
||||
discriminant: variant.discriminant,
|
||||
}
|
||||
}).collect()
|
||||
),
|
||||
syn::Body::Struct(variant_data) => syn::Body::Struct(
|
||||
strip_serde_from_variant_data(variant_data)
|
||||
),
|
||||
},
|
||||
..item
|
||||
}
|
||||
}
|
||||
|
||||
fn strip_serde_from_variant_data(data: syn::VariantData) -> syn::VariantData {
|
||||
match data {
|
||||
syn::VariantData::Struct(fields) => syn::VariantData::Struct(
|
||||
fields.into_iter().map(strip_serde_from_field).collect()
|
||||
),
|
||||
syn::VariantData::Tuple(fields) => syn::VariantData::Tuple(
|
||||
fields.into_iter().map(strip_serde_from_field).collect()
|
||||
),
|
||||
syn::VariantData::Unit => syn::VariantData::Unit,
|
||||
}
|
||||
}
|
||||
|
||||
fn strip_serde_from_field(field: syn::Field) -> syn::Field {
|
||||
syn::Field {
|
||||
attrs: strip_serde_from_attrs(field.attrs),
|
||||
..field
|
||||
}
|
||||
}
|
||||
|
||||
fn strip_serde_from_attrs(attrs: Vec<syn::Attribute>) -> Vec<syn::Attribute> {
|
||||
attrs.into_iter().filter(|attr| {
|
||||
match attr.value {
|
||||
syn::MetaItem::List(ref ident, _) => ident != "serde",
|
||||
_ => true,
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ fn serialize_tuple_struct(
|
||||
|
||||
quote! {
|
||||
let #let_mut __serde_state = try!(_serializer.serialize_tuple_struct(#type_name, #len));
|
||||
#(serialize_stmts)*
|
||||
#(#serialize_stmts)*
|
||||
_serializer.serialize_tuple_struct_end(__serde_state)
|
||||
}
|
||||
}
|
||||
@@ -209,7 +209,7 @@ fn serialize_struct(
|
||||
|
||||
quote! {
|
||||
let #let_mut __serde_state = try!(_serializer.serialize_struct(#type_name, #len));
|
||||
#(serialize_fields)*
|
||||
#(#serialize_fields)*
|
||||
_serializer.serialize_struct_end(__serde_state)
|
||||
}
|
||||
}
|
||||
@@ -238,7 +238,7 @@ fn serialize_item_enum(
|
||||
|
||||
quote! {
|
||||
match *self {
|
||||
#(arms)*
|
||||
#(#arms)*
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -290,7 +290,7 @@ fn serialize_variant(
|
||||
})
|
||||
.collect();
|
||||
|
||||
let pat = quote!(#type_ident::#variant_ident(#(field_names),*));
|
||||
let pat = quote!(#type_ident::#variant_ident(#(#field_names),*));
|
||||
|
||||
let block = serialize_tuple_variant(
|
||||
type_name,
|
||||
@@ -313,7 +313,7 @@ fn serialize_variant(
|
||||
};
|
||||
quote!(ref #id)
|
||||
});
|
||||
let pat = quote!(#type_ident::#variant_ident { #(fields),* });
|
||||
let pat = quote!(#type_ident::#variant_ident { #(#fields),* });
|
||||
|
||||
let block = serialize_struct_variant(
|
||||
variant_index,
|
||||
@@ -381,7 +381,7 @@ fn serialize_tuple_variant(
|
||||
#variant_index,
|
||||
#variant_name,
|
||||
#len));
|
||||
#(serialize_stmts)*
|
||||
#(#serialize_stmts)*
|
||||
_serializer.serialize_tuple_variant_end(__serde_state)
|
||||
}
|
||||
}
|
||||
@@ -428,7 +428,7 @@ fn serialize_struct_variant(
|
||||
#variant_name,
|
||||
#len,
|
||||
));
|
||||
#(serialize_fields)*
|
||||
#(#serialize_fields)*
|
||||
_serializer.serialize_struct_variant_end(__serde_state)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_codegen_internals"
|
||||
version = "0.9.0"
|
||||
version = "0.10.0"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "AST representation used by Serde codegen. Unstable."
|
||||
@@ -15,4 +15,4 @@ unstable-testing = ["clippy"]
|
||||
|
||||
[dependencies]
|
||||
clippy = { version = "^0.*", optional = true }
|
||||
syn = "0.8"
|
||||
syn = "0.9"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_derive"
|
||||
version = "0.8.11"
|
||||
version = "0.8.15"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
||||
@@ -12,10 +12,13 @@ include = ["Cargo.toml", "src/**/*.rs"]
|
||||
|
||||
[lib]
|
||||
name = "serde_derive"
|
||||
rustc-macro = true
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
post-expansion = "0.1.0"
|
||||
|
||||
[dependencies.serde_codegen]
|
||||
version = "=0.8.11"
|
||||
version = "=0.8.15"
|
||||
path = "../serde_codegen"
|
||||
default-features = false
|
||||
features = ["with-syn"]
|
||||
@@ -23,5 +26,5 @@ features = ["with-syn"]
|
||||
[dev-dependencies]
|
||||
compiletest_rs = "^0.2.0"
|
||||
fnv = "1.0"
|
||||
serde = { version = "0.8.11", path = "../serde" }
|
||||
serde_test = { version = "0.8.11", path = "../serde_test" }
|
||||
serde = { version = "0.8.15", path = "../serde" }
|
||||
serde_test = { version = "0.8.15", path = "../serde_test" }
|
||||
|
||||
+10
-5
@@ -1,12 +1,15 @@
|
||||
#![feature(rustc_macro, rustc_macro_lib)]
|
||||
#![feature(proc_macro, proc_macro_lib)]
|
||||
#![cfg(not(test))]
|
||||
|
||||
extern crate rustc_macro;
|
||||
extern crate proc_macro;
|
||||
extern crate serde_codegen;
|
||||
|
||||
use rustc_macro::TokenStream;
|
||||
#[macro_use]
|
||||
extern crate post_expansion;
|
||||
|
||||
#[rustc_macro_derive(Serialize)]
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
#[proc_macro_derive(Serialize)]
|
||||
pub fn derive_serialize(input: TokenStream) -> TokenStream {
|
||||
let item = format!("#[derive(Serialize)]\n{}", input);
|
||||
match serde_codegen::expand_single_item(&item) {
|
||||
@@ -15,7 +18,7 @@ pub fn derive_serialize(input: TokenStream) -> TokenStream {
|
||||
}
|
||||
}
|
||||
|
||||
#[rustc_macro_derive(Deserialize)]
|
||||
#[proc_macro_derive(Deserialize)]
|
||||
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
|
||||
let item = format!("#[derive(Deserialize)]\n{}", input);
|
||||
match serde_codegen::expand_single_item(&item) {
|
||||
@@ -23,3 +26,5 @@ pub fn derive_deserialize(input: TokenStream) -> TokenStream {
|
||||
Err(msg) => panic!(msg),
|
||||
}
|
||||
}
|
||||
|
||||
register_post_expansion!(PostExpansion_serde);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![feature(rustc_macro)]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![feature(rustc_macro)]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![feature(rustc_macro)]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![feature(rustc_macro)]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![feature(rustc_macro)]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![feature(rustc_macro)]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![feature(rustc_macro)]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![feature(rustc_macro)]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![feature(rustc_macro)]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![feature(rustc_macro)]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![feature(rustc_macro)]
|
||||
#![feature(proc_macro)]
|
||||
#![deny(identity_op)]
|
||||
|
||||
#[macro_use]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![feature(test, rustc_macro, rustc_attrs)]
|
||||
#![feature(test, proc_macro)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_test"
|
||||
version = "0.8.11"
|
||||
version = "0.8.15"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "Token De/Serializer for testing De/Serialize implementations"
|
||||
@@ -12,4 +12,4 @@ keywords = ["serde", "serialization"]
|
||||
include = ["Cargo.toml", "src/**/*.rs"]
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "0.8.11", path = "../serde" }
|
||||
serde = { version = "0.8.15", path = "../serde" }
|
||||
|
||||
+1
-5
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_testing"
|
||||
version = "0.8.11"
|
||||
version = "0.8.15"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "A generic serialization/deserialization framework"
|
||||
@@ -29,7 +29,3 @@ clippy = { version = "^0.*", optional = true }
|
||||
[[test]]
|
||||
name = "test"
|
||||
path = "tests/test.rs"
|
||||
|
||||
[[bench]]
|
||||
name = "bench"
|
||||
path = "benches/bench.rs"
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
#![feature(test)]
|
||||
#![cfg_attr(feature = "clippy", feature(plugin))]
|
||||
#![cfg_attr(feature = "clippy", plugin(clippy))]
|
||||
|
||||
extern crate rustc_serialize;
|
||||
extern crate serde;
|
||||
extern crate test;
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/bench.rs"));
|
||||
@@ -1,4 +0,0 @@
|
||||
mod bench_enum;
|
||||
mod bench_map;
|
||||
mod bench_struct;
|
||||
mod bench_vec;
|
||||
@@ -1,466 +0,0 @@
|
||||
use test::Bencher;
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
use rustc_serialize::Decodable;
|
||||
use serde;
|
||||
use serde::de::Deserialize;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, RustcDecodable, Deserialize)]
|
||||
pub enum Animal {
|
||||
Dog,
|
||||
Frog(String, isize)
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
EndOfStream,
|
||||
Syntax,
|
||||
}
|
||||
|
||||
impl serde::de::Error for Error {
|
||||
fn custom<T: Into<String>>(_: T) -> Error { Error::Syntax }
|
||||
|
||||
fn end_of_stream() -> Error { Error::EndOfStream }
|
||||
|
||||
fn unknown_field(_: &str) -> Error { Error::Syntax }
|
||||
|
||||
fn missing_field(_: &'static str) -> Error { Error::Syntax }
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
formatter.write_str(format!("{:?}", self).as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
"Serde Deserialization Error"
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
mod decoder {
|
||||
use rustc_serialize::Decoder;
|
||||
|
||||
use super::{Animal, Error};
|
||||
use super::Animal::{Dog, Frog};
|
||||
|
||||
enum State {
|
||||
Animal(Animal),
|
||||
Isize(isize),
|
||||
String(String),
|
||||
}
|
||||
|
||||
pub struct AnimalDecoder {
|
||||
stack: Vec<State>,
|
||||
|
||||
}
|
||||
|
||||
impl AnimalDecoder {
|
||||
#[inline]
|
||||
pub fn new(animal: Animal) -> AnimalDecoder {
|
||||
AnimalDecoder {
|
||||
stack: vec!(State::Animal(animal)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Decoder for AnimalDecoder {
|
||||
type Error = Error;
|
||||
|
||||
fn error(&mut self, _: &str) -> Error { Error::Syntax }
|
||||
|
||||
// Primitive types:
|
||||
fn read_nil(&mut self) -> Result<(), Error> { Err(Error::Syntax) }
|
||||
fn read_usize(&mut self) -> Result<usize, Error> { Err(Error::Syntax) }
|
||||
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::Syntax) }
|
||||
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::Syntax) }
|
||||
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::Syntax) }
|
||||
fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::Syntax) }
|
||||
#[inline]
|
||||
fn read_isize(&mut self) -> Result<isize, Error> {
|
||||
match self.stack.pop() {
|
||||
Some(State::Isize(x)) => Ok(x),
|
||||
_ => Err(Error::Syntax),
|
||||
}
|
||||
}
|
||||
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::Syntax) }
|
||||
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::Syntax) }
|
||||
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::Syntax) }
|
||||
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::Syntax) }
|
||||
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::Syntax) }
|
||||
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::Syntax) }
|
||||
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::Syntax) }
|
||||
fn read_char(&mut self) -> Result<char, Error> { Err(Error::Syntax) }
|
||||
#[inline]
|
||||
fn read_str(&mut self) -> Result<String, Error> {
|
||||
match self.stack.pop() {
|
||||
Some(State::String(x)) => Ok(x),
|
||||
_ => Err(Error::Syntax),
|
||||
}
|
||||
}
|
||||
|
||||
// Compound types:
|
||||
#[inline]
|
||||
fn read_enum<T, F>(&mut self, name: &str, f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
|
||||
{
|
||||
match self.stack.pop() {
|
||||
Some(State::Animal(animal)) => {
|
||||
self.stack.push(State::Animal(animal));
|
||||
if name == "Animal" {
|
||||
f(self)
|
||||
} else {
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
}
|
||||
_ => Err(Error::Syntax)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_enum_variant<T, F>(&mut self, names: &[&str], f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut AnimalDecoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
let name = match self.stack.pop() {
|
||||
Some(State::Animal(Dog)) => "Dog",
|
||||
Some(State::Animal(Frog(x0, x1))) => {
|
||||
self.stack.push(State::Isize(x1));
|
||||
self.stack.push(State::String(x0));
|
||||
"Frog"
|
||||
}
|
||||
_ => { return Err(Error::Syntax); }
|
||||
};
|
||||
|
||||
let idx = match names.iter().position(|n| *n == name) {
|
||||
Some(idx) => idx,
|
||||
None => { return Err(Error::Syntax); }
|
||||
};
|
||||
|
||||
f(self, idx)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut AnimalDecoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_struct_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
// Specialized types:
|
||||
fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut AnimalDecoder, bool) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_seq<T, F>(&mut self, f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut AnimalDecoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
f(self, 3)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_seq_elt<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn read_map<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut AnimalDecoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_map_elt_key<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_map_elt_val<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
mod deserializer {
|
||||
use super::{Animal, Error};
|
||||
|
||||
use serde::de;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum State {
|
||||
Animal(Animal),
|
||||
Isize(isize),
|
||||
Str(&'static str),
|
||||
String(String),
|
||||
UnitState,
|
||||
}
|
||||
|
||||
pub struct AnimalDeserializer {
|
||||
stack: Vec<State>,
|
||||
}
|
||||
|
||||
impl AnimalDeserializer {
|
||||
#[inline]
|
||||
pub fn new(animal: Animal) -> AnimalDeserializer {
|
||||
AnimalDeserializer {
|
||||
stack: vec!(State::Animal(animal)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl de::Deserializer for AnimalDeserializer {
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::Visitor,
|
||||
{
|
||||
match self.stack.pop() {
|
||||
Some(State::Isize(value)) => {
|
||||
visitor.visit_isize(value)
|
||||
}
|
||||
Some(State::String(value)) => {
|
||||
visitor.visit_string(value)
|
||||
}
|
||||
Some(State::Str(value)) => {
|
||||
visitor.visit_str(value)
|
||||
}
|
||||
Some(State::UnitState) => {
|
||||
visitor.visit_unit()
|
||||
}
|
||||
Some(_) => {
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
None => {
|
||||
Err(Error::EndOfStream)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn deserialize_enum<V>(&mut self,
|
||||
_name: &str,
|
||||
_variants: &[&str],
|
||||
mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::EnumVisitor,
|
||||
{
|
||||
match self.stack.pop() {
|
||||
Some(State::Animal(Animal::Dog)) => {
|
||||
self.stack.push(State::UnitState);
|
||||
self.stack.push(State::Str("Dog"));
|
||||
visitor.visit(DogVisitor {
|
||||
de: self,
|
||||
})
|
||||
}
|
||||
Some(State::Animal(Animal::Frog(x0, x1))) => {
|
||||
self.stack.push(State::Isize(x1));
|
||||
self.stack.push(State::String(x0));
|
||||
self.stack.push(State::Str("Frog"));
|
||||
visitor.visit(FrogVisitor {
|
||||
de: self,
|
||||
state: 0,
|
||||
})
|
||||
}
|
||||
Some(_) => {
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
None => {
|
||||
Err(Error::EndOfStream)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct DogVisitor<'a> {
|
||||
de: &'a mut AnimalDeserializer,
|
||||
}
|
||||
|
||||
impl<'a> de::VariantVisitor for DogVisitor<'a> {
|
||||
type Error = Error;
|
||||
|
||||
fn visit_variant<V>(&mut self) -> Result<V, Error>
|
||||
where V: de::Deserialize
|
||||
{
|
||||
de::Deserialize::deserialize(self.de)
|
||||
}
|
||||
|
||||
fn visit_unit(&mut self) -> Result<(), Error> {
|
||||
de::Deserialize::deserialize(self.de)
|
||||
}
|
||||
}
|
||||
|
||||
struct FrogVisitor<'a> {
|
||||
de: &'a mut AnimalDeserializer,
|
||||
state: usize,
|
||||
}
|
||||
|
||||
impl<'a> de::VariantVisitor for FrogVisitor<'a> {
|
||||
type Error = Error;
|
||||
|
||||
fn visit_variant<V>(&mut self) -> Result<V, Error>
|
||||
where V: de::Deserialize
|
||||
{
|
||||
de::Deserialize::deserialize(self.de)
|
||||
}
|
||||
|
||||
fn visit_tuple<V>(&mut self,
|
||||
_len: usize,
|
||||
mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::Visitor,
|
||||
{
|
||||
visitor.visit_seq(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> de::SeqVisitor for FrogVisitor<'a> {
|
||||
type Error = Error;
|
||||
|
||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
||||
where T: de::Deserialize,
|
||||
{
|
||||
match self.state {
|
||||
0 => {
|
||||
self.state += 1;
|
||||
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
|
||||
}
|
||||
1 => {
|
||||
self.state += 1;
|
||||
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
|
||||
}
|
||||
_ => {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn end(&mut self) -> Result<(), Error> {
|
||||
if self.state == 2 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let len = 2 - self.state;
|
||||
(len, Some(len))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[bench]
|
||||
fn bench_decoder_dog(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let animal = Animal::Dog;
|
||||
|
||||
let mut d = decoder::AnimalDecoder::new(animal.clone());
|
||||
let value: Animal = Decodable::decode(&mut d).unwrap();
|
||||
|
||||
assert_eq!(value, animal);
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_decoder_frog(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let animal = Animal::Frog("Henry".to_owned(), 349);
|
||||
|
||||
let mut d = decoder::AnimalDecoder::new(animal.clone());
|
||||
let value: Animal = Decodable::decode(&mut d).unwrap();
|
||||
|
||||
assert_eq!(value, animal);
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_deserializer_dog(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let animal = Animal::Dog;
|
||||
|
||||
let mut d = deserializer::AnimalDeserializer::new(animal.clone());
|
||||
let value: Animal = Deserialize::deserialize(&mut d).unwrap();
|
||||
|
||||
assert_eq!(value, animal);
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_deserializer_frog(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let animal = Animal::Frog("Henry".to_owned(), 349);
|
||||
|
||||
let mut d = deserializer::AnimalDeserializer::new(animal.clone());
|
||||
let value: Animal = Deserialize::deserialize(&mut d).unwrap();
|
||||
|
||||
assert_eq!(value, animal);
|
||||
})
|
||||
}
|
||||
@@ -1,474 +0,0 @@
|
||||
use std::fmt::Debug;
|
||||
use std::fmt;
|
||||
use std::error;
|
||||
use std::collections::HashMap;
|
||||
use test::Bencher;
|
||||
|
||||
use rustc_serialize::{Decoder, Decodable};
|
||||
|
||||
use serde;
|
||||
use serde::de::{Deserializer, Deserialize};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub enum Error {
|
||||
EndOfStream,
|
||||
Syntax,
|
||||
MissingField,
|
||||
}
|
||||
|
||||
impl serde::de::Error for Error {
|
||||
fn custom<T: Into<String>>(_: T) -> Error { Error::Syntax }
|
||||
|
||||
fn end_of_stream() -> Error { Error::EndOfStream }
|
||||
|
||||
fn unknown_field(_: &str) -> Error { Error::Syntax }
|
||||
|
||||
fn missing_field(_: &'static str) -> Error {
|
||||
Error::MissingField
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
formatter.write_str(format!("{:?}", self).as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
"Serde Deserialization Error"
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
None
|
||||
}
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
mod decoder {
|
||||
use std::collections::HashMap;
|
||||
use std::collections::hash_map::IntoIter;
|
||||
use rustc_serialize;
|
||||
|
||||
use super::Error;
|
||||
|
||||
enum Value {
|
||||
String(String),
|
||||
Isize(isize),
|
||||
}
|
||||
|
||||
pub struct IsizeDecoder {
|
||||
len: usize,
|
||||
iter: IntoIter<String, isize>,
|
||||
stack: Vec<Value>,
|
||||
}
|
||||
|
||||
impl IsizeDecoder {
|
||||
#[inline]
|
||||
pub fn new(values: HashMap<String, isize>) -> IsizeDecoder {
|
||||
IsizeDecoder {
|
||||
len: values.len(),
|
||||
iter: values.into_iter(),
|
||||
stack: vec!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl rustc_serialize::Decoder for IsizeDecoder {
|
||||
type Error = Error;
|
||||
|
||||
fn error(&mut self, _msg: &str) -> Error {
|
||||
Error::Syntax
|
||||
}
|
||||
|
||||
// Primitive types:
|
||||
fn read_nil(&mut self) -> Result<(), Error> { Err(Error::Syntax) }
|
||||
fn read_usize(&mut self) -> Result<usize, Error> { Err(Error::Syntax) }
|
||||
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::Syntax) }
|
||||
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::Syntax) }
|
||||
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::Syntax) }
|
||||
fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::Syntax) }
|
||||
#[inline]
|
||||
fn read_isize(&mut self) -> Result<isize, Error> {
|
||||
match self.stack.pop() {
|
||||
Some(Value::Isize(x)) => Ok(x),
|
||||
Some(_) => Err(Error::Syntax),
|
||||
None => Err(Error::EndOfStream),
|
||||
}
|
||||
}
|
||||
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::Syntax) }
|
||||
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::Syntax) }
|
||||
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::Syntax) }
|
||||
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::Syntax) }
|
||||
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::Syntax) }
|
||||
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::Syntax) }
|
||||
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::Syntax) }
|
||||
fn read_char(&mut self) -> Result<char, Error> { Err(Error::Syntax) }
|
||||
#[inline]
|
||||
fn read_str(&mut self) -> Result<String, Error> {
|
||||
match self.stack.pop() {
|
||||
Some(Value::String(x)) => Ok(x),
|
||||
Some(_) => Err(Error::Syntax),
|
||||
None => Err(Error::EndOfStream),
|
||||
}
|
||||
}
|
||||
|
||||
// Compound types:
|
||||
fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_struct_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
// Specialized types:
|
||||
fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut IsizeDecoder, bool) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_seq<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_seq_elt<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_map<T, F>(&mut self, f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
let len = self.len;
|
||||
f(self, len)
|
||||
}
|
||||
#[inline]
|
||||
fn read_map_elt_key<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
match self.iter.next() {
|
||||
Some((key, value)) => {
|
||||
self.stack.push(Value::Isize(value));
|
||||
self.stack.push(Value::String(key));
|
||||
f(self)
|
||||
}
|
||||
None => {
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_map_elt_val<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
mod deserializer {
|
||||
use std::collections::HashMap;
|
||||
use std::collections::hash_map;
|
||||
|
||||
use super::Error;
|
||||
|
||||
use serde::de;
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
enum State {
|
||||
StartState,
|
||||
Key(String),
|
||||
Value(isize),
|
||||
}
|
||||
|
||||
pub struct IsizeDeserializer {
|
||||
stack: Vec<State>,
|
||||
iter: hash_map::IntoIter<String, isize>,
|
||||
}
|
||||
|
||||
impl IsizeDeserializer {
|
||||
#[inline]
|
||||
pub fn new(values: HashMap<String, isize>) -> IsizeDeserializer {
|
||||
IsizeDeserializer {
|
||||
stack: vec!(State::StartState),
|
||||
iter: values.into_iter(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl de::Deserializer for IsizeDeserializer {
|
||||
type Error = Error;
|
||||
|
||||
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::Visitor,
|
||||
{
|
||||
match self.stack.pop() {
|
||||
Some(State::StartState) => {
|
||||
visitor.visit_map(self)
|
||||
}
|
||||
Some(State::Key(key)) => {
|
||||
visitor.visit_string(key)
|
||||
}
|
||||
Some(State::Value(value)) => {
|
||||
visitor.visit_isize(value)
|
||||
}
|
||||
None => {
|
||||
Err(Error::EndOfStream)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl de::MapVisitor for IsizeDeserializer {
|
||||
type Error = Error;
|
||||
|
||||
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
|
||||
where K: de::Deserialize,
|
||||
{
|
||||
match self.iter.next() {
|
||||
Some((key, value)) => {
|
||||
self.stack.push(State::Value(value));
|
||||
self.stack.push(State::Key(key));
|
||||
Ok(Some(try!(de::Deserialize::deserialize(self))))
|
||||
}
|
||||
None => {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_value<V>(&mut self) -> Result<V, Error>
|
||||
where V: de::Deserialize,
|
||||
{
|
||||
de::Deserialize::deserialize(self)
|
||||
}
|
||||
|
||||
fn end(&mut self) -> Result<(), Error> {
|
||||
match self.iter.next() {
|
||||
Some(_) => Err(Error::Syntax),
|
||||
None => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.iter.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl Iterator for IsizeDeserializer {
|
||||
type Item = Result<de::Token, Error>;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Result<de::Token, Error>> {
|
||||
match self.stack.pop() {
|
||||
Some(State::StartState) => {
|
||||
self.stack.push(KeyOrEndState);
|
||||
Some(Ok(de::Token::MapStart(self.len)))
|
||||
}
|
||||
Some(State::KeyOrEndState) => {
|
||||
match self.iter.next() {
|
||||
Some((key, value)) => {
|
||||
self.stack.push(Value(value));
|
||||
Some(Ok(de::Token::String(key)))
|
||||
}
|
||||
None => {
|
||||
self.stack.push(EndState);
|
||||
Some(Ok(de::Token::End))
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(State::Value(x)) => {
|
||||
self.stack.push(KeyOrEndState);
|
||||
Some(Ok(de::Token::Isize(x)))
|
||||
}
|
||||
Some(EndState) => {
|
||||
None
|
||||
}
|
||||
None => {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl de::Deserializer<Error> for IsizeDeserializer {
|
||||
#[inline]
|
||||
fn end_of_stream(&mut self) -> Error {
|
||||
EndOfStream
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn syntax(&mut self, _token: de::Token, _expected: &[de::TokenKind]) -> Error {
|
||||
Syntax
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn unexpected_name(&mut self, _token: de::Token) -> Error {
|
||||
Syntax
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn conversion_error(&mut self, _token: de::Token) -> Error {
|
||||
Syntax
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn missing_field<
|
||||
T: de::Deserialize<IsizeDeserializer, Error>
|
||||
>(&mut self, _field: &'static str) -> Result<T, Error> {
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
fn run_decoder<
|
||||
D: Decoder<Error=Error>,
|
||||
T: Clone + PartialEq + Debug + Decodable
|
||||
>(mut d: D, value: T) {
|
||||
let v = Decodable::decode(&mut d);
|
||||
|
||||
assert_eq!(Ok(value), v);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_decoder_000(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let m: HashMap<String, isize> = HashMap::new();
|
||||
run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_decoder_003(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let mut m: HashMap<String, isize> = HashMap::new();
|
||||
for i in 0 .. 3 {
|
||||
m.insert(i.to_string(), i);
|
||||
}
|
||||
run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_decoder_100(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let mut m: HashMap<String, isize> = HashMap::new();
|
||||
for i in 0 .. 100 {
|
||||
m.insert(i.to_string(), i);
|
||||
}
|
||||
run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
|
||||
})
|
||||
}
|
||||
|
||||
fn run_deserializer<D, T>(mut d: D, value: T)
|
||||
where D: Deserializer,
|
||||
D::Error: Debug + PartialEq,
|
||||
T: Clone + PartialEq + Debug + Deserialize
|
||||
{
|
||||
let v = T::deserialize(&mut d);
|
||||
|
||||
assert_eq!(Ok(value), v);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_deserializer_000(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let m: HashMap<String, isize> = HashMap::new();
|
||||
run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_deserializer_003(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let mut m: HashMap<String, isize> = HashMap::new();
|
||||
for i in 0 .. 3 {
|
||||
m.insert(i.to_string(), i);
|
||||
}
|
||||
run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_deserializer_100(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let mut m: HashMap<String, isize> = HashMap::new();
|
||||
for i in 0 .. 100 {
|
||||
m.insert(i.to_string(), i);
|
||||
}
|
||||
run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
|
||||
})
|
||||
}
|
||||
@@ -1,745 +0,0 @@
|
||||
use std::collections::HashMap;
|
||||
use test::Bencher;
|
||||
use std::fmt;
|
||||
use std::error;
|
||||
|
||||
use rustc_serialize::Decodable;
|
||||
|
||||
use serde;
|
||||
use serde::de::Deserialize;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, RustcDecodable, Deserialize)]
|
||||
pub struct Inner {
|
||||
a: (),
|
||||
b: usize,
|
||||
c: HashMap<String, Option<char>>,
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, RustcDecodable, Deserialize)]
|
||||
pub struct Outer {
|
||||
inner: Vec<Inner>,
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Error {
|
||||
EndOfStream,
|
||||
Syntax,
|
||||
MissingField,
|
||||
OtherError,
|
||||
}
|
||||
|
||||
impl serde::de::Error for Error {
|
||||
fn custom<T: Into<String>>(_: T) -> Error { Error::Syntax }
|
||||
|
||||
fn end_of_stream() -> Error { Error::EndOfStream }
|
||||
|
||||
fn unknown_field(_: &str) -> Error { Error::Syntax }
|
||||
|
||||
fn missing_field(_: &'static str) -> Error {
|
||||
Error::MissingField
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
formatter.write_str(format!("{:?}", self).as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
"Serde Deserialization Error"
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
mod decoder {
|
||||
use std::collections::HashMap;
|
||||
use rustc_serialize::Decoder;
|
||||
|
||||
use super::{Outer, Inner, Error};
|
||||
|
||||
#[derive(Debug)]
|
||||
enum State {
|
||||
Outer(Outer),
|
||||
Inner(Inner),
|
||||
Null,
|
||||
Usize(usize),
|
||||
Char(char),
|
||||
String(String),
|
||||
Field(&'static str),
|
||||
Vec(Vec<Inner>),
|
||||
Map(HashMap<String, Option<char>>),
|
||||
Option(bool),
|
||||
}
|
||||
|
||||
pub struct OuterDecoder {
|
||||
stack: Vec<State>,
|
||||
|
||||
}
|
||||
|
||||
impl OuterDecoder {
|
||||
#[inline]
|
||||
pub fn new(animal: Outer) -> OuterDecoder {
|
||||
OuterDecoder {
|
||||
stack: vec!(State::Outer(animal)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Decoder for OuterDecoder {
|
||||
type Error = Error;
|
||||
|
||||
fn error(&mut self, _msg: &str) -> Error {
|
||||
Error::OtherError
|
||||
}
|
||||
|
||||
// Primitive types:
|
||||
#[inline]
|
||||
fn read_nil(&mut self) -> Result<(), Error> {
|
||||
match self.stack.pop() {
|
||||
Some(State::Null) => Ok(()),
|
||||
_ => Err(Error::Syntax),
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn read_usize(&mut self) -> Result<usize, Error> {
|
||||
match self.stack.pop() {
|
||||
Some(State::Usize(value)) => Ok(value),
|
||||
_ => Err(Error::Syntax),
|
||||
}
|
||||
}
|
||||
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::Syntax) }
|
||||
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::Syntax) }
|
||||
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::Syntax) }
|
||||
fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::Syntax) }
|
||||
fn read_isize(&mut self) -> Result<isize, Error> { Err(Error::Syntax) }
|
||||
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::Syntax) }
|
||||
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::Syntax) }
|
||||
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::Syntax) }
|
||||
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::Syntax) }
|
||||
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::Syntax) }
|
||||
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::Syntax) }
|
||||
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::Syntax) }
|
||||
#[inline]
|
||||
fn read_char(&mut self) -> Result<char, Error> {
|
||||
match self.stack.pop() {
|
||||
Some(State::Char(c)) => Ok(c),
|
||||
_ => Err(Error::Syntax),
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn read_str(&mut self) -> Result<String, Error> {
|
||||
match self.stack.pop() {
|
||||
Some(State::String(value)) => Ok(value),
|
||||
_ => Err(Error::Syntax),
|
||||
}
|
||||
}
|
||||
|
||||
// Compound types:
|
||||
fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut OuterDecoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut OuterDecoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_struct<T, F>(&mut self, s_name: &str, _len: usize, f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
||||
{
|
||||
match self.stack.pop() {
|
||||
Some(State::Outer(Outer { inner })) => {
|
||||
if s_name == "Outer" {
|
||||
self.stack.push(State::Vec(inner));
|
||||
self.stack.push(State::Field("inner"));
|
||||
f(self)
|
||||
} else {
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
}
|
||||
Some(State::Inner(Inner { a: (), b, c })) => {
|
||||
if s_name == "Inner" {
|
||||
self.stack.push(State::Map(c));
|
||||
self.stack.push(State::Field("c"));
|
||||
|
||||
self.stack.push(State::Usize(b));
|
||||
self.stack.push(State::Field("b"));
|
||||
|
||||
self.stack.push(State::Null);
|
||||
self.stack.push(State::Field("a"));
|
||||
f(self)
|
||||
} else {
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
}
|
||||
_ => Err(Error::Syntax),
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn read_struct_field<T, F>(&mut self, f_name: &str, _f_idx: usize, f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
||||
{
|
||||
match self.stack.pop() {
|
||||
Some(State::Field(name)) => {
|
||||
if f_name == name {
|
||||
f(self)
|
||||
} else {
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
}
|
||||
_ => Err(Error::Syntax)
|
||||
}
|
||||
}
|
||||
|
||||
fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
// Specialized types:
|
||||
#[inline]
|
||||
fn read_option<T, F>(&mut self, f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut OuterDecoder, bool) -> Result<T, Error>,
|
||||
{
|
||||
match self.stack.pop() {
|
||||
Some(State::Option(b)) => f(self, b),
|
||||
_ => Err(Error::Syntax),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_seq<T, F>(&mut self, f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut OuterDecoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
match self.stack.pop() {
|
||||
Some(State::Vec(value)) => {
|
||||
let len = value.len();
|
||||
for inner in value.into_iter().rev() {
|
||||
self.stack.push(State::Inner(inner));
|
||||
}
|
||||
f(self, len)
|
||||
}
|
||||
_ => Err(Error::Syntax)
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn read_seq_elt<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_map<T, F>(&mut self, f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut OuterDecoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
match self.stack.pop() {
|
||||
Some(State::Map(map)) => {
|
||||
let len = map.len();
|
||||
for (key, value) in map {
|
||||
match value {
|
||||
Some(c) => {
|
||||
self.stack.push(State::Char(c));
|
||||
self.stack.push(State::Option(true));
|
||||
}
|
||||
None => {
|
||||
self.stack.push(State::Option(false));
|
||||
}
|
||||
}
|
||||
self.stack.push(State::String(key));
|
||||
}
|
||||
f(self, len)
|
||||
}
|
||||
_ => Err(Error::Syntax),
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn read_map_elt_key<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_map_elt_val<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
mod deserializer {
|
||||
use std::collections::HashMap;
|
||||
use std::collections::hash_map;
|
||||
use std::vec;
|
||||
use super::{Outer, Inner};
|
||||
use super::Error;
|
||||
use serde::de;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum State {
|
||||
Outer(Outer),
|
||||
Inner(Inner),
|
||||
Str(&'static str),
|
||||
Null,
|
||||
Usize(usize),
|
||||
Char(char),
|
||||
String(String),
|
||||
Option(bool),
|
||||
Vec(Vec<Inner>),
|
||||
Map(HashMap<String, Option<char>>),
|
||||
}
|
||||
|
||||
pub struct OuterDeserializer {
|
||||
stack: Vec<State>,
|
||||
}
|
||||
|
||||
impl OuterDeserializer {
|
||||
#[inline]
|
||||
pub fn new(outer: Outer) -> OuterDeserializer {
|
||||
OuterDeserializer {
|
||||
stack: vec!(State::Outer(outer)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl de::Deserializer for OuterDeserializer {
|
||||
type Error = Error;
|
||||
|
||||
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::Visitor,
|
||||
{
|
||||
match self.stack.pop() {
|
||||
Some(State::Vec(value)) => {
|
||||
visitor.visit_seq(OuterSeqVisitor {
|
||||
de: self,
|
||||
iter: value.into_iter(),
|
||||
})
|
||||
}
|
||||
Some(State::Map(value)) => {
|
||||
visitor.visit_map(MapVisitor {
|
||||
de: self,
|
||||
iter: value.into_iter(),
|
||||
})
|
||||
}
|
||||
Some(State::Null) => {
|
||||
visitor.visit_unit()
|
||||
}
|
||||
Some(State::Usize(x)) => {
|
||||
visitor.visit_usize(x)
|
||||
}
|
||||
Some(State::Char(x)) => {
|
||||
visitor.visit_char(x)
|
||||
}
|
||||
Some(State::Str(x)) => {
|
||||
visitor.visit_str(x)
|
||||
}
|
||||
Some(State::String(x)) => {
|
||||
visitor.visit_string(x)
|
||||
}
|
||||
Some(State::Option(false)) => {
|
||||
visitor.visit_none()
|
||||
}
|
||||
Some(State::Option(true)) => {
|
||||
visitor.visit_some(self)
|
||||
}
|
||||
Some(_) => Err(Error::Syntax),
|
||||
None => Err(Error::EndOfStream),
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_struct<V>(&mut self,
|
||||
name: &str,
|
||||
_fields: &'static [&'static str],
|
||||
mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::Visitor,
|
||||
{
|
||||
match self.stack.pop() {
|
||||
Some(State::Outer(Outer { inner })) => {
|
||||
if name != "Outer" {
|
||||
return Err(Error::Syntax);
|
||||
}
|
||||
|
||||
self.stack.push(State::Vec(inner));
|
||||
self.stack.push(State::Str("inner"));
|
||||
|
||||
visitor.visit_map(OuterMapVisitor {
|
||||
de: self,
|
||||
state: 0,
|
||||
})
|
||||
}
|
||||
Some(State::Inner(Inner { a: (), b, c })) => {
|
||||
if name != "Inner" {
|
||||
return Err(Error::Syntax);
|
||||
}
|
||||
|
||||
self.stack.push(State::Map(c));
|
||||
self.stack.push(State::Str("c"));
|
||||
|
||||
self.stack.push(State::Usize(b));
|
||||
self.stack.push(State::Str("b"));
|
||||
|
||||
self.stack.push(State::Null);
|
||||
self.stack.push(State::Str("a"));
|
||||
|
||||
visitor.visit_map(InnerMapVisitor {
|
||||
de: self,
|
||||
state: 0,
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct OuterMapVisitor<'a> {
|
||||
de: &'a mut OuterDeserializer,
|
||||
state: usize,
|
||||
}
|
||||
|
||||
impl<'a> de::MapVisitor for OuterMapVisitor<'a> {
|
||||
type Error = Error;
|
||||
|
||||
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
|
||||
where K: de::Deserialize,
|
||||
{
|
||||
match self.state {
|
||||
0 => {
|
||||
self.state += 1;
|
||||
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
|
||||
}
|
||||
_ => {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_value<V>(&mut self) -> Result<V, Error>
|
||||
where V: de::Deserialize,
|
||||
{
|
||||
de::Deserialize::deserialize(self.de)
|
||||
}
|
||||
|
||||
fn end(&mut self) -> Result<(), Error> {
|
||||
if self.state == 1 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let len = 1 - self.state;
|
||||
(len, Some(len))
|
||||
}
|
||||
}
|
||||
|
||||
struct OuterSeqVisitor<'a> {
|
||||
de: &'a mut OuterDeserializer,
|
||||
iter: vec::IntoIter<Inner>,
|
||||
}
|
||||
|
||||
impl<'a> de::SeqVisitor for OuterSeqVisitor<'a> {
|
||||
type Error = Error;
|
||||
|
||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
||||
where T: de::Deserialize,
|
||||
{
|
||||
match self.iter.next() {
|
||||
Some(value) => {
|
||||
self.de.stack.push(State::Inner(value));
|
||||
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
|
||||
}
|
||||
None => {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn end(&mut self) -> Result<(), Error> {
|
||||
match self.iter.next() {
|
||||
Some(_) => Err(Error::Syntax),
|
||||
None => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.iter.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
struct InnerMapVisitor<'a> {
|
||||
de: &'a mut OuterDeserializer,
|
||||
state: usize,
|
||||
}
|
||||
|
||||
impl<'a> de::MapVisitor for InnerMapVisitor<'a> {
|
||||
type Error = Error;
|
||||
|
||||
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
|
||||
where K: de::Deserialize,
|
||||
{
|
||||
match self.state {
|
||||
0 ... 2 => {
|
||||
self.state += 1;
|
||||
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
|
||||
}
|
||||
_ => {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_value<V>(&mut self) -> Result<V, Error>
|
||||
where V: de::Deserialize,
|
||||
{
|
||||
de::Deserialize::deserialize(self.de)
|
||||
}
|
||||
|
||||
fn end(&mut self) -> Result<(), Error> {
|
||||
if self.state == 3 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let len = 1 - self.state;
|
||||
(len, Some(len))
|
||||
}
|
||||
}
|
||||
|
||||
struct MapVisitor<'a> {
|
||||
de: &'a mut OuterDeserializer,
|
||||
iter: hash_map::IntoIter<String, Option<char>>,
|
||||
}
|
||||
|
||||
impl<'a> de::MapVisitor for MapVisitor<'a> {
|
||||
type Error = Error;
|
||||
|
||||
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
|
||||
where K: de::Deserialize,
|
||||
{
|
||||
match self.iter.next() {
|
||||
Some((key, Some(value))) => {
|
||||
self.de.stack.push(State::Char(value));
|
||||
self.de.stack.push(State::Option(true));
|
||||
self.de.stack.push(State::String(key));
|
||||
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
|
||||
}
|
||||
Some((key, None)) => {
|
||||
self.de.stack.push(State::Option(false));
|
||||
self.de.stack.push(State::String(key));
|
||||
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
|
||||
}
|
||||
None => {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_value<V>(&mut self) -> Result<V, Error>
|
||||
where V: de::Deserialize,
|
||||
{
|
||||
de::Deserialize::deserialize(self.de)
|
||||
}
|
||||
|
||||
fn end(&mut self) -> Result<(), Error> {
|
||||
match self.iter.next() {
|
||||
Some(_) => Err(Error::Syntax),
|
||||
None => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.iter.size_hint()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_decoder_0_0(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let mut map = HashMap::new();
|
||||
map.insert("abc".to_owned(), Some('c'));
|
||||
|
||||
let outer = Outer {
|
||||
inner: vec!(),
|
||||
};
|
||||
|
||||
let mut d = decoder::OuterDecoder::new(outer.clone());
|
||||
let value: Result<Outer, Error> = Decodable::decode(&mut d);
|
||||
|
||||
assert_eq!(value, Ok(outer));
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_decoder_1_0(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let map = HashMap::new();
|
||||
|
||||
let outer = Outer {
|
||||
inner: vec!(
|
||||
Inner {
|
||||
a: (),
|
||||
b: 5,
|
||||
c: map,
|
||||
},
|
||||
)
|
||||
};
|
||||
|
||||
let mut d = decoder::OuterDecoder::new(outer.clone());
|
||||
let value: Result<Outer, Error> = Decodable::decode(&mut d);
|
||||
|
||||
assert_eq!(value, Ok(outer));
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_decoder_1_5(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let mut map = HashMap::new();
|
||||
map.insert("1".to_owned(), Some('a'));
|
||||
map.insert("2".to_owned(), None);
|
||||
map.insert("3".to_owned(), Some('b'));
|
||||
map.insert("4".to_owned(), None);
|
||||
map.insert("5".to_owned(), Some('c'));
|
||||
|
||||
let outer = Outer {
|
||||
inner: vec!(
|
||||
Inner {
|
||||
a: (),
|
||||
b: 5,
|
||||
c: map,
|
||||
},
|
||||
)
|
||||
};
|
||||
|
||||
let mut d = decoder::OuterDecoder::new(outer.clone());
|
||||
let value: Result<Outer, Error> = Decodable::decode(&mut d);
|
||||
|
||||
assert_eq!(value, Ok(outer));
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_deserializer_0_0(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let outer = Outer {
|
||||
inner: vec!(),
|
||||
};
|
||||
|
||||
let mut d = deserializer::OuterDeserializer::new(outer.clone());
|
||||
let value: Result<Outer, Error> = Deserialize::deserialize(&mut d);
|
||||
|
||||
assert_eq!(value, Ok(outer));
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_deserializer_1_0(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let map = HashMap::new();
|
||||
|
||||
let outer = Outer {
|
||||
inner: vec!(
|
||||
Inner {
|
||||
a: (),
|
||||
b: 5,
|
||||
c: map,
|
||||
},
|
||||
)
|
||||
};
|
||||
|
||||
let mut d = deserializer::OuterDeserializer::new(outer.clone());
|
||||
let value: Result<Outer, Error> = Deserialize::deserialize(&mut d);
|
||||
|
||||
assert_eq!(value, Ok(outer));
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_deserializer_1_5(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let mut map = HashMap::new();
|
||||
map.insert("1".to_owned(), Some('a'));
|
||||
map.insert("2".to_owned(), None);
|
||||
map.insert("3".to_owned(), Some('b'));
|
||||
map.insert("4".to_owned(), None);
|
||||
map.insert("5".to_owned(), Some('c'));
|
||||
|
||||
let outer = Outer {
|
||||
inner: vec!(
|
||||
Inner {
|
||||
a: (),
|
||||
b: 5,
|
||||
c: map,
|
||||
},
|
||||
)
|
||||
};
|
||||
|
||||
let mut d = deserializer::OuterDeserializer::new(outer.clone());
|
||||
let value: Result<Outer, Error> = Deserialize::deserialize(&mut d);
|
||||
|
||||
assert_eq!(value, Ok(outer));
|
||||
})
|
||||
}
|
||||
@@ -1,628 +0,0 @@
|
||||
use std::fmt::Debug;
|
||||
use std::fmt;
|
||||
use std::error;
|
||||
use test::Bencher;
|
||||
|
||||
use rustc_serialize::{Decoder, Decodable};
|
||||
|
||||
use serde;
|
||||
use serde::de::{Deserializer, Deserialize};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub enum Error {
|
||||
EndOfStream,
|
||||
Syntax,
|
||||
}
|
||||
|
||||
impl serde::de::Error for Error {
|
||||
fn custom<T: Into<String>>(_: T) -> Error { Error::Syntax }
|
||||
|
||||
fn end_of_stream() -> Error { Error::EndOfStream }
|
||||
|
||||
fn unknown_field(_: &str) -> Error { Error::Syntax }
|
||||
|
||||
fn missing_field(_: &'static str) -> Error { Error::Syntax }
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
formatter.write_str(format!("{:?}", self).as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
"Serde Deserialization Error"
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
None
|
||||
}
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
mod decoder {
|
||||
use std::vec;
|
||||
use rustc_serialize;
|
||||
|
||||
use super::Error;
|
||||
|
||||
pub struct UsizeDecoder {
|
||||
len: usize,
|
||||
iter: vec::IntoIter<usize>,
|
||||
}
|
||||
|
||||
impl UsizeDecoder {
|
||||
#[inline]
|
||||
pub fn new(values: Vec<usize>) -> UsizeDecoder {
|
||||
UsizeDecoder {
|
||||
len: values.len(),
|
||||
iter: values.into_iter(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl rustc_serialize::Decoder for UsizeDecoder {
|
||||
type Error = Error;
|
||||
|
||||
fn error(&mut self, _: &str) -> Error { Error::Syntax }
|
||||
|
||||
// Primitive types:
|
||||
fn read_nil(&mut self) -> Result<(), Error> { Err(Error::Syntax) }
|
||||
#[inline]
|
||||
fn read_usize(&mut self) -> Result<usize, Error> {
|
||||
match self.iter.next() {
|
||||
Some(value) => Ok(value),
|
||||
None => Err(Error::EndOfStream),
|
||||
}
|
||||
}
|
||||
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::Syntax) }
|
||||
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::Syntax) }
|
||||
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::Syntax) }
|
||||
fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::Syntax) }
|
||||
fn read_isize(&mut self) -> Result<isize, Error> { Err(Error::Syntax) }
|
||||
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::Syntax) }
|
||||
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::Syntax) }
|
||||
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::Syntax) }
|
||||
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::Syntax) }
|
||||
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::Syntax) }
|
||||
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::Syntax) }
|
||||
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::Syntax) }
|
||||
fn read_char(&mut self) -> Result<char, Error> { Err(Error::Syntax) }
|
||||
fn read_str(&mut self) -> Result<String, Error> { Err(Error::Syntax) }
|
||||
|
||||
// Compound types:
|
||||
fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut UsizeDecoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut UsizeDecoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_struct_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
// Specialized types:
|
||||
fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut UsizeDecoder, bool) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_seq<T, F>(&mut self, f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut UsizeDecoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
let len = self.len;
|
||||
f(self, len)
|
||||
}
|
||||
#[inline]
|
||||
fn read_seq_elt<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn read_map<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut UsizeDecoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_map_elt_key<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_map_elt_val<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct U8Decoder {
|
||||
len: usize,
|
||||
iter: vec::IntoIter<u8>,
|
||||
}
|
||||
|
||||
impl U8Decoder {
|
||||
#[inline]
|
||||
pub fn new(values: Vec<u8>) -> U8Decoder {
|
||||
U8Decoder {
|
||||
len: values.len(),
|
||||
iter: values.into_iter(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl rustc_serialize::Decoder for U8Decoder {
|
||||
type Error = Error;
|
||||
|
||||
fn error(&mut self, _: &str) -> Error { Error::Syntax }
|
||||
|
||||
// Primitive types:
|
||||
fn read_nil(&mut self) -> Result<(), Error> { Err(Error::Syntax) }
|
||||
fn read_usize(&mut self) -> Result<usize, Error> { Err(Error::Syntax) }
|
||||
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::Syntax) }
|
||||
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::Syntax) }
|
||||
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::Syntax) }
|
||||
#[inline]
|
||||
fn read_u8(&mut self) -> Result<u8, Error> {
|
||||
match self.iter.next() {
|
||||
Some(value) => Ok(value),
|
||||
None => Err(Error::EndOfStream),
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn read_isize(&mut self) -> Result<isize, Error> { Err(Error::Syntax) }
|
||||
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::Syntax) }
|
||||
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::Syntax) }
|
||||
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::Syntax) }
|
||||
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::Syntax) }
|
||||
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::Syntax) }
|
||||
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::Syntax) }
|
||||
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::Syntax) }
|
||||
fn read_char(&mut self) -> Result<char, Error> { Err(Error::Syntax) }
|
||||
fn read_str(&mut self) -> Result<String, Error> { Err(Error::Syntax) }
|
||||
|
||||
// Compound types:
|
||||
fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut U8Decoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut U8Decoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_struct_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
// Specialized types:
|
||||
fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut U8Decoder, bool) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_seq<T, F>(&mut self, f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut U8Decoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
let len = self.len;
|
||||
f(self, len)
|
||||
}
|
||||
#[inline]
|
||||
fn read_seq_elt<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn read_map<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut U8Decoder, usize) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_map_elt_key<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
|
||||
fn read_map_elt_val<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
||||
F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
|
||||
{
|
||||
Err(Error::Syntax)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
mod deserializer {
|
||||
//use std::num;
|
||||
use std::vec;
|
||||
|
||||
use super::Error;
|
||||
|
||||
use serde::de;
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
enum State {
|
||||
Start,
|
||||
SepOrEnd,
|
||||
End,
|
||||
}
|
||||
|
||||
pub struct Deserializer<A> {
|
||||
state: State,
|
||||
iter: vec::IntoIter<A>,
|
||||
len: usize,
|
||||
value: Option<A>,
|
||||
}
|
||||
|
||||
impl<A> Deserializer<A> {
|
||||
#[inline]
|
||||
pub fn new(values: Vec<A>) -> Deserializer<A> {
|
||||
let len = values.len();
|
||||
Deserializer {
|
||||
state: State::Start,
|
||||
iter: values.into_iter(),
|
||||
len: len,
|
||||
value: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl de::Deserializer for Deserializer<usize> {
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::Visitor,
|
||||
{
|
||||
match self.state {
|
||||
State::Start => {
|
||||
self.state = State::SepOrEnd;
|
||||
visitor.visit_seq(self)
|
||||
}
|
||||
State::SepOrEnd => {
|
||||
visitor.visit_usize(self.value.take().unwrap())
|
||||
}
|
||||
State::End => {
|
||||
Err(Error::EndOfStream)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl de::SeqVisitor for Deserializer<usize> {
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
||||
where T: de::Deserialize,
|
||||
{
|
||||
match self.iter.next() {
|
||||
Some(value) => {
|
||||
self.len -= 1;
|
||||
self.value = Some(value);
|
||||
Ok(Some(try!(de::Deserialize::deserialize(self))))
|
||||
}
|
||||
None => {
|
||||
self.state = State::End;
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn end(&mut self) -> Result<(), Error> {
|
||||
match self.iter.next() {
|
||||
Some(_) => Err(Error::Syntax),
|
||||
None => {
|
||||
self.state = State::End;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
(self.len, Some(self.len))
|
||||
}
|
||||
}
|
||||
|
||||
impl de::Deserializer for Deserializer<u8> {
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::Visitor,
|
||||
{
|
||||
match self.state {
|
||||
State::Start => {
|
||||
self.state = State::SepOrEnd;
|
||||
visitor.visit_seq(self)
|
||||
}
|
||||
State::SepOrEnd => {
|
||||
visitor.visit_u8(self.value.take().unwrap())
|
||||
}
|
||||
State::End => {
|
||||
Err(Error::EndOfStream)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl de::SeqVisitor for Deserializer<u8> {
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
||||
where T: de::Deserialize,
|
||||
{
|
||||
match self.iter.next() {
|
||||
Some(value) => {
|
||||
self.len -= 1;
|
||||
self.value = Some(value);
|
||||
Ok(Some(try!(de::Deserialize::deserialize(self))))
|
||||
}
|
||||
None => {
|
||||
self.state = State::End;
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn end(&mut self) -> Result<(), Error> {
|
||||
match self.iter.next() {
|
||||
Some(_) => Err(Error::Syntax),
|
||||
None => {
|
||||
self.state = State::End;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
(self.len, Some(self.len))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
fn run_decoder<
|
||||
D: Decoder<Error=Error>,
|
||||
T: Clone + PartialEq + Debug + Decodable
|
||||
>(mut d: D, value: T) {
|
||||
let v = Decodable::decode(&mut d);
|
||||
|
||||
assert_eq!(Ok(value), v);
|
||||
}
|
||||
|
||||
fn run_deserializer<D, T>(mut d: D, value: T)
|
||||
where D: Deserializer,
|
||||
D::Error: Debug + PartialEq,
|
||||
T: Clone + PartialEq + Debug + Deserialize
|
||||
{
|
||||
let v = T::deserialize(&mut d);
|
||||
|
||||
assert_eq!(Ok(value), v);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_decoder_usize_000(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let v: Vec<usize> = vec!();
|
||||
run_decoder(decoder::UsizeDecoder::new(v.clone()), v)
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_decoder_usize_003(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let v: Vec<usize> = vec!(1, 2, 3);
|
||||
run_decoder(decoder::UsizeDecoder::new(v.clone()), v)
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_decoder_usize_100(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let v: Vec<usize> = (0 .. 100).collect();
|
||||
run_decoder(decoder::UsizeDecoder::new(v.clone()), v)
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_decoder_u8_000(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let v: Vec<u8> = vec!();
|
||||
run_decoder(decoder::U8Decoder::new(v.clone()), v)
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_decoder_u8_003(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let v: Vec<u8> = vec!(1, 2, 3);
|
||||
run_decoder(decoder::U8Decoder::new(v.clone()), v)
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_decoder_u8_100(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let v: Vec<u8> = (0 .. 100).collect();
|
||||
run_decoder(decoder::U8Decoder::new(v.clone()), v)
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_deserializer_usize_000(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let v: Vec<usize> = vec!();
|
||||
run_deserializer(deserializer::Deserializer::new(v.clone()), v)
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_deserializer_usize_003(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let v: Vec<usize> = vec!(1, 2, 3);
|
||||
run_deserializer(deserializer::Deserializer::new(v.clone()), v)
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_deserializer_usize_100(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let v: Vec<usize> = (0 .. 100).collect();
|
||||
run_deserializer(deserializer::Deserializer::new(v.clone()), v)
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_deserializer_u8_000(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let v: Vec<u8> = vec!();
|
||||
run_deserializer(deserializer::Deserializer::new(v.clone()), v)
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_deserializer_u8_003(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let v: Vec<u8> = vec!(1, 2, 3);
|
||||
run_deserializer(deserializer::Deserializer::new(v.clone()), v)
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_deserializer_u8_100(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let v: Vec<u8> = (0 .. 100).collect();
|
||||
run_deserializer(deserializer::Deserializer::new(v.clone()), v)
|
||||
})
|
||||
}
|
||||
+3
-9
@@ -5,13 +5,7 @@ use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
|
||||
for &(src, dst) in &[
|
||||
("tests/test.rs.in", "test.rs"),
|
||||
("benches/bench.rs.in", "bench.rs"),
|
||||
] {
|
||||
let src = Path::new(src);
|
||||
let dst = Path::new(&out_dir).join(dst);
|
||||
serde_codegen::expand(&src, &dst).unwrap();
|
||||
}
|
||||
let src = Path::new("tests/test.rs.in");
|
||||
let dst = Path::new(&out_dir).join("test.rs");
|
||||
serde_codegen::expand(&src, &dst).unwrap();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user