Remove benchmarks
Nobody noticed these did not compile for 3 months, so I am guessing nobody cares. The JSON benchmarks at https://github.com/serde-rs/json-benchmark are much more relevant.
This commit is contained in:
parent
21c9446890
commit
536e78a146
@ -29,7 +29,3 @@ clippy = { version = "^0.*", optional = true }
|
|||||||
[[test]]
|
[[test]]
|
||||||
name = "test"
|
name = "test"
|
||||||
path = "tests/test.rs"
|
path = "tests/test.rs"
|
||||||
|
|
||||||
[[bench]]
|
|
||||||
name = "bench"
|
|
||||||
path = "benches/bench.rs"
|
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
#![feature(test)]
|
|
||||||
#![cfg_attr(feature = "clippy", feature(plugin))]
|
|
||||||
#![cfg_attr(feature = "clippy", plugin(clippy))]
|
|
||||||
|
|
||||||
extern crate rustc_serialize;
|
|
||||||
#[macro_use]
|
|
||||||
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,506 +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::{self, Deserialize};
|
|
||||||
|
|
||||||
#[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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
forward_to_deserialize! {
|
|
||||||
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str
|
|
||||||
string unit option seq seq_fixed_size bytes map unit_struct
|
|
||||||
newtype_struct tuple_struct struct struct_field tuple ignored_any
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_newtype<T>(&mut self) -> Result<T, Self::Error>
|
|
||||||
where T: Deserialize
|
|
||||||
{
|
|
||||||
Err(de::Error::invalid_type(de::Type::TupleVariant))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_tuple<V>(&mut self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: de::Visitor
|
|
||||||
{
|
|
||||||
Err(de::Error::invalid_type(de::Type::TupleVariant))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_struct<V>(&mut self, _fields: &'static [&'static str], _visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: de::Visitor
|
|
||||||
{
|
|
||||||
Err(de::Error::invalid_type(de::Type::StructVariant))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_unit(&mut self) -> Result<(), Error> {
|
|
||||||
Err(de::Error::invalid_type(de::Type::UnitVariant))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_newtype<T>(&mut self) -> Result<T, Self::Error>
|
|
||||||
where T: Deserialize
|
|
||||||
{
|
|
||||||
Err(de::Error::invalid_type(de::Type::TupleVariant))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_struct<V>(&mut self, _fields: &'static [&'static str], _visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: de::Visitor
|
|
||||||
{
|
|
||||||
Err(de::Error::invalid_type(de::Type::StructVariant))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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,481 +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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
forward_to_deserialize! {
|
|
||||||
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str
|
|
||||||
string unit option seq seq_fixed_size bytes map unit_struct
|
|
||||||
newtype_struct tuple_struct struct struct_field tuple enum
|
|
||||||
ignored_any
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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,751 +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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
forward_to_deserialize! {
|
|
||||||
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str
|
|
||||||
string unit option seq seq_fixed_size bytes map unit_struct
|
|
||||||
newtype_struct tuple_struct struct_field tuple enum ignored_any
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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,642 +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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
forward_to_deserialize! {
|
|
||||||
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str
|
|
||||||
string unit option seq seq_fixed_size bytes map unit_struct
|
|
||||||
newtype_struct tuple_struct struct struct_field tuple enum
|
|
||||||
ignored_any
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
forward_to_deserialize! {
|
|
||||||
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str
|
|
||||||
string unit option seq seq_fixed_size bytes map unit_struct
|
|
||||||
newtype_struct tuple_struct struct struct_field tuple enum
|
|
||||||
ignored_any
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
})
|
|
||||||
}
|
|
@ -5,13 +5,7 @@ use std::path::Path;
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||||
|
let src = Path::new("tests/test.rs.in");
|
||||||
for &(src, dst) in &[
|
let dst = Path::new(&out_dir).join("test.rs");
|
||||||
("tests/test.rs.in", "test.rs"),
|
serde_codegen::expand(&src, &dst).unwrap();
|
||||||
("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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user