mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-08-04 16:45:44 +00:00
@@ -1,3 +1,2 @@
|
|||||||
/target/
|
/target/
|
||||||
/Cargo.lock
|
/Cargo.lock
|
||||||
/serde2/Cargo.lock
|
|
||||||
|
|||||||
+2
-4
@@ -1,15 +1,13 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
path = "src/lib.rs"
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rustc-serialize = "*"
|
rustc-serialize = "*"
|
||||||
|
|
||||||
[dependencies.serde_macros]
|
[dev-dependencies.serde_macros]
|
||||||
path = "serde_macros/"
|
path = "serde_macros/"
|
||||||
|
|||||||
+118
-77
@@ -1,4 +1,4 @@
|
|||||||
#![feature(plugin, test)]
|
#![feature(custom_derive, plugin, test)]
|
||||||
#![plugin(serde_macros)]
|
#![plugin(serde_macros)]
|
||||||
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
@@ -26,9 +26,16 @@ enum Animal {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
EndOfStream,
|
EndOfStreamError,
|
||||||
SyntaxError,
|
SyntaxError,
|
||||||
OtherError(String),
|
}
|
||||||
|
|
||||||
|
impl serde::de::Error for Error {
|
||||||
|
fn syntax_error() -> Error { Error::SyntaxError }
|
||||||
|
|
||||||
|
fn end_of_stream_error() -> Error { Error::EndOfStreamError }
|
||||||
|
|
||||||
|
fn missing_field_error(_: &'static str) -> Error { Error::SyntaxError }
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -38,7 +45,6 @@ mod decoder {
|
|||||||
|
|
||||||
use super::{Animal, Error};
|
use super::{Animal, Error};
|
||||||
use super::Animal::{Dog, Frog};
|
use super::Animal::{Dog, Frog};
|
||||||
use super::Error::{SyntaxError, OtherError};
|
|
||||||
use self::State::{AnimalState, IsizeState, StringState};
|
use self::State::{AnimalState, IsizeState, StringState};
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
@@ -64,37 +70,35 @@ mod decoder {
|
|||||||
impl Decoder for AnimalDecoder {
|
impl Decoder for AnimalDecoder {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn error(&mut self, msg: &str) -> Error {
|
fn error(&mut self, _: &str) -> Error { Error::SyntaxError }
|
||||||
OtherError(msg.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Primitive types:
|
// Primitive types:
|
||||||
fn read_nil(&mut self) -> Result<(), Error> { Err(SyntaxError) }
|
fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) }
|
||||||
fn read_usize(&mut self) -> Result<usize, Error> { Err(SyntaxError) }
|
fn read_usize(&mut self) -> Result<usize, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_u64(&mut self) -> Result<u64, Error> { Err(SyntaxError) }
|
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_u32(&mut self) -> Result<u32, Error> { Err(SyntaxError) }
|
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_u16(&mut self) -> Result<u16, Error> { Err(SyntaxError) }
|
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_u8(&mut self) -> Result<u8, Error> { Err(SyntaxError) }
|
fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::SyntaxError) }
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_isize(&mut self) -> Result<isize, Error> {
|
fn read_isize(&mut self) -> Result<isize, Error> {
|
||||||
match self.stack.pop() {
|
match self.stack.pop() {
|
||||||
Some(IsizeState(x)) => Ok(x),
|
Some(IsizeState(x)) => Ok(x),
|
||||||
_ => Err(SyntaxError),
|
_ => Err(Error::SyntaxError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn read_i64(&mut self) -> Result<i64, Error> { Err(SyntaxError) }
|
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_i32(&mut self) -> Result<i32, Error> { Err(SyntaxError) }
|
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_i16(&mut self) -> Result<i16, Error> { Err(SyntaxError) }
|
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_i8(&mut self) -> Result<i8, Error> { Err(SyntaxError) }
|
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_bool(&mut self) -> Result<bool, Error> { Err(SyntaxError) }
|
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_f64(&mut self) -> Result<f64, Error> { Err(SyntaxError) }
|
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_f32(&mut self) -> Result<f32, Error> { Err(SyntaxError) }
|
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_char(&mut self) -> Result<char, Error> { Err(SyntaxError) }
|
fn read_char(&mut self) -> Result<char, Error> { Err(Error::SyntaxError) }
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_str(&mut self) -> Result<String, Error> {
|
fn read_str(&mut self) -> Result<String, Error> {
|
||||||
match self.stack.pop() {
|
match self.stack.pop() {
|
||||||
Some(StringState(x)) => Ok(x),
|
Some(StringState(x)) => Ok(x),
|
||||||
_ => Err(SyntaxError),
|
_ => Err(Error::SyntaxError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,10 +113,10 @@ mod decoder {
|
|||||||
if name == "Animal" {
|
if name == "Animal" {
|
||||||
f(self)
|
f(self)
|
||||||
} else {
|
} else {
|
||||||
Err(SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Err(SyntaxError)
|
_ => Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,12 +131,12 @@ mod decoder {
|
|||||||
self.stack.push(StringState(x0));
|
self.stack.push(StringState(x0));
|
||||||
"Frog"
|
"Frog"
|
||||||
}
|
}
|
||||||
_ => { return Err(SyntaxError); }
|
_ => { return Err(Error::SyntaxError); }
|
||||||
};
|
};
|
||||||
|
|
||||||
let idx = match names.iter().position(|n| *n == name) {
|
let idx = match names.iter().position(|n| *n == name) {
|
||||||
Some(idx) => idx,
|
Some(idx) => idx,
|
||||||
None => { return Err(SyntaxError); }
|
None => { return Err(Error::SyntaxError); }
|
||||||
};
|
};
|
||||||
|
|
||||||
f(self, idx)
|
f(self, idx)
|
||||||
@@ -197,7 +201,7 @@ mod decoder {
|
|||||||
fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut AnimalDecoder, bool) -> Result<T, Error>,
|
F: FnOnce(&mut AnimalDecoder, bool) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -217,19 +221,19 @@ mod decoder {
|
|||||||
fn read_map<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
fn read_map<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut AnimalDecoder, usize) -> Result<T, Error>,
|
F: FnOnce(&mut AnimalDecoder, usize) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_map_elt_key<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
fn read_map_elt_key<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
|
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_map_elt_val<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
fn read_map_elt_val<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
|
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -238,9 +242,6 @@ mod decoder {
|
|||||||
|
|
||||||
mod deserializer {
|
mod deserializer {
|
||||||
use super::{Animal, Error};
|
use super::{Animal, Error};
|
||||||
use super::Animal::{Dog, Frog};
|
|
||||||
use super::Error::{EndOfStream, SyntaxError};
|
|
||||||
use self::State::{AnimalState, IsizeState, StringState, EndState};
|
|
||||||
|
|
||||||
use serde::de;
|
use serde::de;
|
||||||
|
|
||||||
@@ -248,8 +249,7 @@ mod deserializer {
|
|||||||
AnimalState(Animal),
|
AnimalState(Animal),
|
||||||
IsizeState(isize),
|
IsizeState(isize),
|
||||||
StringState(String),
|
StringState(String),
|
||||||
EndState,
|
UnitState,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AnimalDeserializer {
|
pub struct AnimalDeserializer {
|
||||||
@@ -260,67 +260,108 @@ mod deserializer {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(animal: Animal) -> AnimalDeserializer {
|
pub fn new(animal: Animal) -> AnimalDeserializer {
|
||||||
AnimalDeserializer {
|
AnimalDeserializer {
|
||||||
stack: vec!(AnimalState(animal)),
|
stack: vec!(State::AnimalState(animal)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for AnimalDeserializer {
|
impl de::Deserializer for AnimalDeserializer {
|
||||||
type Item = Result<de::Token, Error>;
|
type Error = Error;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<Result<de::Token, Error>> {
|
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
|
where V: de::Visitor,
|
||||||
|
{
|
||||||
match self.stack.pop() {
|
match self.stack.pop() {
|
||||||
Some(AnimalState(Dog)) => {
|
Some(State::AnimalState(Animal::Dog)) => {
|
||||||
self.stack.push(EndState);
|
self.stack.push(State::UnitState);
|
||||||
Some(Ok(de::Token::EnumStart("Animal", "Dog", 0)))
|
visitor.visit_enum("Animal", "Dog", DogVisitor {
|
||||||
|
de: self,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
Some(AnimalState(Frog(x0, x1))) => {
|
Some(State::AnimalState(Animal::Frog(x0, x1))) => {
|
||||||
self.stack.push(EndState);
|
self.stack.push(State::IsizeState(x1));
|
||||||
self.stack.push(IsizeState(x1));
|
self.stack.push(State::StringState(x0));
|
||||||
self.stack.push(StringState(x0));
|
visitor.visit_enum("Animal", "Frog", FrogVisitor {
|
||||||
Some(Ok(de::Token::EnumStart("Animal", "Frog", 2)))
|
de: self,
|
||||||
|
state: 0,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
Some(IsizeState(x)) => {
|
Some(State::IsizeState(value)) => {
|
||||||
Some(Ok(de::Token::Isize(x)))
|
visitor.visit_isize(value)
|
||||||
}
|
}
|
||||||
Some(StringState(x)) => {
|
Some(State::StringState(value)) => {
|
||||||
Some(Ok(de::Token::String(x)))
|
visitor.visit_string(value)
|
||||||
}
|
}
|
||||||
Some(EndState) => {
|
Some(State::UnitState) => {
|
||||||
Some(Ok(de::Token::End))
|
visitor.visit_unit()
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
Err(Error::EndOfStreamError)
|
||||||
}
|
}
|
||||||
None => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl de::Deserializer<Error> for AnimalDeserializer {
|
struct DogVisitor<'a> {
|
||||||
#[inline]
|
de: &'a mut AnimalDeserializer,
|
||||||
fn end_of_stream_error(&mut self) -> Error {
|
}
|
||||||
EndOfStream
|
|
||||||
|
impl<'a> de::EnumVisitor for DogVisitor<'a> {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn visit_unit(&mut self) -> Result<(), Error> {
|
||||||
|
de::Deserialize::deserialize(self.de)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FrogVisitor<'a> {
|
||||||
|
de: &'a mut AnimalDeserializer,
|
||||||
|
state: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> de::EnumVisitor for FrogVisitor<'a> {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
|
where V: de::EnumSeqVisitor,
|
||||||
|
{
|
||||||
|
visitor.visit(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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn end(&mut self) -> Result<(), Error> {
|
||||||
fn syntax_error(&mut self, _token: de::Token, _expected: &[de::TokenKind]) -> Error {
|
if self.state == 2 {
|
||||||
SyntaxError
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(Error::SyntaxError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
fn unexpected_name_error(&mut self, _token: de::Token) -> Error {
|
let len = 2 - self.state;
|
||||||
SyntaxError
|
(len, Some(len))
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn conversion_error(&mut self, _token: de::Token) -> Error {
|
|
||||||
SyntaxError
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn missing_field<
|
|
||||||
T: de::Deserialize<AnimalDeserializer, Error>
|
|
||||||
>(&mut self, _field: &'static str) -> Result<T, Error> {
|
|
||||||
Err(SyntaxError)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+91
-573
@@ -1,4 +1,4 @@
|
|||||||
#![feature(collections, core, io, plugin, test)]
|
#![feature(custom_derive, collections, core, io, plugin, test)]
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
#![plugin(serde_macros)]
|
#![plugin(serde_macros)]
|
||||||
|
|
||||||
@@ -10,11 +10,10 @@ use std::io::{self, ReadExt, WriteExt};
|
|||||||
use std::num::FromPrimitive;
|
use std::num::FromPrimitive;
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
|
|
||||||
use serde::de;
|
use serde::de::{self, Deserialize, Deserializer};
|
||||||
use serde::json::ser::escape_str;
|
use serde::json::ser::escape_str;
|
||||||
use serde::json;
|
use serde::json;
|
||||||
use serde::ser::Serialize;
|
use serde::ser::{self, Serialize, Serializer};
|
||||||
use serde::ser;
|
|
||||||
|
|
||||||
use rustc_serialize::Encodable;
|
use rustc_serialize::Encodable;
|
||||||
|
|
||||||
@@ -48,24 +47,28 @@ impl rustc_serialize::Encodable for HttpProtocol {
|
|||||||
|
|
||||||
impl rustc_serialize::Decodable for HttpProtocol {
|
impl rustc_serialize::Decodable for HttpProtocol {
|
||||||
fn decode<D: rustc_serialize::Decoder>(d: &mut D) -> Result<HttpProtocol, D::Error> {
|
fn decode<D: rustc_serialize::Decoder>(d: &mut D) -> Result<HttpProtocol, D::Error> {
|
||||||
match FromPrimitive::from_uint(try!(d.read_usize())) {
|
match FromPrimitive::from_usize(try!(d.read_usize())) {
|
||||||
Some(value) => Ok(value),
|
Some(value) => Ok(value),
|
||||||
None => Err(d.error("cannot convert from usize")),
|
None => Err(d.error("cannot convert from usize")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: ser::Serializer<E>, E> ser::Serialize<S, E> for HttpProtocol {
|
impl ser::Serialize for HttpProtocol {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E> {
|
fn visit<
|
||||||
s.serialize_u8(*self as u8)
|
V: ser::Visitor,
|
||||||
|
>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
|
||||||
|
visitor.visit_u8(*self as u8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: de::Deserializer<E>, E> de::Deserialize<D, E> for HttpProtocol {
|
impl de::Deserialize for HttpProtocol {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize_token(d: &mut D, token: de::Token) -> Result<HttpProtocol, E> {
|
fn deserialize<
|
||||||
d.expect_from_primitive(token)
|
S: Deserializer,
|
||||||
|
>(state: &mut S) -> Result<HttpProtocol, S::Error> {
|
||||||
|
state.visit(de::PrimitiveVisitor::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,24 +95,28 @@ impl rustc_serialize::Encodable for HttpMethod {
|
|||||||
|
|
||||||
impl rustc_serialize::Decodable for HttpMethod {
|
impl rustc_serialize::Decodable for HttpMethod {
|
||||||
fn decode<D: rustc_serialize::Decoder>(d: &mut D) -> Result<HttpMethod, D::Error> {
|
fn decode<D: rustc_serialize::Decoder>(d: &mut D) -> Result<HttpMethod, D::Error> {
|
||||||
match FromPrimitive::from_uint(try!(d.read_usize())) {
|
match FromPrimitive::from_usize(try!(d.read_usize())) {
|
||||||
Some(value) => Ok(value),
|
Some(value) => Ok(value),
|
||||||
None => Err(d.error("cannot convert from usize")),
|
None => Err(d.error("cannot convert from usize")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: ser::Serializer<E>, E> ser::Serialize<S, E> for HttpMethod {
|
impl ser::Serialize for HttpMethod {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E> {
|
fn visit<
|
||||||
s.serialize_u8(*self as u8)
|
V: ser::Visitor,
|
||||||
|
>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
|
||||||
|
visitor.visit_u8(*self as u8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: de::Deserializer<E>, E> de::Deserialize<D, E> for HttpMethod {
|
impl de::Deserialize for HttpMethod {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize_token(d: &mut D, token: de::Token) -> Result<HttpMethod, E> {
|
fn deserialize<
|
||||||
d.expect_from_primitive(token)
|
S: de::Deserializer,
|
||||||
|
>(state: &mut S) -> Result<HttpMethod, S::Error> {
|
||||||
|
state.visit(de::PrimitiveVisitor::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,17 +143,21 @@ impl rustc_serialize::Decodable for CacheStatus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: ser::Serializer<E>, E> ser::Serialize<S, E> for CacheStatus {
|
impl ser::Serialize for CacheStatus {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E> {
|
fn visit<
|
||||||
s.serialize_usize(*self as usize)
|
V: ser::Visitor,
|
||||||
|
>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
|
||||||
|
visitor.visit_u8(*self as u8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: de::Deserializer<E>, E> de::Deserialize<D, E> for CacheStatus {
|
impl de::Deserialize for CacheStatus {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize_token(d: &mut D, token: de::Token) -> Result<CacheStatus, E> {
|
fn deserialize<
|
||||||
d.expect_from_primitive(token)
|
S: de::Deserializer,
|
||||||
|
>(state: &mut S) -> Result<CacheStatus, S::Error> {
|
||||||
|
state.visit(de::PrimitiveVisitor::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,17 +193,21 @@ impl rustc_serialize::Decodable for OriginProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: ser::Serializer<E>, E> ser::Serialize<S, E> for OriginProtocol {
|
impl ser::Serialize for OriginProtocol {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E> {
|
fn visit<
|
||||||
s.serialize_u8(*self as u8)
|
V: ser::Visitor,
|
||||||
|
>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
|
||||||
|
visitor.visit_u8(*self as u8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: de::Deserializer<E>, E> de::Deserialize<D, E> for OriginProtocol {
|
impl de::Deserialize for OriginProtocol {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize_token(d: &mut D, token: de::Token) -> Result<OriginProtocol, E> {
|
fn deserialize<
|
||||||
d.expect_from_primitive(token)
|
S: de::Deserializer,
|
||||||
|
>(state: &mut S) -> Result<OriginProtocol, S::Error> {
|
||||||
|
state.visit(de::PrimitiveVisitor::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,17 +235,21 @@ impl rustc_serialize::Decodable for ZonePlan {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: ser::Serializer<E>, E> ser::Serialize<S, E> for ZonePlan {
|
impl ser::Serialize for ZonePlan {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E> {
|
fn visit<
|
||||||
s.serialize_u8(*self as u8)
|
V: ser::Visitor,
|
||||||
|
>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
|
||||||
|
visitor.visit_u8(*self as u8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: de::Deserializer<E>, E> de::Deserialize<D, E> for ZonePlan {
|
impl de::Deserialize for ZonePlan {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize_token(d: &mut D, token: de::Token) -> Result<ZonePlan, E> {
|
fn deserialize<
|
||||||
d.expect_from_primitive(token)
|
S: de::Deserializer,
|
||||||
|
>(state: &mut S) -> Result<ZonePlan, S::Error> {
|
||||||
|
state.visit(de::PrimitiveVisitor::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,17 +528,21 @@ impl rustc_serialize::Decodable for Country {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: ser::Serializer<E>, E> ser::Serialize<S, E> for Country {
|
impl ser::Serialize for Country {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E> {
|
fn visit<
|
||||||
s.serialize_u8(*self as u8)
|
V: ser::Visitor,
|
||||||
|
>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
|
||||||
|
visitor.visit_u8(*self as u8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: de::Deserializer<E>, E> de::Deserialize<D, E> for Country {
|
impl de::Deserialize for Country {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize_token(d: &mut D, token: de::Token) -> Result<Country, E> {
|
fn deserialize<
|
||||||
d.expect_from_primitive(token)
|
S: de::Deserializer,
|
||||||
|
>(state: &mut S) -> Result<Country, S::Error> {
|
||||||
|
state.visit(de::PrimitiveVisitor::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -652,7 +675,7 @@ fn push_all_bytes(dst: &mut Vec<u8>, src: &[u8]) {
|
|||||||
// we would have failed if `reserve` overflowed.
|
// we would have failed if `reserve` overflowed.
|
||||||
dst.set_len(dst_len + src_len);
|
dst.set_len(dst_len + src_len);
|
||||||
|
|
||||||
::std::ptr::copy_nonoverlapping_memory(
|
::std::ptr::copy_nonoverlapping(
|
||||||
dst.as_mut_ptr().offset(dst_len as isize),
|
dst.as_mut_ptr().offset(dst_len as isize),
|
||||||
src.as_ptr(),
|
src.as_ptr(),
|
||||||
src_len);
|
src_len);
|
||||||
@@ -687,7 +710,7 @@ fn test_encoder() {
|
|||||||
log.encode(&mut encoder).unwrap();
|
log.encode(&mut encoder).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(&wr[], JSON_STR);
|
assert_eq!(&wr, &JSON_STR);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
@@ -734,10 +757,10 @@ fn test_serializer_vec() {
|
|||||||
let log = Log::new();
|
let log = Log::new();
|
||||||
let wr = Vec::with_capacity(1024);
|
let wr = Vec::with_capacity(1024);
|
||||||
let mut serializer = json::Serializer::new(wr);
|
let mut serializer = json::Serializer::new(wr);
|
||||||
log.serialize(&mut serializer).unwrap();
|
serializer.visit(&log).unwrap();
|
||||||
|
|
||||||
let json = serializer.unwrap();
|
let json = serializer.into_inner();
|
||||||
assert_eq!(&json[], JSON_STR.as_bytes());
|
assert_eq!(&json, &JSON_STR.as_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
@@ -752,8 +775,8 @@ fn bench_serializer_vec(b: &mut Bencher) {
|
|||||||
wr.clear();
|
wr.clear();
|
||||||
|
|
||||||
let mut serializer = json::Serializer::new(wr.by_ref());
|
let mut serializer = json::Serializer::new(wr.by_ref());
|
||||||
log.serialize(&mut serializer).unwrap();
|
serializer.visit(&log).unwrap();
|
||||||
let _json = serializer.unwrap();
|
let _json = serializer.into_inner();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -767,11 +790,11 @@ fn bench_serializer_slice(b: &mut Bencher) {
|
|||||||
|
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
for item in buf.iter_mut(){ *item = 0; }
|
for item in buf.iter_mut(){ *item = 0; }
|
||||||
let mut wr = &mut buf[];
|
let mut wr = &mut buf[..];
|
||||||
|
|
||||||
let mut serializer = json::Serializer::new(wr.by_ref());
|
let mut serializer = json::Serializer::new(wr.by_ref());
|
||||||
log.serialize(&mut serializer).unwrap();
|
serializer.visit(&log).unwrap();
|
||||||
let _json = serializer.unwrap();
|
let _json = serializer.into_inner();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -783,10 +806,11 @@ fn test_serializer_my_mem_writer0() {
|
|||||||
|
|
||||||
{
|
{
|
||||||
let mut serializer = json::Serializer::new(wr.by_ref());
|
let mut serializer = json::Serializer::new(wr.by_ref());
|
||||||
log.serialize(&mut serializer).unwrap();
|
serializer.visit(&log).unwrap();
|
||||||
|
let _json = serializer.into_inner();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(&wr.buf[], JSON_STR.as_bytes());
|
assert_eq!(&wr.buf, &JSON_STR.as_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
@@ -801,8 +825,8 @@ fn bench_serializer_my_mem_writer0(b: &mut Bencher) {
|
|||||||
wr.buf.clear();
|
wr.buf.clear();
|
||||||
|
|
||||||
let mut serializer = json::Serializer::new(wr.by_ref());
|
let mut serializer = json::Serializer::new(wr.by_ref());
|
||||||
log.serialize(&mut serializer).unwrap();
|
serializer.visit(&log).unwrap();
|
||||||
let _json = serializer.unwrap();
|
let _json = serializer.into_inner();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -814,10 +838,11 @@ fn test_serializer_my_mem_writer1() {
|
|||||||
|
|
||||||
{
|
{
|
||||||
let mut serializer = json::Serializer::new(wr.by_ref());
|
let mut serializer = json::Serializer::new(wr.by_ref());
|
||||||
log.serialize(&mut serializer).unwrap();
|
serializer.visit(&log).unwrap();
|
||||||
|
let _json = serializer.into_inner();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(&wr.buf[], JSON_STR.as_bytes());
|
assert_eq!(&wr.buf, &JSON_STR.as_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
@@ -832,8 +857,8 @@ fn bench_serializer_my_mem_writer1(b: &mut Bencher) {
|
|||||||
wr.buf.clear();
|
wr.buf.clear();
|
||||||
|
|
||||||
let mut serializer = json::Serializer::new(wr.by_ref());
|
let mut serializer = json::Serializer::new(wr.by_ref());
|
||||||
log.serialize(&mut serializer).unwrap();
|
serializer.visit(&log).unwrap();
|
||||||
let _json = serializer.unwrap();
|
let _json = serializer.into_inner();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1017,7 +1042,7 @@ fn test_manual_serialize_vec_no_escape() {
|
|||||||
manual_serialize_no_escape(&mut wr, &log);
|
manual_serialize_no_escape(&mut wr, &log);
|
||||||
|
|
||||||
let json = String::from_utf8(wr).unwrap();
|
let json = String::from_utf8(wr).unwrap();
|
||||||
assert_eq!(JSON_STR, &json[]);
|
assert_eq!(&JSON_STR, &json);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
@@ -1042,7 +1067,7 @@ fn test_manual_serialize_vec_escape() {
|
|||||||
manual_serialize_escape(&mut wr, &log);
|
manual_serialize_escape(&mut wr, &log);
|
||||||
|
|
||||||
let json = String::from_utf8(wr).unwrap();
|
let json = String::from_utf8(wr).unwrap();
|
||||||
assert_eq!(JSON_STR, &json[]);
|
assert_eq!(&JSON_STR, &json);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
@@ -1068,7 +1093,7 @@ fn test_manual_serialize_my_mem_writer0_no_escape() {
|
|||||||
manual_serialize_no_escape(&mut wr, &log);
|
manual_serialize_no_escape(&mut wr, &log);
|
||||||
|
|
||||||
let json = String::from_utf8(wr.buf).unwrap();
|
let json = String::from_utf8(wr.buf).unwrap();
|
||||||
assert_eq!(JSON_STR, &json[]);
|
assert_eq!(&JSON_STR, &json);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
@@ -1094,7 +1119,7 @@ fn test_manual_serialize_my_mem_writer0_escape() {
|
|||||||
manual_serialize_escape(&mut wr, &log);
|
manual_serialize_escape(&mut wr, &log);
|
||||||
|
|
||||||
let json = String::from_utf8(wr.buf).unwrap();
|
let json = String::from_utf8(wr.buf).unwrap();
|
||||||
assert_eq!(JSON_STR, &json[]);
|
assert_eq!(&JSON_STR, &json);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
@@ -1120,7 +1145,7 @@ fn test_manual_serialize_my_mem_writer1_no_escape() {
|
|||||||
manual_serialize_no_escape(&mut wr, &log);
|
manual_serialize_no_escape(&mut wr, &log);
|
||||||
|
|
||||||
let json = String::from_utf8(wr.buf).unwrap();
|
let json = String::from_utf8(wr.buf).unwrap();
|
||||||
assert_eq!(JSON_STR, &json[]);
|
assert_eq!(&JSON_STR, &json);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
@@ -1146,7 +1171,7 @@ fn test_manual_serialize_my_mem_writer1_escape() {
|
|||||||
manual_serialize_escape(&mut wr, &log);
|
manual_serialize_escape(&mut wr, &log);
|
||||||
|
|
||||||
let json = String::from_utf8(wr.buf).unwrap();
|
let json = String::from_utf8(wr.buf).unwrap();
|
||||||
assert_eq!(JSON_STR, &json[]);
|
assert_eq!(&JSON_STR, &json);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
@@ -1164,116 +1189,6 @@ fn bench_manual_serialize_my_mem_writer1_escape(b: &mut Bencher) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn direct<W: io::Write>(wr: &mut W, log: &Log) {
|
|
||||||
use serde::ser::Serializer;
|
|
||||||
|
|
||||||
let mut serializer = json::Serializer::new(wr.by_ref());
|
|
||||||
|
|
||||||
serializer.serialize_struct_start("Log", 12).unwrap();
|
|
||||||
|
|
||||||
serializer.serialize_struct_elt("timestamp", &log.timestamp).unwrap();
|
|
||||||
serializer.serialize_struct_elt("zone_id", &log.zone_id).unwrap();
|
|
||||||
serializer.serialize_struct_elt("zone_plan", &(log.zone_plan as usize)).unwrap();
|
|
||||||
serializer.serialize_struct_elt("http", &log.http).unwrap();
|
|
||||||
serializer.serialize_struct_elt("origin", &log.origin).unwrap();
|
|
||||||
serializer.serialize_struct_elt("country", &(log.country as usize)).unwrap();
|
|
||||||
serializer.serialize_struct_elt("cache_status", &(log.cache_status as usize)).unwrap();
|
|
||||||
serializer.serialize_struct_elt("server_ip", &log.server_ip).unwrap();
|
|
||||||
serializer.serialize_struct_elt("server_name", &log.server_name).unwrap();
|
|
||||||
serializer.serialize_struct_elt("remote_ip", &log.remote_ip).unwrap();
|
|
||||||
serializer.serialize_struct_elt("bytes_dlv", &log.bytes_dlv).unwrap();
|
|
||||||
serializer.serialize_struct_elt("ray_id", &log.ray_id).unwrap();
|
|
||||||
|
|
||||||
serializer.serialize_struct_end().unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_direct_vec() {
|
|
||||||
let log = Log::new();
|
|
||||||
|
|
||||||
let mut wr = Vec::with_capacity(1024);
|
|
||||||
direct(&mut wr, &log);
|
|
||||||
|
|
||||||
let json = String::from_utf8(wr).unwrap();
|
|
||||||
assert_eq!(JSON_STR, &json[]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_direct_vec(b: &mut Bencher) {
|
|
||||||
let log = Log::new();
|
|
||||||
|
|
||||||
let mut wr = Vec::with_capacity(1024);
|
|
||||||
direct(&mut wr, &log);
|
|
||||||
b.bytes = wr.len() as u64;
|
|
||||||
|
|
||||||
b.iter(|| {
|
|
||||||
let mut wr = Vec::with_capacity(1024);
|
|
||||||
direct(&mut wr, &log);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_direct_my_mem_writer0() {
|
|
||||||
let log = Log::new();
|
|
||||||
|
|
||||||
let mut wr = MyMemWriter0::with_capacity(1024);
|
|
||||||
direct(&mut wr, &log);
|
|
||||||
|
|
||||||
let json = String::from_utf8(wr.buf).unwrap();
|
|
||||||
assert_eq!(JSON_STR, &json[]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_direct_my_mem_writer0(b: &mut Bencher) {
|
|
||||||
let log = Log::new();
|
|
||||||
|
|
||||||
let mut wr = MyMemWriter0::with_capacity(1024);
|
|
||||||
direct(&mut wr, &log);
|
|
||||||
b.bytes = wr.buf.len() as u64;
|
|
||||||
|
|
||||||
b.iter(|| {
|
|
||||||
wr.buf.clear();
|
|
||||||
|
|
||||||
direct(&mut wr, &log);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_direct_my_mem_writer1() {
|
|
||||||
let log = Log::new();
|
|
||||||
|
|
||||||
let mut wr = MyMemWriter1::with_capacity(1024);
|
|
||||||
direct(&mut wr, &log);
|
|
||||||
|
|
||||||
let json = String::from_utf8(wr.buf).unwrap();
|
|
||||||
assert_eq!(JSON_STR, &json[]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_direct_my_mem_writer1(b: &mut Bencher) {
|
|
||||||
let log = Log::new();
|
|
||||||
|
|
||||||
let mut wr = MyMemWriter1::with_capacity(1024);
|
|
||||||
direct(&mut wr, &log);
|
|
||||||
b.bytes = wr.buf.len() as u64;
|
|
||||||
|
|
||||||
b.iter(|| {
|
|
||||||
wr.buf.clear();
|
|
||||||
|
|
||||||
direct(&mut wr, &log);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_decoder() {
|
|
||||||
use rustc_serialize::json::Json;
|
|
||||||
|
|
||||||
let json = Json::from_str(JSON_STR).unwrap();
|
|
||||||
let mut decoder = rustc_serialize::json::Decoder::new(json);
|
|
||||||
let log: Log = rustc_serialize::Decodable::decode(&mut decoder).unwrap();
|
|
||||||
assert_eq!(log, Log::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_decoder(b: &mut Bencher) {
|
fn bench_decoder(b: &mut Bencher) {
|
||||||
use rustc_serialize::json::Json;
|
use rustc_serialize::json::Json;
|
||||||
@@ -1287,299 +1202,6 @@ fn bench_decoder(b: &mut Bencher) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_deserializer() {
|
|
||||||
let log: Log = json::from_str(JSON_STR).unwrap();
|
|
||||||
assert_eq!(log, Log::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn manual_reader_ignore<R: Reader>(rdr: &mut R, buf: &mut [u8], key: &[u8]) {
|
|
||||||
let buf = &mut buf[0..key.len()];
|
|
||||||
rdr.read(buf).unwrap();
|
|
||||||
assert_eq!(buf, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn manual_reader_field<R: Reader>(rdr: &mut R, buf: &mut [u8], key: &[u8]) {
|
|
||||||
let b = rdr.read_byte().unwrap();
|
|
||||||
assert_eq!(b, b'"');
|
|
||||||
|
|
||||||
manual_reader_ignore(rdr, buf, key);
|
|
||||||
|
|
||||||
let b = rdr.read_byte().unwrap();
|
|
||||||
assert_eq!(b, b'"');
|
|
||||||
|
|
||||||
let b = rdr.read_byte().unwrap();
|
|
||||||
assert_eq!(b, b':');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn manual_reader_int<R: Reader>(rdr: &mut R, buf: &mut [u8], key: &[u8]) -> i64 {
|
|
||||||
manual_reader_field(rdr, buf, key);
|
|
||||||
|
|
||||||
let mut res = 0;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let byte = rdr.read_byte().unwrap();
|
|
||||||
match byte {
|
|
||||||
b'0' ... b'9' => {
|
|
||||||
res *= 10;
|
|
||||||
res += (byte as i64) - (b'0' as i64);
|
|
||||||
}
|
|
||||||
_ => { break; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn manual_reader_string<R: Reader>(rdr: &mut R, buf: &mut [u8], key: &[u8]) -> String {
|
|
||||||
manual_reader_field(rdr, buf, key);
|
|
||||||
manual_reader_ignore(rdr, buf, b"\"");
|
|
||||||
|
|
||||||
let mut idx = 0;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let byte = rdr.read_byte().unwrap();
|
|
||||||
match byte {
|
|
||||||
b'"' => { break; }
|
|
||||||
byte => { buf[idx] = byte; }
|
|
||||||
};
|
|
||||||
|
|
||||||
idx += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
let b = rdr.read_byte().unwrap();
|
|
||||||
assert!(b == b',' || b == b']' || b == b'}');
|
|
||||||
|
|
||||||
String::from_utf8(buf[..idx].to_vec()).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn manual_reader_deserialize<R: Reader>(rdr: &mut R) -> Log {
|
|
||||||
let mut buf = [0; 128];
|
|
||||||
|
|
||||||
manual_reader_ignore(rdr, &mut buf, b"{");
|
|
||||||
let timestamp = manual_reader_int(rdr, &mut buf, b"timestamp");
|
|
||||||
let zone_id = manual_reader_int(rdr, &mut buf, b"zone_id");
|
|
||||||
let zone_plan = manual_reader_int(rdr, &mut buf, b"zone_plan");
|
|
||||||
|
|
||||||
manual_reader_field(rdr, &mut buf, b"http");
|
|
||||||
manual_reader_ignore(rdr, &mut buf, b"{");
|
|
||||||
|
|
||||||
let protocol = manual_reader_int(rdr, &mut buf, b"protocol");
|
|
||||||
let status = manual_reader_int(rdr, &mut buf, b"status");
|
|
||||||
let host_status = manual_reader_int(rdr, &mut buf, b"host_status");
|
|
||||||
let up_status = manual_reader_int(rdr, &mut buf, b"up_status");
|
|
||||||
let method = manual_reader_int(rdr, &mut buf, b"method");
|
|
||||||
let content_type = manual_reader_string(rdr, &mut buf, b"content_type");
|
|
||||||
let user_agent = manual_reader_string(rdr, &mut buf, b"user_agent");
|
|
||||||
let referer = manual_reader_string(rdr, &mut buf, b"referer");
|
|
||||||
let request_uri = manual_reader_string(rdr, &mut buf, b"request_uri");
|
|
||||||
|
|
||||||
let http = Http {
|
|
||||||
protocol: FromPrimitive::from_i64(protocol).unwrap(),
|
|
||||||
status: FromPrimitive::from_i64(status).unwrap(),
|
|
||||||
host_status: FromPrimitive::from_i64(host_status).unwrap(),
|
|
||||||
up_status: FromPrimitive::from_i64(up_status).unwrap(),
|
|
||||||
method: FromPrimitive::from_i64(method).unwrap(),
|
|
||||||
content_type: content_type,
|
|
||||||
user_agent: user_agent,
|
|
||||||
referer: referer,
|
|
||||||
request_uri: request_uri,
|
|
||||||
};
|
|
||||||
|
|
||||||
manual_reader_ignore(rdr, &mut buf, b",");
|
|
||||||
manual_reader_field(rdr, &mut buf, b"origin");
|
|
||||||
manual_reader_ignore(rdr, &mut buf, b"{");
|
|
||||||
|
|
||||||
let ip = manual_reader_string(rdr, &mut buf, b"ip");
|
|
||||||
let port = manual_reader_int(rdr, &mut buf, b"port");
|
|
||||||
let hostname = manual_reader_string(rdr, &mut buf, b"hostname");
|
|
||||||
let protocol = manual_reader_int(rdr, &mut buf, b"protocol");
|
|
||||||
|
|
||||||
let origin = Origin {
|
|
||||||
ip: ip,
|
|
||||||
port: FromPrimitive::from_i64(port).unwrap(),
|
|
||||||
hostname: hostname,
|
|
||||||
protocol: FromPrimitive::from_i64(protocol).unwrap(),
|
|
||||||
};
|
|
||||||
|
|
||||||
manual_reader_ignore(rdr, &mut buf, b",");
|
|
||||||
let country = manual_reader_int(rdr, &mut buf, b"country");
|
|
||||||
let cache_status = manual_reader_int(rdr, &mut buf, b"cache_status");
|
|
||||||
let server_ip = manual_reader_string(rdr, &mut buf, b"server_ip");
|
|
||||||
let server_name = manual_reader_string(rdr, &mut buf, b"server_name");
|
|
||||||
let remote_ip = manual_reader_string(rdr, &mut buf, b"remote_ip");
|
|
||||||
let bytes_dlv = manual_reader_int(rdr, &mut buf, b"bytes_dlv");
|
|
||||||
let ray_id = manual_reader_string(rdr, &mut buf, b"ray_id");
|
|
||||||
|
|
||||||
Log {
|
|
||||||
timestamp: timestamp,
|
|
||||||
zone_id: FromPrimitive::from_i64(zone_id).unwrap(),
|
|
||||||
zone_plan: FromPrimitive::from_i64(zone_plan).unwrap(),
|
|
||||||
http: http,
|
|
||||||
origin: origin,
|
|
||||||
country: FromPrimitive::from_i64(country).unwrap(),
|
|
||||||
cache_status: FromPrimitive::from_i64(cache_status).unwrap(),
|
|
||||||
server_ip: server_ip,
|
|
||||||
server_name: server_name,
|
|
||||||
remote_ip: remote_ip,
|
|
||||||
bytes_dlv: FromPrimitive::from_i64(bytes_dlv).unwrap(),
|
|
||||||
ray_id: ray_id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn manual_iter_ignore<R: Iterator<Item=u8>>(mut rdr: R, buf: &mut [u8], key: &[u8]) {
|
|
||||||
let buf = &mut buf[0..key.len()];
|
|
||||||
|
|
||||||
for idx in range(0, key.len()) {
|
|
||||||
buf[idx] = rdr.next().unwrap();
|
|
||||||
}
|
|
||||||
assert_eq!(buf, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn manual_iter_field<R: Iterator<Item=u8>>(mut rdr: R, buf: &mut [u8], key: &[u8]) {
|
|
||||||
let b = rdr.next().unwrap();
|
|
||||||
assert_eq!(b, b'"');
|
|
||||||
|
|
||||||
manual_iter_ignore(rdr.by_ref(), buf, key);
|
|
||||||
|
|
||||||
let b = rdr.next().unwrap();
|
|
||||||
assert_eq!(b, b'"');
|
|
||||||
|
|
||||||
let b = rdr.next().unwrap();
|
|
||||||
assert_eq!(b, b':');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn manual_iter_int<R: Iterator<Item=u8>>(mut rdr: R, buf: &mut [u8], key: &[u8]) -> i64 {
|
|
||||||
manual_iter_field(rdr.by_ref(), buf, key);
|
|
||||||
|
|
||||||
let mut res = 0;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let byte = rdr.next().unwrap();
|
|
||||||
match byte {
|
|
||||||
b'0' ... b'9' => {
|
|
||||||
res *= 10;
|
|
||||||
res += (byte as i64) - (b'0' as i64);
|
|
||||||
}
|
|
||||||
_ => { break; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn manual_iter_string<R: Iterator<Item=u8>>(mut rdr: R, buf: &mut [u8], key: &[u8]) -> String {
|
|
||||||
manual_iter_field(rdr.by_ref(), buf, key);
|
|
||||||
manual_iter_ignore(rdr.by_ref(), buf, b"\"");
|
|
||||||
|
|
||||||
let mut idx = 0;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let byte = rdr.next().unwrap();
|
|
||||||
match byte {
|
|
||||||
b'"' => { break; }
|
|
||||||
byte => { buf[idx] = byte; }
|
|
||||||
};
|
|
||||||
|
|
||||||
idx += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
let b = rdr.next().unwrap();
|
|
||||||
assert!(b == b',' || b == b']' || b == b'}');
|
|
||||||
|
|
||||||
String::from_utf8(buf[..idx].to_vec()).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn manual_iter_deserialize<R: Iterator<Item=u8>>(mut rdr: R) -> Log {
|
|
||||||
let mut buf = [0u8; 128];
|
|
||||||
|
|
||||||
manual_iter_ignore(rdr.by_ref(), &mut buf, b"{");
|
|
||||||
let timestamp = manual_iter_int(rdr.by_ref(), &mut buf, b"timestamp");
|
|
||||||
let zone_id = manual_iter_int(rdr.by_ref(), &mut buf, b"zone_id");
|
|
||||||
let zone_plan = manual_iter_int(rdr.by_ref(), &mut buf, b"zone_plan");
|
|
||||||
|
|
||||||
manual_iter_field(rdr.by_ref(), &mut buf, b"http");
|
|
||||||
manual_iter_ignore(rdr.by_ref(), &mut buf, b"{");
|
|
||||||
|
|
||||||
let protocol = manual_iter_int(rdr.by_ref(), &mut buf, b"protocol");
|
|
||||||
let status = manual_iter_int(rdr.by_ref(), &mut buf, b"status");
|
|
||||||
let host_status = manual_iter_int(rdr.by_ref(), &mut buf, b"host_status");
|
|
||||||
let up_status = manual_iter_int(rdr.by_ref(), &mut buf, b"up_status");
|
|
||||||
let method = manual_iter_int(rdr.by_ref(), &mut buf, b"method");
|
|
||||||
let content_type = manual_iter_string(rdr.by_ref(), &mut buf, b"content_type");
|
|
||||||
let user_agent = manual_iter_string(rdr.by_ref(), &mut buf, b"user_agent");
|
|
||||||
let referer = manual_iter_string(rdr.by_ref(), &mut buf, b"referer");
|
|
||||||
let request_uri = manual_iter_string(rdr.by_ref(), &mut buf, b"request_uri");
|
|
||||||
|
|
||||||
let http = Http {
|
|
||||||
protocol: FromPrimitive::from_i64(protocol).unwrap(),
|
|
||||||
status: FromPrimitive::from_i64(status).unwrap(),
|
|
||||||
host_status: FromPrimitive::from_i64(host_status).unwrap(),
|
|
||||||
up_status: FromPrimitive::from_i64(up_status).unwrap(),
|
|
||||||
method: FromPrimitive::from_i64(method).unwrap(),
|
|
||||||
content_type: content_type,
|
|
||||||
user_agent: user_agent,
|
|
||||||
referer: referer,
|
|
||||||
request_uri: request_uri,
|
|
||||||
};
|
|
||||||
|
|
||||||
manual_iter_ignore(rdr.by_ref(), &mut buf, b",");
|
|
||||||
manual_iter_field(rdr.by_ref(), &mut buf, b"origin");
|
|
||||||
manual_iter_ignore(rdr.by_ref(), &mut buf, b"{");
|
|
||||||
|
|
||||||
let ip = manual_iter_string(rdr.by_ref(), &mut buf, b"ip");
|
|
||||||
let port = manual_iter_int(rdr.by_ref(), &mut buf, b"port");
|
|
||||||
let hostname = manual_iter_string(rdr.by_ref(), &mut buf, b"hostname");
|
|
||||||
let protocol = manual_iter_int(rdr.by_ref(), &mut buf, b"protocol");
|
|
||||||
|
|
||||||
let origin = Origin {
|
|
||||||
ip: ip,
|
|
||||||
port: FromPrimitive::from_i64(port).unwrap(),
|
|
||||||
hostname: hostname,
|
|
||||||
protocol: FromPrimitive::from_i64(protocol).unwrap(),
|
|
||||||
};
|
|
||||||
|
|
||||||
manual_iter_ignore(rdr.by_ref(), &mut buf, b",");
|
|
||||||
let country = manual_iter_int(rdr.by_ref(), &mut buf, b"country");
|
|
||||||
let cache_status = manual_iter_int(rdr.by_ref(), &mut buf, b"cache_status");
|
|
||||||
let server_ip = manual_iter_string(rdr.by_ref(), &mut buf, b"server_ip");
|
|
||||||
let server_name = manual_iter_string(rdr.by_ref(), &mut buf, b"server_name");
|
|
||||||
let remote_ip = manual_iter_string(rdr.by_ref(), &mut buf, b"remote_ip");
|
|
||||||
let bytes_dlv = manual_iter_int(rdr.by_ref(), &mut buf, b"bytes_dlv");
|
|
||||||
let ray_id = manual_iter_string(rdr.by_ref(), &mut buf, b"ray_id");
|
|
||||||
|
|
||||||
Log {
|
|
||||||
timestamp: timestamp,
|
|
||||||
zone_id: FromPrimitive::from_i64(zone_id).unwrap(),
|
|
||||||
zone_plan: FromPrimitive::from_i64(zone_plan).unwrap(),
|
|
||||||
http: http,
|
|
||||||
origin: origin,
|
|
||||||
country: FromPrimitive::from_i64(country).unwrap(),
|
|
||||||
cache_status: FromPrimitive::from_i64(cache_status).unwrap(),
|
|
||||||
server_ip: server_ip,
|
|
||||||
server_name: server_name,
|
|
||||||
remote_ip: remote_ip,
|
|
||||||
bytes_dlv: FromPrimitive::from_i64(bytes_dlv).unwrap(),
|
|
||||||
ray_id: ray_id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_deserializer(b: &mut Bencher) {
|
fn bench_deserializer(b: &mut Bencher) {
|
||||||
b.bytes = JSON_STR.len() as u64;
|
b.bytes = JSON_STR.len() as u64;
|
||||||
@@ -1588,107 +1210,3 @@ fn bench_deserializer(b: &mut Bencher) {
|
|||||||
let _log: Log = json::from_str(JSON_STR).unwrap();
|
let _log: Log = json::from_str(JSON_STR).unwrap();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_deserializers(b: &mut Bencher) {
|
|
||||||
let s = r#"{"timestamp":25469139677502,"zone_id":123456,"zone_plan":1,"http":{"protocol":2,"status":200,"host_status":503,"up_status":520,"method":1,"content_type":"text/html","user_agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36","referer":"https://www.cloudflare.com/","request_uri":"/cdn-cgi/trace"},"origin":{"ip":"1.2.3.4","port":8000,"hostname":"www.example.com","protocol":2},"country":238,"cache_status":3,"server_ip":"192.168.1.1","server_name":"metal.cloudflare.com","remote_ip":"10.1.2.3","bytes_dlv":123456,"ray_id":"10c73629cce30078-LAX"}"#;
|
|
||||||
|
|
||||||
b.bytes = s.len() as u64;
|
|
||||||
|
|
||||||
for _ in range(0is, 10000) {
|
|
||||||
let _log: Log = json::from_str(s).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_reader_manual_deserializer() {
|
|
||||||
let mut rdr = JSON_STR.as_bytes();
|
|
||||||
let log = manual_reader_deserialize(&mut rdr);
|
|
||||||
|
|
||||||
assert_eq!(log, Log::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_reader_manual_reader_deserializer(b: &mut Bencher) {
|
|
||||||
b.bytes = JSON_STR.len() as u64;
|
|
||||||
|
|
||||||
b.iter(|| {
|
|
||||||
let mut rdr = JSON_STR.as_bytes();
|
|
||||||
let _ = manual_reader_deserialize(&mut rdr);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_reader_manual_reader_deserializers(b: &mut Bencher) {
|
|
||||||
b.bytes = JSON_STR.len() as u64;
|
|
||||||
|
|
||||||
for _ in range(0is, 100000) {
|
|
||||||
let mut rdr = JSON_STR.as_bytes();
|
|
||||||
let _ = manual_reader_deserialize(&mut rdr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_iter_manual_iter_deserializer() {
|
|
||||||
let log = manual_iter_deserialize(JSON_STR.bytes());
|
|
||||||
|
|
||||||
assert_eq!(log, Log::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_iter_manual_iter_deserializer(b: &mut Bencher) {
|
|
||||||
b.bytes = JSON_STR.len() as u64;
|
|
||||||
|
|
||||||
b.iter(|| {
|
|
||||||
let _ = manual_iter_deserialize(JSON_STR.bytes());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_iter_manual_iter_deserializers(b: &mut Bencher) {
|
|
||||||
b.bytes = JSON_STR.len() as u64;
|
|
||||||
|
|
||||||
for _ in range(0is, 10000) {
|
|
||||||
let _ = manual_iter_deserialize(JSON_STR.bytes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_iter_manual_reader_as_iter_deserializer() {
|
|
||||||
let rdr = JSON_STR.as_bytes();
|
|
||||||
let iter = rdr.bytes().map(|x| x.unwrap());
|
|
||||||
|
|
||||||
let log = manual_iter_deserialize(iter);
|
|
||||||
|
|
||||||
assert_eq!(log, Log::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_iter_manual_reader_as_iter_deserializer(b: &mut Bencher) {
|
|
||||||
b.bytes = JSON_STR.len() as u64;
|
|
||||||
|
|
||||||
b.iter(|| {
|
|
||||||
let rdr = JSON_STR.as_bytes();
|
|
||||||
let iter = rdr.bytes().map(|x| x.unwrap());
|
|
||||||
|
|
||||||
let _ = manual_iter_deserialize(iter);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_iter_manual_reader_as_iter_deserializers(b: &mut Bencher) {
|
|
||||||
b.bytes = JSON_STR.len() as u64;
|
|
||||||
|
|
||||||
for _ in range(0is, 10000) {
|
|
||||||
let rdr = JSON_STR.as_bytes();
|
|
||||||
let iter = rdr.bytes().map(|x| x.unwrap());
|
|
||||||
|
|
||||||
let _ = manual_iter_deserialize(iter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+108
-43
@@ -1,4 +1,4 @@
|
|||||||
#![feature(core, plugin, test)]
|
#![feature(custom_derive, core, plugin, test)]
|
||||||
#![plugin(serde_macros)]
|
#![plugin(serde_macros)]
|
||||||
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
@@ -19,7 +19,17 @@ use serde::de::{Deserializer, Deserialize};
|
|||||||
pub enum Error {
|
pub enum Error {
|
||||||
EndOfStream,
|
EndOfStream,
|
||||||
SyntaxError,
|
SyntaxError,
|
||||||
OtherError(String),
|
MissingField,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl serde::de::Error for Error {
|
||||||
|
fn syntax_error() -> Error { Error::SyntaxError }
|
||||||
|
|
||||||
|
fn end_of_stream_error() -> Error { Error::EndOfStream }
|
||||||
|
|
||||||
|
fn missing_field_error(_: &'static str) -> Error {
|
||||||
|
Error::MissingField
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -30,7 +40,6 @@ mod decoder {
|
|||||||
use rustc_serialize;
|
use rustc_serialize;
|
||||||
|
|
||||||
use super::Error;
|
use super::Error;
|
||||||
use super::Error::{EndOfStream, SyntaxError, OtherError};
|
|
||||||
use self::Value::{StringValue, IsizeValue};
|
use self::Value::{StringValue, IsizeValue};
|
||||||
|
|
||||||
enum Value {
|
enum Value {
|
||||||
@@ -58,39 +67,39 @@ mod decoder {
|
|||||||
impl rustc_serialize::Decoder for IsizeDecoder {
|
impl rustc_serialize::Decoder for IsizeDecoder {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn error(&mut self, msg: &str) -> Error {
|
fn error(&mut self, _msg: &str) -> Error {
|
||||||
OtherError(msg.to_string())
|
Error::SyntaxError
|
||||||
}
|
}
|
||||||
|
|
||||||
// Primitive types:
|
// Primitive types:
|
||||||
fn read_nil(&mut self) -> Result<(), Error> { Err(SyntaxError) }
|
fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) }
|
||||||
fn read_usize(&mut self) -> Result<usize, Error> { Err(SyntaxError) }
|
fn read_usize(&mut self) -> Result<usize, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_u64(&mut self) -> Result<u64, Error> { Err(SyntaxError) }
|
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_u32(&mut self) -> Result<u32, Error> { Err(SyntaxError) }
|
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_u16(&mut self) -> Result<u16, Error> { Err(SyntaxError) }
|
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_u8(&mut self) -> Result<u8, Error> { Err(SyntaxError) }
|
fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::SyntaxError) }
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_isize(&mut self) -> Result<isize, Error> {
|
fn read_isize(&mut self) -> Result<isize, Error> {
|
||||||
match self.stack.pop() {
|
match self.stack.pop() {
|
||||||
Some(IsizeValue(x)) => Ok(x),
|
Some(IsizeValue(x)) => Ok(x),
|
||||||
Some(_) => Err(SyntaxError),
|
Some(_) => Err(Error::SyntaxError),
|
||||||
None => Err(EndOfStream),
|
None => Err(Error::EndOfStream),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn read_i64(&mut self) -> Result<i64, Error> { Err(SyntaxError) }
|
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_i32(&mut self) -> Result<i32, Error> { Err(SyntaxError) }
|
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_i16(&mut self) -> Result<i16, Error> { Err(SyntaxError) }
|
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_i8(&mut self) -> Result<i8, Error> { Err(SyntaxError) }
|
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_bool(&mut self) -> Result<bool, Error> { Err(SyntaxError) }
|
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_f64(&mut self) -> Result<f64, Error> { Err(SyntaxError) }
|
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_f32(&mut self) -> Result<f32, Error> { Err(SyntaxError) }
|
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_char(&mut self) -> Result<char, Error> { Err(SyntaxError) }
|
fn read_char(&mut self) -> Result<char, Error> { Err(Error::SyntaxError) }
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_str(&mut self) -> Result<String, Error> {
|
fn read_str(&mut self) -> Result<String, Error> {
|
||||||
match self.stack.pop() {
|
match self.stack.pop() {
|
||||||
Some(StringValue(x)) => Ok(x),
|
Some(StringValue(x)) => Ok(x),
|
||||||
Some(_) => Err(SyntaxError),
|
Some(_) => Err(Error::SyntaxError),
|
||||||
None => Err(EndOfStream),
|
None => Err(Error::EndOfStream),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,19 +174,19 @@ mod decoder {
|
|||||||
fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut IsizeDecoder, bool) -> Result<T, Error>,
|
F: FnOnce(&mut IsizeDecoder, bool) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_seq<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
fn read_seq<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
|
F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_seq_elt<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
fn read_seq_elt<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -198,7 +207,7 @@ mod decoder {
|
|||||||
f(self)
|
f(self)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
Err(SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,39 +225,94 @@ mod decoder {
|
|||||||
|
|
||||||
mod deserializer {
|
mod deserializer {
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::hash_map::IntoIter;
|
use std::collections::hash_map;
|
||||||
|
|
||||||
use super::Error;
|
use super::Error;
|
||||||
use super::Error::{EndOfStream, SyntaxError};
|
|
||||||
use self::State::{StartState, KeyOrEndState, ValueState, EndState};
|
|
||||||
|
|
||||||
use serde::de;
|
use serde::de;
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
enum State {
|
enum State {
|
||||||
StartState,
|
StartState,
|
||||||
KeyOrEndState,
|
KeyState(String),
|
||||||
ValueState(isize),
|
ValueState(isize),
|
||||||
EndState,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct IsizeDeserializer {
|
pub struct IsizeDeserializer {
|
||||||
stack: Vec<State>,
|
stack: Vec<State>,
|
||||||
len: usize,
|
iter: hash_map::IntoIter<String, isize>,
|
||||||
iter: IntoIter<String, isize>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IsizeDeserializer {
|
impl IsizeDeserializer {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(values: HashMap<String, isize>) -> IsizeDeserializer {
|
pub fn new(values: HashMap<String, isize>) -> IsizeDeserializer {
|
||||||
IsizeDeserializer {
|
IsizeDeserializer {
|
||||||
stack: vec!(StartState),
|
stack: vec!(State::StartState),
|
||||||
len: values.len(),
|
|
||||||
iter: values.into_iter(),
|
iter: values.into_iter(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl de::Deserializer for IsizeDeserializer {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn visit<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::KeyState(key)) => {
|
||||||
|
visitor.visit_string(key)
|
||||||
|
}
|
||||||
|
Some(State::ValueState(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::ValueState(value));
|
||||||
|
self.stack.push(State::KeyState(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::SyntaxError),
|
||||||
|
None => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
self.iter.size_hint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
impl Iterator for IsizeDeserializer {
|
impl Iterator for IsizeDeserializer {
|
||||||
type Item = Result<de::Token, Error>;
|
type Item = Result<de::Token, Error>;
|
||||||
|
|
||||||
@@ -310,9 +374,10 @@ mod deserializer {
|
|||||||
fn missing_field<
|
fn missing_field<
|
||||||
T: de::Deserialize<IsizeDeserializer, Error>
|
T: de::Deserialize<IsizeDeserializer, Error>
|
||||||
>(&mut self, _field: &'static str) -> Result<T, Error> {
|
>(&mut self, _field: &'static str) -> Result<T, Error> {
|
||||||
Err(SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -338,7 +403,7 @@ fn bench_decoder_000(b: &mut Bencher) {
|
|||||||
fn bench_decoder_003(b: &mut Bencher) {
|
fn bench_decoder_003(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let mut m: HashMap<String, isize> = HashMap::new();
|
let mut m: HashMap<String, isize> = HashMap::new();
|
||||||
for i in range(0is, 3) {
|
for i in range(0, 3) {
|
||||||
m.insert(i.to_string(), i);
|
m.insert(i.to_string(), i);
|
||||||
}
|
}
|
||||||
run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
|
run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
|
||||||
@@ -349,7 +414,7 @@ fn bench_decoder_003(b: &mut Bencher) {
|
|||||||
fn bench_decoder_100(b: &mut Bencher) {
|
fn bench_decoder_100(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let mut m: HashMap<String, isize> = HashMap::new();
|
let mut m: HashMap<String, isize> = HashMap::new();
|
||||||
for i in range(0is, 100) {
|
for i in range(0, 100) {
|
||||||
m.insert(i.to_string(), i);
|
m.insert(i.to_string(), i);
|
||||||
}
|
}
|
||||||
run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
|
run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
|
||||||
@@ -357,9 +422,9 @@ fn bench_decoder_100(b: &mut Bencher) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run_deserializer<
|
fn run_deserializer<
|
||||||
D: Deserializer<E>,
|
D: Deserializer<Error=E>,
|
||||||
E: Debug,
|
E: Debug,
|
||||||
T: Clone + PartialEq + Debug + Deserialize<D, E>
|
T: Clone + PartialEq + Debug + Deserialize
|
||||||
>(mut d: D, value: T) {
|
>(mut d: D, value: T) {
|
||||||
let v: T = Deserialize::deserialize(&mut d).unwrap();
|
let v: T = Deserialize::deserialize(&mut d).unwrap();
|
||||||
|
|
||||||
@@ -378,7 +443,7 @@ fn bench_deserializer_000(b: &mut Bencher) {
|
|||||||
fn bench_deserializer_003(b: &mut Bencher) {
|
fn bench_deserializer_003(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let mut m: HashMap<String, isize> = HashMap::new();
|
let mut m: HashMap<String, isize> = HashMap::new();
|
||||||
for i in range(0is, 3) {
|
for i in range(0, 3) {
|
||||||
m.insert(i.to_string(), i);
|
m.insert(i.to_string(), i);
|
||||||
}
|
}
|
||||||
run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
|
run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
|
||||||
@@ -389,7 +454,7 @@ fn bench_deserializer_003(b: &mut Bencher) {
|
|||||||
fn bench_deserializer_100(b: &mut Bencher) {
|
fn bench_deserializer_100(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let mut m: HashMap<String, isize> = HashMap::new();
|
let mut m: HashMap<String, isize> = HashMap::new();
|
||||||
for i in range(0is, 100) {
|
for i in range(0, 100) {
|
||||||
m.insert(i.to_string(), i);
|
m.insert(i.to_string(), i);
|
||||||
}
|
}
|
||||||
run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
|
run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
|
||||||
|
|||||||
+266
-130
@@ -1,4 +1,4 @@
|
|||||||
#![feature(plugin, test)]
|
#![feature(custom_derive, plugin, test)]
|
||||||
#![plugin(serde_macros)]
|
#![plugin(serde_macros)]
|
||||||
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
@@ -35,11 +35,21 @@ struct Outer {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
EndOfStream,
|
EndOfStream,
|
||||||
SyntaxError(String),
|
SyntaxError,
|
||||||
UnexpectedName(String),
|
UnexpectedName,
|
||||||
ConversionError(String),
|
ConversionError,
|
||||||
MissingField(&'static str),
|
MissingField,
|
||||||
OtherError(String),
|
OtherError,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl serde::de::Error for Error {
|
||||||
|
fn syntax_error() -> Error { Error::SyntaxError }
|
||||||
|
|
||||||
|
fn end_of_stream_error() -> Error { Error::EndOfStream }
|
||||||
|
|
||||||
|
fn missing_field_error(_: &'static str) -> Error {
|
||||||
|
Error::MissingField
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod decoder {
|
mod decoder {
|
||||||
@@ -92,8 +102,8 @@ mod decoder {
|
|||||||
impl Decoder for OuterDecoder {
|
impl Decoder for OuterDecoder {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn error(&mut self, msg: &str) -> Error {
|
fn error(&mut self, _msg: &str) -> Error {
|
||||||
Error::OtherError(msg.to_string())
|
Error::OtherError
|
||||||
}
|
}
|
||||||
|
|
||||||
// Primitive types:
|
// Primitive types:
|
||||||
@@ -101,40 +111,40 @@ mod decoder {
|
|||||||
fn read_nil(&mut self) -> Result<(), Error> {
|
fn read_nil(&mut self) -> Result<(), Error> {
|
||||||
match self.stack.pop() {
|
match self.stack.pop() {
|
||||||
Some(NullState) => Ok(()),
|
Some(NullState) => Ok(()),
|
||||||
_ => Err(Error::SyntaxError("NullState".to_string())),
|
_ => Err(Error::SyntaxError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_usize(&mut self) -> Result<usize, Error> {
|
fn read_usize(&mut self) -> Result<usize, Error> {
|
||||||
match self.stack.pop() {
|
match self.stack.pop() {
|
||||||
Some(UsizeState(value)) => Ok(value),
|
Some(UsizeState(value)) => Ok(value),
|
||||||
_ => Err(Error::SyntaxError("UintState".to_string())),
|
_ => Err(Error::SyntaxError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::SyntaxError("".to_string())) }
|
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::SyntaxError("".to_string())) }
|
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::SyntaxError("".to_string())) }
|
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::SyntaxError("".to_string())) }
|
fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_isize(&mut self) -> Result<isize, Error> { Err(Error::SyntaxError("".to_string())) }
|
fn read_isize(&mut self) -> Result<isize, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::SyntaxError("".to_string())) }
|
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::SyntaxError("".to_string())) }
|
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::SyntaxError("".to_string())) }
|
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::SyntaxError("".to_string())) }
|
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::SyntaxError("".to_string())) }
|
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::SyntaxError("".to_string())) }
|
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::SyntaxError("".to_string())) }
|
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::SyntaxError) }
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_char(&mut self) -> Result<char, Error> {
|
fn read_char(&mut self) -> Result<char, Error> {
|
||||||
match self.stack.pop() {
|
match self.stack.pop() {
|
||||||
Some(CharState(c)) => Ok(c),
|
Some(CharState(c)) => Ok(c),
|
||||||
_ => Err(Error::SyntaxError("".to_string())),
|
_ => Err(Error::SyntaxError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_str(&mut self) -> Result<String, Error> {
|
fn read_str(&mut self) -> Result<String, Error> {
|
||||||
match self.stack.pop() {
|
match self.stack.pop() {
|
||||||
Some(StringState(value)) => Ok(value),
|
Some(StringState(value)) => Ok(value),
|
||||||
_ => Err(Error::SyntaxError("".to_string())),
|
_ => Err(Error::SyntaxError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,31 +152,31 @@ mod decoder {
|
|||||||
fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where
|
fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError("".to_string()))
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
|
fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut OuterDecoder, usize) -> Result<T, Error>,
|
F: FnOnce(&mut OuterDecoder, usize) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError("".to_string()))
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
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>,
|
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError("".to_string()))
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
|
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>,
|
F: FnOnce(&mut OuterDecoder, usize) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError("".to_string()))
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
|
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>,
|
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError("".to_string()))
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -180,7 +190,7 @@ mod decoder {
|
|||||||
self.stack.push(FieldState("inner"));
|
self.stack.push(FieldState("inner"));
|
||||||
f(self)
|
f(self)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::SyntaxError("expected Outer".to_string()))
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(InnerState(Inner { a: (), b, c })) => {
|
Some(InnerState(Inner { a: (), b, c })) => {
|
||||||
@@ -195,10 +205,10 @@ mod decoder {
|
|||||||
self.stack.push(FieldState("a"));
|
self.stack.push(FieldState("a"));
|
||||||
f(self)
|
f(self)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::SyntaxError("expected Inner".to_string()))
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Err(Error::SyntaxError("expected InnerState or OuterState".to_string())),
|
_ => Err(Error::SyntaxError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -210,35 +220,35 @@ mod decoder {
|
|||||||
if f_name == name {
|
if f_name == name {
|
||||||
f(self)
|
f(self)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::SyntaxError("expected FieldState".to_string()))
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Err(Error::SyntaxError("expected FieldState".to_string()))
|
_ => Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
|
fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError("".to_string()))
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError("".to_string()))
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
|
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>,
|
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError("".to_string()))
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
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>,
|
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError("".to_string()))
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specialized types:
|
// Specialized types:
|
||||||
@@ -248,7 +258,7 @@ mod decoder {
|
|||||||
{
|
{
|
||||||
match self.stack.pop() {
|
match self.stack.pop() {
|
||||||
Some(OptionState(b)) => f(self, b),
|
Some(OptionState(b)) => f(self, b),
|
||||||
_ => Err(Error::SyntaxError("expected OptionState".to_string())),
|
_ => Err(Error::SyntaxError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,7 +274,7 @@ mod decoder {
|
|||||||
}
|
}
|
||||||
f(self, len)
|
f(self, len)
|
||||||
}
|
}
|
||||||
_ => Err(Error::SyntaxError("expected VecState".to_string()))
|
_ => Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -295,7 +305,7 @@ mod decoder {
|
|||||||
}
|
}
|
||||||
f(self, len)
|
f(self, len)
|
||||||
}
|
}
|
||||||
_ => Err(Error::SyntaxError("expected MapState".to_string())),
|
_ => Err(Error::SyntaxError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -318,39 +328,24 @@ mod decoder {
|
|||||||
|
|
||||||
mod deserializer {
|
mod deserializer {
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::collections::hash_map;
|
||||||
|
use std::vec;
|
||||||
use super::{Outer, Inner};
|
use super::{Outer, Inner};
|
||||||
use super::Error;
|
use super::Error;
|
||||||
use serde::de;
|
use serde::de;
|
||||||
|
|
||||||
use self::State::{
|
|
||||||
OuterState,
|
|
||||||
InnerState,
|
|
||||||
FieldState,
|
|
||||||
NullState,
|
|
||||||
UsizeState,
|
|
||||||
CharState,
|
|
||||||
StringState,
|
|
||||||
OptionState,
|
|
||||||
//TupleState(usize),
|
|
||||||
VecState,
|
|
||||||
MapState,
|
|
||||||
EndState,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum State {
|
enum State {
|
||||||
OuterState(Outer),
|
OuterState(Outer),
|
||||||
InnerState(Inner),
|
InnerState(Inner),
|
||||||
FieldState(&'static str),
|
StrState(&'static str),
|
||||||
NullState,
|
NullState,
|
||||||
UsizeState(usize),
|
UsizeState(usize),
|
||||||
CharState(char),
|
CharState(char),
|
||||||
StringState(String),
|
StringState(String),
|
||||||
OptionState(bool),
|
OptionState(bool),
|
||||||
//TupleState(uint),
|
|
||||||
VecState(Vec<Inner>),
|
VecState(Vec<Inner>),
|
||||||
MapState(HashMap<String, Option<char>>),
|
MapState(HashMap<String, Option<char>>),
|
||||||
EndState,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct OuterDeserializer {
|
pub struct OuterDeserializer {
|
||||||
@@ -361,101 +356,242 @@ mod deserializer {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(outer: Outer) -> OuterDeserializer {
|
pub fn new(outer: Outer) -> OuterDeserializer {
|
||||||
OuterDeserializer {
|
OuterDeserializer {
|
||||||
stack: vec!(OuterState(outer)),
|
stack: vec!(State::OuterState(outer)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for OuterDeserializer {
|
impl de::Deserializer for OuterDeserializer {
|
||||||
type Item = Result<de::Token, Error>;
|
type Error = Error;
|
||||||
|
|
||||||
#[inline]
|
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
fn next(&mut self) -> Option<Result<de::Token, Error>> {
|
where V: de::Visitor,
|
||||||
|
{
|
||||||
match self.stack.pop() {
|
match self.stack.pop() {
|
||||||
Some(OuterState(Outer { inner })) => {
|
Some(State::OuterState(Outer { inner })) => {
|
||||||
self.stack.push(EndState);
|
self.stack.push(State::VecState(inner));
|
||||||
self.stack.push(VecState(inner));
|
self.stack.push(State::StrState("inner"));
|
||||||
self.stack.push(FieldState("inner"));
|
|
||||||
Some(Ok(de::Token::StructStart("Outer", 1)))
|
|
||||||
}
|
|
||||||
Some(InnerState(Inner { a: (), b, c })) => {
|
|
||||||
self.stack.push(EndState);
|
|
||||||
self.stack.push(MapState(c));
|
|
||||||
self.stack.push(FieldState("c"));
|
|
||||||
|
|
||||||
self.stack.push(UsizeState(b));
|
visitor.visit_named_map("Outer", OuterMapVisitor {
|
||||||
self.stack.push(FieldState("b"));
|
de: self,
|
||||||
|
state: 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Some(State::InnerState(Inner { a: (), b, c })) => {
|
||||||
|
self.stack.push(State::MapState(c));
|
||||||
|
self.stack.push(State::StrState("c"));
|
||||||
|
|
||||||
self.stack.push(NullState);
|
self.stack.push(State::UsizeState(b));
|
||||||
self.stack.push(FieldState("a"));
|
self.stack.push(State::StrState("b"));
|
||||||
Some(Ok(de::Token::StructStart("Inner", 3)))
|
|
||||||
|
self.stack.push(State::NullState);
|
||||||
|
self.stack.push(State::StrState("a"));
|
||||||
|
|
||||||
|
visitor.visit_named_map("Inner", InnerMapVisitor {
|
||||||
|
de: self,
|
||||||
|
state: 0,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
Some(FieldState(name)) => Some(Ok(de::Token::Str(name))),
|
Some(State::VecState(value)) => {
|
||||||
Some(VecState(value)) => {
|
visitor.visit_seq(OuterSeqVisitor {
|
||||||
self.stack.push(EndState);
|
de: self,
|
||||||
let len = value.len();
|
iter: value.into_iter(),
|
||||||
for inner in value.into_iter().rev() {
|
})
|
||||||
self.stack.push(InnerState(inner));
|
|
||||||
}
|
|
||||||
Some(Ok(de::Token::SeqStart(len)))
|
|
||||||
}
|
}
|
||||||
Some(MapState(value)) => {
|
Some(State::MapState(value)) => {
|
||||||
self.stack.push(EndState);
|
visitor.visit_map(MapVisitor {
|
||||||
let len = value.len();
|
de: self,
|
||||||
for (key, value) in value {
|
iter: value.into_iter(),
|
||||||
match value {
|
})
|
||||||
Some(c) => {
|
|
||||||
self.stack.push(CharState(c));
|
|
||||||
self.stack.push(OptionState(true));
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
self.stack.push(OptionState(false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.stack.push(StringState(key));
|
|
||||||
}
|
|
||||||
Some(Ok(de::Token::MapStart(len)))
|
|
||||||
}
|
}
|
||||||
//Some(TupleState(len)) => Some(Ok(de::Token::TupleStart(len))),
|
Some(State::NullState) => {
|
||||||
Some(NullState) => Some(Ok(de::Token::Null)),
|
visitor.visit_unit()
|
||||||
Some(UsizeState(x)) => Some(Ok(de::Token::Usize(x))),
|
|
||||||
Some(CharState(x)) => Some(Ok(de::Token::Char(x))),
|
|
||||||
Some(StringState(x)) => Some(Ok(de::Token::String(x))),
|
|
||||||
Some(OptionState(x)) => Some(Ok(de::Token::Option(x))),
|
|
||||||
Some(EndState) => {
|
|
||||||
Some(Ok(de::Token::End))
|
|
||||||
}
|
}
|
||||||
None => None,
|
Some(State::UsizeState(x)) => {
|
||||||
|
visitor.visit_usize(x)
|
||||||
|
}
|
||||||
|
Some(State::CharState(x)) => {
|
||||||
|
visitor.visit_char(x)
|
||||||
|
}
|
||||||
|
Some(State::StrState(x)) => {
|
||||||
|
visitor.visit_str(x)
|
||||||
|
}
|
||||||
|
Some(State::StringState(x)) => {
|
||||||
|
visitor.visit_string(x)
|
||||||
|
}
|
||||||
|
Some(State::OptionState(false)) => {
|
||||||
|
visitor.visit_none()
|
||||||
|
}
|
||||||
|
Some(State::OptionState(true)) => {
|
||||||
|
visitor.visit_some(self)
|
||||||
|
}
|
||||||
|
None => Err(Error::EndOfStream),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl de::Deserializer<Error> for OuterDeserializer {
|
struct OuterMapVisitor<'a> {
|
||||||
#[inline]
|
de: &'a mut OuterDeserializer,
|
||||||
fn end_of_stream_error(&mut self) -> Error {
|
state: usize,
|
||||||
Error::EndOfStream
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn visit_value<V>(&mut self) -> Result<V, Error>
|
||||||
fn syntax_error(&mut self, token: de::Token, expected: &[de::TokenKind]) -> Error {
|
where V: de::Deserialize,
|
||||||
Error::SyntaxError(format!("expected {:?}, found {:?}", expected, token))
|
{
|
||||||
|
de::Deserialize::deserialize(self.de)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn end(&mut self) -> Result<(), Error> {
|
||||||
fn unexpected_name_error(&mut self, token: de::Token) -> Error {
|
if self.state == 1 {
|
||||||
Error::UnexpectedName(format!("found {:?}", token))
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(Error::SyntaxError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
fn conversion_error(&mut self, token: de::Token) -> Error {
|
let len = 1 - self.state;
|
||||||
Error::UnexpectedName(format!("found {:?}", token))
|
(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::InnerState(value));
|
||||||
|
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn end(&mut self) -> Result<(), Error> {
|
||||||
fn missing_field<
|
match self.iter.next() {
|
||||||
T: de::Deserialize<OuterDeserializer, Error>
|
Some(_) => Err(Error::SyntaxError),
|
||||||
>(&mut self, field: &'static str) -> Result<T, Error> {
|
None => Ok(()),
|
||||||
Err(Error::MissingField(field))
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 == 1 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(Error::SyntaxError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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::CharState(value));
|
||||||
|
self.de.stack.push(State::OptionState(true));
|
||||||
|
self.de.stack.push(State::StringState(key));
|
||||||
|
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
|
||||||
|
}
|
||||||
|
Some((key, None)) => {
|
||||||
|
self.de.stack.push(State::OptionState(false));
|
||||||
|
self.de.stack.push(State::StringState(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::SyntaxError),
|
||||||
|
None => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
self.iter.size_hint()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+192
-202
@@ -16,9 +16,16 @@ use serde::de::{Deserializer, Deserialize};
|
|||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
EndOfStream,
|
EndOfStreamError,
|
||||||
SyntaxError,
|
SyntaxError,
|
||||||
OtherError(String),
|
}
|
||||||
|
|
||||||
|
impl serde::de::Error for Error {
|
||||||
|
fn syntax_error() -> Error { Error::SyntaxError }
|
||||||
|
|
||||||
|
fn end_of_stream_error() -> Error { Error::EndOfStreamError }
|
||||||
|
|
||||||
|
fn missing_field_error(_: &'static str) -> Error { Error::SyntaxError }
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -28,158 +35,155 @@ mod decoder {
|
|||||||
use rustc_serialize;
|
use rustc_serialize;
|
||||||
|
|
||||||
use super::Error;
|
use super::Error;
|
||||||
use super::Error::{EndOfStream, SyntaxError, OtherError};
|
|
||||||
|
|
||||||
pub struct IsizeDecoder {
|
pub struct UsizeDecoder {
|
||||||
len: usize,
|
len: usize,
|
||||||
iter: vec::IntoIter<isize>,
|
iter: vec::IntoIter<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IsizeDecoder {
|
impl UsizeDecoder {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(values: Vec<isize>) -> IsizeDecoder {
|
pub fn new(values: Vec<usize>) -> UsizeDecoder {
|
||||||
IsizeDecoder {
|
UsizeDecoder {
|
||||||
len: values.len(),
|
len: values.len(),
|
||||||
iter: values.into_iter(),
|
iter: values.into_iter(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl rustc_serialize::Decoder for IsizeDecoder {
|
impl rustc_serialize::Decoder for UsizeDecoder {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn error(&mut self, msg: &str) -> Error {
|
fn error(&mut self, _: &str) -> Error { Error::SyntaxError }
|
||||||
OtherError(msg.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Primitive types:
|
// Primitive types:
|
||||||
fn read_nil(&mut self) -> Result<(), Error> { Err(SyntaxError) }
|
fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) }
|
||||||
fn read_usize(&mut self) -> Result<usize, Error> { Err(SyntaxError) }
|
|
||||||
fn read_u64(&mut self) -> Result<u64, Error> { Err(SyntaxError) }
|
|
||||||
fn read_u32(&mut self) -> Result<u32, Error> { Err(SyntaxError) }
|
|
||||||
fn read_u16(&mut self) -> Result<u16, Error> { Err(SyntaxError) }
|
|
||||||
fn read_u8(&mut self) -> Result<u8, Error> { Err(SyntaxError) }
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_isize(&mut self) -> Result<isize, Error> {
|
fn read_usize(&mut self) -> Result<usize, Error> {
|
||||||
match self.iter.next() {
|
match self.iter.next() {
|
||||||
Some(value) => Ok(value),
|
Some(value) => Ok(value),
|
||||||
None => Err(EndOfStream),
|
None => Err(Error::EndOfStreamError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn read_i64(&mut self) -> Result<i64, Error> { Err(SyntaxError) }
|
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_i32(&mut self) -> Result<i32, Error> { Err(SyntaxError) }
|
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_i16(&mut self) -> Result<i16, Error> { Err(SyntaxError) }
|
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_i8(&mut self) -> Result<i8, Error> { Err(SyntaxError) }
|
fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_bool(&mut self) -> Result<bool, Error> { Err(SyntaxError) }
|
fn read_isize(&mut self) -> Result<isize, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_f64(&mut self) -> Result<f64, Error> { Err(SyntaxError) }
|
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_f32(&mut self) -> Result<f32, Error> { Err(SyntaxError) }
|
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_char(&mut self) -> Result<char, Error> { Err(SyntaxError) }
|
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_str(&mut self) -> Result<String, Error> { Err(SyntaxError) }
|
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::SyntaxError) }
|
||||||
|
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::SyntaxError) }
|
||||||
|
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::SyntaxError) }
|
||||||
|
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::SyntaxError) }
|
||||||
|
fn read_char(&mut self) -> Result<char, Error> { Err(Error::SyntaxError) }
|
||||||
|
fn read_str(&mut self) -> Result<String, Error> { Err(Error::SyntaxError) }
|
||||||
|
|
||||||
// Compound types:
|
// Compound types:
|
||||||
fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where
|
fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
|
fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
|
F: FnOnce(&mut UsizeDecoder, usize) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
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>,
|
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
|
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>,
|
F: FnOnce(&mut UsizeDecoder, usize) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
|
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>,
|
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
|
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>,
|
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_struct_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
|
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>,
|
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
|
fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
|
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>,
|
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
|
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>,
|
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(Error::SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specialized types:
|
// Specialized types:
|
||||||
fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut IsizeDecoder, bool) -> Result<T, Error>,
|
F: FnOnce(&mut UsizeDecoder, bool) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_seq<T, F>(&mut self, f: F) -> Result<T, Error> where
|
fn read_seq<T, F>(&mut self, f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
|
F: FnOnce(&mut UsizeDecoder, usize) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
let len = self.len;
|
let len = self.len;
|
||||||
f(self, len)
|
f(self, len)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_seq_elt<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Error> where
|
fn read_seq_elt<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
f(self)
|
f(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_map<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
fn read_map<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
|
F: FnOnce(&mut UsizeDecoder, usize) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_map_elt_key<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
fn read_map_elt_key<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_map_elt_val<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
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: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,34 +206,32 @@ mod decoder {
|
|||||||
impl rustc_serialize::Decoder for U8Decoder {
|
impl rustc_serialize::Decoder for U8Decoder {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn error(&mut self, msg: &str) -> Error {
|
fn error(&mut self, _: &str) -> Error { Error::SyntaxError }
|
||||||
OtherError(msg.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Primitive types:
|
// Primitive types:
|
||||||
fn read_nil(&mut self) -> Result<(), Error> { Err(SyntaxError) }
|
fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) }
|
||||||
fn read_usize(&mut self) -> Result<usize, Error> { Err(SyntaxError) }
|
fn read_usize(&mut self) -> Result<usize, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_u64(&mut self) -> Result<u64, Error> { Err(SyntaxError) }
|
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_u32(&mut self) -> Result<u32, Error> { Err(SyntaxError) }
|
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_u16(&mut self) -> Result<u16, Error> { Err(SyntaxError) }
|
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::SyntaxError) }
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_u8(&mut self) -> Result<u8, Error> {
|
fn read_u8(&mut self) -> Result<u8, Error> {
|
||||||
match self.iter.next() {
|
match self.iter.next() {
|
||||||
Some(value) => Ok(value),
|
Some(value) => Ok(value),
|
||||||
None => Err(EndOfStream),
|
None => Err(Error::EndOfStreamError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_isize(&mut self) -> Result<isize, Error> { Err(SyntaxError) }
|
fn read_isize(&mut self) -> Result<isize, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_i64(&mut self) -> Result<i64, Error> { Err(SyntaxError) }
|
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_i32(&mut self) -> Result<i32, Error> { Err(SyntaxError) }
|
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_i16(&mut self) -> Result<i16, Error> { Err(SyntaxError) }
|
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_i8(&mut self) -> Result<i8, Error> { Err(SyntaxError) }
|
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_bool(&mut self) -> Result<bool, Error> { Err(SyntaxError) }
|
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_f64(&mut self) -> Result<f64, Error> { Err(SyntaxError) }
|
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_f32(&mut self) -> Result<f32, Error> { Err(SyntaxError) }
|
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_char(&mut self) -> Result<char, Error> { Err(SyntaxError) }
|
fn read_char(&mut self) -> Result<char, Error> { Err(Error::SyntaxError) }
|
||||||
fn read_str(&mut self) -> Result<String, Error> { Err(SyntaxError) }
|
fn read_str(&mut self) -> Result<String, Error> { Err(Error::SyntaxError) }
|
||||||
|
|
||||||
// Compound types:
|
// Compound types:
|
||||||
fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where
|
fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where
|
||||||
@@ -302,7 +304,7 @@ mod decoder {
|
|||||||
fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut U8Decoder, bool) -> Result<T, Error>,
|
F: FnOnce(&mut U8Decoder, bool) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -322,19 +324,19 @@ mod decoder {
|
|||||||
fn read_map<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
fn read_map<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut U8Decoder, usize) -> Result<T, Error>,
|
F: FnOnce(&mut U8Decoder, usize) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_map_elt_key<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
fn read_map_elt_key<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
|
F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_map_elt_val<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
fn read_map_elt_val<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
|
||||||
F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
|
F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
|
||||||
{
|
{
|
||||||
Err(SyntaxError)
|
Err(Error::SyntaxError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -346,8 +348,6 @@ mod deserializer {
|
|||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
use super::Error;
|
use super::Error;
|
||||||
use super::Error::{EndOfStream, SyntaxError};
|
|
||||||
use self::State::{StartState, SepOrEndState, EndState};
|
|
||||||
|
|
||||||
use serde::de;
|
use serde::de;
|
||||||
|
|
||||||
@@ -358,151 +358,141 @@ mod deserializer {
|
|||||||
EndState,
|
EndState,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct IsizeDeserializer {
|
pub struct Deserializer<A> {
|
||||||
state: State,
|
state: State,
|
||||||
|
iter: vec::IntoIter<A>,
|
||||||
len: usize,
|
len: usize,
|
||||||
iter: vec::IntoIter<isize>,
|
value: Option<A>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IsizeDeserializer {
|
impl<A> Deserializer<A> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(values: Vec<isize>) -> IsizeDeserializer {
|
pub fn new(values: Vec<A>) -> Deserializer<A> {
|
||||||
IsizeDeserializer {
|
let len = values.len();
|
||||||
state: StartState,
|
Deserializer {
|
||||||
len: values.len(),
|
state: State::StartState,
|
||||||
iter: values.into_iter(),
|
iter: values.into_iter(),
|
||||||
|
len: len,
|
||||||
|
value: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for IsizeDeserializer {
|
impl de::Deserializer for Deserializer<usize> {
|
||||||
type Item = Result<de::Token, Error>;
|
type Error = Error;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<Result<de::Token, Error>> {
|
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
|
where V: de::Visitor,
|
||||||
|
{
|
||||||
match self.state {
|
match self.state {
|
||||||
StartState => {
|
State::StartState => {
|
||||||
self.state = SepOrEndState;
|
self.state = State::SepOrEndState;
|
||||||
Some(Ok(de::Token::SeqStart(self.len)))
|
visitor.visit_seq(self)
|
||||||
}
|
}
|
||||||
SepOrEndState => {
|
State::SepOrEndState => {
|
||||||
match self.iter.next() {
|
visitor.visit_usize(self.value.take().unwrap())
|
||||||
Some(value) => {
|
|
||||||
Some(Ok(de::Token::Isize(value)))
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
self.state = EndState;
|
|
||||||
Some(Ok(de::Token::End))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
EndState => {
|
State::EndState => {
|
||||||
None
|
Err(Error::EndOfStreamError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl de::Deserializer<Error> for IsizeDeserializer {
|
impl de::SeqVisitor for Deserializer<usize> {
|
||||||
#[inline]
|
type Error = Error;
|
||||||
fn end_of_stream_error(&mut self) -> Error {
|
|
||||||
EndOfStream
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn syntax_error(&mut self, _token: de::Token, _expected: &[de::TokenKind]) -> Error {
|
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
||||||
SyntaxError
|
where T: de::Deserialize,
|
||||||
}
|
{
|
||||||
|
match self.iter.next() {
|
||||||
#[inline]
|
Some(value) => {
|
||||||
fn unexpected_name_error(&mut self, _token: de::Token) -> Error {
|
self.len -= 1;
|
||||||
SyntaxError
|
self.value = Some(value);
|
||||||
}
|
Ok(Some(try!(de::Deserialize::deserialize(self))))
|
||||||
|
}
|
||||||
#[inline]
|
None => {
|
||||||
fn conversion_error(&mut self, _token: de::Token) -> Error {
|
self.state = State::EndState;
|
||||||
SyntaxError
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn missing_field<
|
|
||||||
T: de::Deserialize<IsizeDeserializer, Error>
|
|
||||||
>(&mut self, _field: &'static str) -> Result<T, Error> {
|
|
||||||
Err(SyntaxError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct U8Deserializer {
|
|
||||||
state: State,
|
|
||||||
len: usize,
|
|
||||||
iter: vec::IntoIter<u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl U8Deserializer {
|
|
||||||
#[inline]
|
|
||||||
pub fn new(values: Vec<u8>) -> U8Deserializer {
|
|
||||||
U8Deserializer {
|
|
||||||
state: StartState,
|
|
||||||
len: values.len(),
|
|
||||||
iter: values.into_iter(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Iterator for U8Deserializer {
|
|
||||||
type Item = Result<de::Token, Error>;
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<Result<de::Token, Error>> {
|
fn end(&mut self) -> Result<(), Error> {
|
||||||
|
match self.iter.next() {
|
||||||
|
Some(_) => Err(Error::SyntaxError),
|
||||||
|
None => {
|
||||||
|
self.state = State::EndState;
|
||||||
|
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 visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
|
where V: de::Visitor,
|
||||||
|
{
|
||||||
match self.state {
|
match self.state {
|
||||||
StartState => {
|
State::StartState => {
|
||||||
self.state = SepOrEndState;
|
self.state = State::SepOrEndState;
|
||||||
Some(Ok(de::Token::SeqStart(self.len)))
|
visitor.visit_seq(self)
|
||||||
}
|
}
|
||||||
SepOrEndState => {
|
State::SepOrEndState => {
|
||||||
match self.iter.next() {
|
visitor.visit_u8(self.value.take().unwrap())
|
||||||
Some(value) => {
|
|
||||||
Some(Ok(de::Token::U8(value)))
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
self.state = EndState;
|
|
||||||
Some(Ok(de::Token::End))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
EndState => {
|
State::EndState => {
|
||||||
None
|
Err(Error::EndOfStreamError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl de::Deserializer<Error> for U8Deserializer {
|
impl de::SeqVisitor for Deserializer<u8> {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn end_of_stream_error(&mut self) -> Error {
|
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
||||||
EndOfStream
|
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::EndState;
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn syntax_error(&mut self, _token: de::Token, _expected: &[de::TokenKind]) -> Error {
|
fn end(&mut self) -> Result<(), Error> {
|
||||||
SyntaxError
|
match self.iter.next() {
|
||||||
|
Some(_) => Err(Error::SyntaxError),
|
||||||
|
None => {
|
||||||
|
self.state = State::EndState;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn unexpected_name_error(&mut self, _token: de::Token) -> Error {
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
SyntaxError
|
(self.len, Some(self.len))
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn conversion_error(&mut self, _token: de::Token) -> Error {
|
|
||||||
SyntaxError
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn missing_field<
|
|
||||||
T: de::Deserialize<U8Deserializer, Error>
|
|
||||||
>(&mut self, _field: &'static str) -> Result<T, Error> {
|
|
||||||
Err(SyntaxError)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -519,9 +509,9 @@ fn run_decoder<
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run_deserializer<
|
fn run_deserializer<
|
||||||
D: Deserializer<E>,
|
D: Deserializer<Error=E>,
|
||||||
E: Debug,
|
E: Debug,
|
||||||
T: Clone + PartialEq + Debug + Deserialize<D, E>
|
T: Clone + PartialEq + Debug + Deserialize
|
||||||
>(mut d: D, value: T) {
|
>(mut d: D, value: T) {
|
||||||
let v: T = Deserialize::deserialize(&mut d).unwrap();
|
let v: T = Deserialize::deserialize(&mut d).unwrap();
|
||||||
|
|
||||||
@@ -529,26 +519,26 @@ fn run_deserializer<
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_decoder_int_000(b: &mut Bencher) {
|
fn bench_decoder_usize_000(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let v: Vec<isize> = vec!();
|
let v: Vec<usize> = vec!();
|
||||||
run_decoder(decoder::IsizeDecoder::new(v.clone()), v)
|
run_decoder(decoder::UsizeDecoder::new(v.clone()), v)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_decoder_int_003(b: &mut Bencher) {
|
fn bench_decoder_usize_003(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let v: Vec<isize> = vec!(1, 2, 3);
|
let v: Vec<usize> = vec!(1, 2, 3);
|
||||||
run_decoder(decoder::IsizeDecoder::new(v.clone()), v)
|
run_decoder(decoder::UsizeDecoder::new(v.clone()), v)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_decoder_int_100(b: &mut Bencher) {
|
fn bench_decoder_usize_100(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let v: Vec<isize> = range(0is, 100).collect();
|
let v: Vec<usize> = range(0, 100).collect();
|
||||||
run_decoder(decoder::IsizeDecoder::new(v.clone()), v)
|
run_decoder(decoder::UsizeDecoder::new(v.clone()), v)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -577,26 +567,26 @@ fn bench_decoder_u8_100(b: &mut Bencher) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_deserializer_int_000(b: &mut Bencher) {
|
fn bench_deserializer_usize_000(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let v: Vec<isize> = vec!();
|
let v: Vec<usize> = vec!();
|
||||||
run_deserializer(deserializer::IsizeDeserializer::new(v.clone()), v)
|
run_deserializer(deserializer::Deserializer::new(v.clone()), v)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_deserializer_int_003(b: &mut Bencher) {
|
fn bench_deserializer_usize_003(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let v: Vec<isize> = vec!(1, 2, 3);
|
let v: Vec<usize> = vec!(1, 2, 3);
|
||||||
run_deserializer(deserializer::IsizeDeserializer::new(v.clone()), v)
|
run_deserializer(deserializer::Deserializer::new(v.clone()), v)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_deserializer_int_100(b: &mut Bencher) {
|
fn bench_deserializer_usize_100(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let v: Vec<isize> = range(0is, 100).collect();
|
let v: Vec<usize> = range(0, 100).collect();
|
||||||
run_deserializer(deserializer::IsizeDeserializer::new(v.clone()), v)
|
run_deserializer(deserializer::Deserializer::new(v.clone()), v)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -604,7 +594,7 @@ fn bench_deserializer_int_100(b: &mut Bencher) {
|
|||||||
fn bench_deserializer_u8_000(b: &mut Bencher) {
|
fn bench_deserializer_u8_000(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let v: Vec<u8> = vec!();
|
let v: Vec<u8> = vec!();
|
||||||
run_deserializer(deserializer::U8Deserializer::new(v.clone()), v)
|
run_deserializer(deserializer::Deserializer::new(v.clone()), v)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,7 +602,7 @@ fn bench_deserializer_u8_000(b: &mut Bencher) {
|
|||||||
fn bench_deserializer_u8_003(b: &mut Bencher) {
|
fn bench_deserializer_u8_003(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let v: Vec<u8> = vec!(1, 2, 3);
|
let v: Vec<u8> = vec!(1, 2, 3);
|
||||||
run_deserializer(deserializer::U8Deserializer::new(v.clone()), v)
|
run_deserializer(deserializer::Deserializer::new(v.clone()), v)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -620,6 +610,6 @@ fn bench_deserializer_u8_003(b: &mut Bencher) {
|
|||||||
fn bench_deserializer_u8_100(b: &mut Bencher) {
|
fn bench_deserializer_u8_100(b: &mut Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let v: Vec<u8> = range(0u8, 100).collect();
|
let v: Vec<u8> = range(0u8, 100).collect();
|
||||||
run_deserializer(deserializer::U8Deserializer::new(v.clone()), v)
|
run_deserializer(deserializer::Deserializer::new(v.clone()), v)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
-311
@@ -1,311 +0,0 @@
|
|||||||
#![feature(core, plugin, test)]
|
|
||||||
#![plugin(serde_macros)]
|
|
||||||
|
|
||||||
extern crate serde;
|
|
||||||
extern crate "rustc-serialize" as rustc_serialize;
|
|
||||||
extern crate test;
|
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
|
||||||
use std::string;
|
|
||||||
use rustc_serialize as serialize;
|
|
||||||
use test::Bencher;
|
|
||||||
|
|
||||||
use serde::de::Token;
|
|
||||||
|
|
||||||
use serde::json::{Parser, Value, from_str};
|
|
||||||
|
|
||||||
macro_rules! treemap {
|
|
||||||
($($k:expr => $v:expr),*) => ({
|
|
||||||
let mut _m = ::std::collections::BTreeMap::new();
|
|
||||||
$(_m.insert($k, $v);)*
|
|
||||||
_m
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn json_str(count: usize) -> string::String {
|
|
||||||
let mut src = "[".to_string();
|
|
||||||
for _ in range(0, count) {
|
|
||||||
src.push_str(r#"{"a":true,"b":null,"c":3.1415,"d":"Hello world","e":[1,2,3]},"#);
|
|
||||||
}
|
|
||||||
src.push_str("{}]");
|
|
||||||
src
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pretty_json_str(count: usize) -> string::String {
|
|
||||||
let mut src = "[\n".to_string();
|
|
||||||
for _ in range(0, count) {
|
|
||||||
src.push_str(
|
|
||||||
concat!(
|
|
||||||
" {\n",
|
|
||||||
" \"a\": true,\n",
|
|
||||||
" \"b\": null,\n",
|
|
||||||
" \"c\": 3.1415,\n",
|
|
||||||
" \"d\": \"Hello world\",\n",
|
|
||||||
" \"e\": [\n",
|
|
||||||
" 1,\n",
|
|
||||||
" 2,\n",
|
|
||||||
" 3\n",
|
|
||||||
" ]\n",
|
|
||||||
" },\n"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
src.push_str(" {}\n]");
|
|
||||||
src
|
|
||||||
}
|
|
||||||
|
|
||||||
fn encoder_json(count: usize) -> serialize::json::Json {
|
|
||||||
use rustc_serialize::json::Json;
|
|
||||||
|
|
||||||
let mut list = vec!();
|
|
||||||
for _ in range(0, count) {
|
|
||||||
list.push(Json::Object(treemap!(
|
|
||||||
"a".to_string() => Json::Boolean(true),
|
|
||||||
"b".to_string() => Json::Null,
|
|
||||||
"c".to_string() => Json::F64(3.1415),
|
|
||||||
"d".to_string() => Json::String("Hello world".to_string()),
|
|
||||||
"e".to_string() => Json::Array(vec!(
|
|
||||||
Json::U64(1),
|
|
||||||
Json::U64(2),
|
|
||||||
Json::U64(3)
|
|
||||||
))
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
list.push(Json::Object(BTreeMap::new()));
|
|
||||||
Json::Array(list)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serializer_json(count: usize) -> Value {
|
|
||||||
let mut list = vec!();
|
|
||||||
for _ in range(0, count) {
|
|
||||||
list.push(Value::Object(treemap!(
|
|
||||||
"a".to_string() => Value::Boolean(true),
|
|
||||||
"b".to_string() => Value::Null,
|
|
||||||
"c".to_string() => Value::Floating(3.1415),
|
|
||||||
"d".to_string() => Value::String("Hello world".to_string()),
|
|
||||||
"e".to_string() => Value::Array(vec!(
|
|
||||||
Value::Integer(1),
|
|
||||||
Value::Integer(2),
|
|
||||||
Value::Integer(3)
|
|
||||||
))
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
list.push(Value::Object(BTreeMap::new()));
|
|
||||||
Value::Array(list)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bench_encoder(b: &mut Bencher, count: usize) {
|
|
||||||
let src = json_str(count);
|
|
||||||
let json = encoder_json(count);
|
|
||||||
|
|
||||||
b.iter(|| {
|
|
||||||
assert_eq!(json.to_string(), src);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bench_encoder_pretty(b: &mut Bencher, count: usize) {
|
|
||||||
let src = pretty_json_str(count);
|
|
||||||
let json = encoder_json(count);
|
|
||||||
|
|
||||||
b.iter(|| {
|
|
||||||
assert_eq!(json.pretty().to_string(), src);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bench_serializer(b: &mut Bencher, count: usize) {
|
|
||||||
let src = json_str(count);
|
|
||||||
let json = serializer_json(count);
|
|
||||||
|
|
||||||
b.iter(|| {
|
|
||||||
assert_eq!(json.to_string(), src);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bench_serializer_pretty(b: &mut Bencher, count: usize) {
|
|
||||||
let src = pretty_json_str(count);
|
|
||||||
let json = serializer_json(count);
|
|
||||||
|
|
||||||
b.iter(|| {
|
|
||||||
assert_eq!(json.to_pretty_string(), src);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bench_decoder(b: &mut Bencher, count: usize) {
|
|
||||||
let src = json_str(count);
|
|
||||||
let json = encoder_json(count);
|
|
||||||
b.iter(|| {
|
|
||||||
assert_eq!(json, serialize::json::Json::from_str(&src).unwrap());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bench_deserializer(b: &mut Bencher, count: usize) {
|
|
||||||
let src = json_str(count);
|
|
||||||
let json = encoder_json(count);
|
|
||||||
b.iter(|| {
|
|
||||||
assert_eq!(json, serialize::json::Json::from_str(&src).unwrap());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bench_decoder_streaming(b: &mut Bencher, count: usize) {
|
|
||||||
let src = json_str(count);
|
|
||||||
|
|
||||||
b.iter( || {
|
|
||||||
use rustc_serialize::json::{Parser, JsonEvent, StackElement};
|
|
||||||
|
|
||||||
let mut parser = Parser::new(src.chars());
|
|
||||||
assert_eq!(parser.next(), Some(JsonEvent::ArrayStart));
|
|
||||||
for _ in range(0, count) {
|
|
||||||
assert_eq!(parser.next(), Some(JsonEvent::ObjectStart));
|
|
||||||
|
|
||||||
assert_eq!(parser.next(), Some(JsonEvent::BooleanValue(true)));
|
|
||||||
assert_eq!(parser.stack().top(), Some(StackElement::Key("a")));
|
|
||||||
|
|
||||||
assert_eq!(parser.next(), Some(JsonEvent::NullValue));
|
|
||||||
assert_eq!(parser.stack().top(), Some(StackElement::Key("b")));
|
|
||||||
|
|
||||||
assert_eq!(parser.next(), Some(JsonEvent::F64Value(3.1415)));
|
|
||||||
assert_eq!(parser.stack().top(), Some(StackElement::Key("c")));
|
|
||||||
|
|
||||||
assert_eq!(parser.next(), Some(JsonEvent::StringValue("Hello world".to_string())));
|
|
||||||
assert_eq!(parser.stack().top(), Some(StackElement::Key("d")));
|
|
||||||
|
|
||||||
assert_eq!(parser.next(), Some(JsonEvent::ArrayStart));
|
|
||||||
assert_eq!(parser.stack().top(), Some(StackElement::Key("e")));
|
|
||||||
assert_eq!(parser.next(), Some(JsonEvent::U64Value(1)));
|
|
||||||
assert_eq!(parser.next(), Some(JsonEvent::U64Value(2)));
|
|
||||||
assert_eq!(parser.next(), Some(JsonEvent::U64Value(3)));
|
|
||||||
assert_eq!(parser.next(), Some(JsonEvent::ArrayEnd));
|
|
||||||
|
|
||||||
assert_eq!(parser.next(), Some(JsonEvent::ObjectEnd));
|
|
||||||
}
|
|
||||||
assert_eq!(parser.next(), Some(JsonEvent::ObjectStart));
|
|
||||||
assert_eq!(parser.next(), Some(JsonEvent::ObjectEnd));
|
|
||||||
assert_eq!(parser.next(), Some(JsonEvent::ArrayEnd));
|
|
||||||
assert_eq!(parser.next(), None);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bench_deserializer_streaming(b: &mut Bencher, count: usize) {
|
|
||||||
let src = json_str(count);
|
|
||||||
|
|
||||||
b.iter( || {
|
|
||||||
let mut parser = Parser::new(src.bytes());
|
|
||||||
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::SeqStart(0))));
|
|
||||||
for _ in range(0, count) {
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::MapStart(0))));
|
|
||||||
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::String("a".to_string()))));
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::Bool(true))));
|
|
||||||
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::String("b".to_string()))));
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::Null)));
|
|
||||||
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::String("c".to_string()))));
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::F64(3.1415))));
|
|
||||||
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::String("d".to_string()))));
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::String("Hello world".to_string()))));
|
|
||||||
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::String("e".to_string()))));
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::SeqStart(0))));
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::I64(1))));
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::I64(2))));
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::I64(3))));
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::End)));
|
|
||||||
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::End)));
|
|
||||||
}
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::MapStart(0))));
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::End)));
|
|
||||||
assert_eq!(parser.next(), Some(Ok(Token::End)));
|
|
||||||
assert_eq!(parser.next(), None);
|
|
||||||
|
|
||||||
loop {
|
|
||||||
match parser.next() {
|
|
||||||
None => return,
|
|
||||||
Some(Ok(_)) => { }
|
|
||||||
Some(Err(err)) => { panic!("error: {:?}", err); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_encoder_001(b: &mut Bencher) {
|
|
||||||
bench_encoder(b, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_encoder_500(b: &mut Bencher) {
|
|
||||||
bench_encoder(b, 500)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_encoder_001_pretty(b: &mut Bencher) {
|
|
||||||
bench_encoder_pretty(b, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_encoder_500_pretty(b: &mut Bencher) {
|
|
||||||
bench_encoder_pretty(b, 500)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_serializer_001(b: &mut Bencher) {
|
|
||||||
bench_serializer(b, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_serializer_500(b: &mut Bencher) {
|
|
||||||
bench_serializer(b, 500)
|
|
||||||
}
|
|
||||||
#[bench]
|
|
||||||
fn bench_serializer_001_pretty(b: &mut Bencher) {
|
|
||||||
bench_serializer_pretty(b, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_serializer_500_pretty(b: &mut Bencher) {
|
|
||||||
bench_serializer_pretty(b, 500)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_decoder_001(b: &mut Bencher) {
|
|
||||||
bench_decoder(b, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_decoder_500(b: &mut Bencher) {
|
|
||||||
bench_decoder(b, 500)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_deserializer_001(b: &mut Bencher) {
|
|
||||||
bench_deserializer(b, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_deserializer_500(b: &mut Bencher) {
|
|
||||||
bench_deserializer(b, 500)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_decoder_001_streaming(b: &mut Bencher) {
|
|
||||||
bench_decoder_streaming(b, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_decoder_500_streaming(b: &mut Bencher) {
|
|
||||||
bench_decoder_streaming(b, 500)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_deserializer_001_streaming(b: &mut Bencher) {
|
|
||||||
bench_deserializer_streaming(b, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_deserializer_500_streaming(b: &mut Bencher) {
|
|
||||||
bench_deserializer_streaming(b, 500)
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
/target/
|
|
||||||
Cargo.lock
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "serde2"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
name = "serde2"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
rustc-serialize = "*"
|
|
||||||
|
|
||||||
[dev-dependencies.serde2_macros]
|
|
||||||
path = "serde2_macros/"
|
|
||||||
@@ -1,417 +0,0 @@
|
|||||||
#![feature(custom_derive, plugin, test)]
|
|
||||||
#![plugin(serde2_macros)]
|
|
||||||
|
|
||||||
extern crate serde2;
|
|
||||||
extern crate "rustc-serialize" as rustc_serialize;
|
|
||||||
extern crate test;
|
|
||||||
|
|
||||||
use test::Bencher;
|
|
||||||
|
|
||||||
use rustc_serialize::{Decoder, Decodable};
|
|
||||||
|
|
||||||
use serde2::de::{Deserializer, Deserialize};
|
|
||||||
|
|
||||||
use Animal::{Dog, Frog};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, RustcDecodable)]
|
|
||||||
#[derive_deserialize]
|
|
||||||
enum Animal {
|
|
||||||
Dog,
|
|
||||||
Frog(String, isize)
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Error {
|
|
||||||
EndOfStreamError,
|
|
||||||
SyntaxError,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl serde2::de::Error for Error {
|
|
||||||
fn syntax_error() -> Error { Error::SyntaxError }
|
|
||||||
|
|
||||||
fn end_of_stream_error() -> Error { Error::EndOfStreamError }
|
|
||||||
|
|
||||||
fn missing_field_error(_: &'static str) -> Error { Error::SyntaxError }
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
mod decoder {
|
|
||||||
use rustc_serialize::Decoder;
|
|
||||||
|
|
||||||
use super::{Animal, Error};
|
|
||||||
use super::Animal::{Dog, Frog};
|
|
||||||
use self::State::{AnimalState, IsizeState, StringState};
|
|
||||||
|
|
||||||
enum State {
|
|
||||||
AnimalState(Animal),
|
|
||||||
IsizeState(isize),
|
|
||||||
StringState(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct AnimalDecoder {
|
|
||||||
stack: Vec<State>,
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AnimalDecoder {
|
|
||||||
#[inline]
|
|
||||||
pub fn new(animal: Animal) -> AnimalDecoder {
|
|
||||||
AnimalDecoder {
|
|
||||||
stack: vec!(AnimalState(animal)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decoder for AnimalDecoder {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn error(&mut self, _: &str) -> Error { Error::SyntaxError }
|
|
||||||
|
|
||||||
// Primitive types:
|
|
||||||
fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_usize(&mut self) -> Result<usize, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::SyntaxError) }
|
|
||||||
#[inline]
|
|
||||||
fn read_isize(&mut self) -> Result<isize, Error> {
|
|
||||||
match self.stack.pop() {
|
|
||||||
Some(IsizeState(x)) => Ok(x),
|
|
||||||
_ => Err(Error::SyntaxError),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_char(&mut self) -> Result<char, Error> { Err(Error::SyntaxError) }
|
|
||||||
#[inline]
|
|
||||||
fn read_str(&mut self) -> Result<String, Error> {
|
|
||||||
match self.stack.pop() {
|
|
||||||
Some(StringState(x)) => Ok(x),
|
|
||||||
_ => Err(Error::SyntaxError),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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(AnimalState(animal)) => {
|
|
||||||
self.stack.push(AnimalState(animal));
|
|
||||||
if name == "Animal" {
|
|
||||||
f(self)
|
|
||||||
} else {
|
|
||||||
Err(Error::SyntaxError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => Err(Error::SyntaxError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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(AnimalState(Dog)) => "Dog",
|
|
||||||
Some(AnimalState(Frog(x0, x1))) => {
|
|
||||||
self.stack.push(IsizeState(x1));
|
|
||||||
self.stack.push(StringState(x0));
|
|
||||||
"Frog"
|
|
||||||
}
|
|
||||||
_ => { return Err(Error::SyntaxError); }
|
|
||||||
};
|
|
||||||
|
|
||||||
let idx = match names.iter().position(|n| *n == name) {
|
|
||||||
Some(idx) => idx,
|
|
||||||
None => { return Err(Error::SyntaxError); }
|
|
||||||
};
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
|
|
||||||
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
|
|
||||||
{
|
|
||||||
Err(Error::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
mod deserializer {
|
|
||||||
use super::{Animal, Error};
|
|
||||||
|
|
||||||
use serde2::de;
|
|
||||||
|
|
||||||
enum State {
|
|
||||||
AnimalState(Animal),
|
|
||||||
IsizeState(isize),
|
|
||||||
StringState(String),
|
|
||||||
UnitState,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct AnimalDeserializer {
|
|
||||||
stack: Vec<State>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AnimalDeserializer {
|
|
||||||
#[inline]
|
|
||||||
pub fn new(animal: Animal) -> AnimalDeserializer {
|
|
||||||
AnimalDeserializer {
|
|
||||||
stack: vec!(State::AnimalState(animal)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl de::Deserializer for AnimalDeserializer {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
||||||
where V: de::Visitor,
|
|
||||||
{
|
|
||||||
match self.stack.pop() {
|
|
||||||
Some(State::AnimalState(Animal::Dog)) => {
|
|
||||||
self.stack.push(State::UnitState);
|
|
||||||
visitor.visit_enum("Animal", "Dog", DogVisitor {
|
|
||||||
de: self,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Some(State::AnimalState(Animal::Frog(x0, x1))) => {
|
|
||||||
self.stack.push(State::IsizeState(x1));
|
|
||||||
self.stack.push(State::StringState(x0));
|
|
||||||
visitor.visit_enum("Animal", "Frog", FrogVisitor {
|
|
||||||
de: self,
|
|
||||||
state: 0,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Some(State::IsizeState(value)) => {
|
|
||||||
visitor.visit_isize(value)
|
|
||||||
}
|
|
||||||
Some(State::StringState(value)) => {
|
|
||||||
visitor.visit_string(value)
|
|
||||||
}
|
|
||||||
Some(State::UnitState) => {
|
|
||||||
visitor.visit_unit()
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
Err(Error::EndOfStreamError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DogVisitor<'a> {
|
|
||||||
de: &'a mut AnimalDeserializer,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> de::EnumVisitor for DogVisitor<'a> {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn visit_unit(&mut self) -> Result<(), Error> {
|
|
||||||
de::Deserialize::deserialize(self.de)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct FrogVisitor<'a> {
|
|
||||||
de: &'a mut AnimalDeserializer,
|
|
||||||
state: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> de::EnumVisitor for FrogVisitor<'a> {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
||||||
where V: de::EnumSeqVisitor,
|
|
||||||
{
|
|
||||||
visitor.visit(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::SyntaxError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = 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 = Frog("Henry".to_string(), 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 = 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 = Frog("Henry".to_string(), 349);
|
|
||||||
|
|
||||||
let mut d = deserializer::AnimalDeserializer::new(animal.clone());
|
|
||||||
let value: Animal = Deserialize::deserialize(&mut d).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(value, animal);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,462 +0,0 @@
|
|||||||
#![feature(custom_derive, core, plugin, test)]
|
|
||||||
#![plugin(serde2_macros)]
|
|
||||||
|
|
||||||
extern crate serde2;
|
|
||||||
extern crate "rustc-serialize" as rustc_serialize;
|
|
||||||
extern crate test;
|
|
||||||
|
|
||||||
use std::fmt::Debug;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use test::Bencher;
|
|
||||||
|
|
||||||
use rustc_serialize::{Decoder, Decodable};
|
|
||||||
|
|
||||||
use serde2::de::{Deserializer, Deserialize};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
|
||||||
pub enum Error {
|
|
||||||
EndOfStream,
|
|
||||||
SyntaxError,
|
|
||||||
MissingField,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl serde2::de::Error for Error {
|
|
||||||
fn syntax_error() -> Error { Error::SyntaxError }
|
|
||||||
|
|
||||||
fn end_of_stream_error() -> Error { Error::EndOfStream }
|
|
||||||
|
|
||||||
fn missing_field_error(_: &'static str) -> Error {
|
|
||||||
Error::MissingField
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
mod decoder {
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::collections::hash_map::IntoIter;
|
|
||||||
use rustc_serialize;
|
|
||||||
|
|
||||||
use super::Error;
|
|
||||||
use self::Value::{StringValue, IsizeValue};
|
|
||||||
|
|
||||||
enum Value {
|
|
||||||
StringValue(String),
|
|
||||||
IsizeValue(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::SyntaxError
|
|
||||||
}
|
|
||||||
|
|
||||||
// Primitive types:
|
|
||||||
fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_usize(&mut self) -> Result<usize, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::SyntaxError) }
|
|
||||||
#[inline]
|
|
||||||
fn read_isize(&mut self) -> Result<isize, Error> {
|
|
||||||
match self.stack.pop() {
|
|
||||||
Some(IsizeValue(x)) => Ok(x),
|
|
||||||
Some(_) => Err(Error::SyntaxError),
|
|
||||||
None => Err(Error::EndOfStream),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_char(&mut self) -> Result<char, Error> { Err(Error::SyntaxError) }
|
|
||||||
#[inline]
|
|
||||||
fn read_str(&mut self) -> Result<String, Error> {
|
|
||||||
match self.stack.pop() {
|
|
||||||
Some(StringValue(x)) => Ok(x),
|
|
||||||
Some(_) => Err(Error::SyntaxError),
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
|
|
||||||
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
|
|
||||||
{
|
|
||||||
Err(Error::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_seq<T, F>(&mut self, _f: F) -> Result<T, Error> where
|
|
||||||
F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
|
|
||||||
{
|
|
||||||
Err(Error::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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(IsizeValue(value));
|
|
||||||
self.stack.push(StringValue(key));
|
|
||||||
f(self)
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
Err(Error::SyntaxError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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 serde2::de;
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
|
||||||
enum State {
|
|
||||||
StartState,
|
|
||||||
KeyState(String),
|
|
||||||
ValueState(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 visit<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::KeyState(key)) => {
|
|
||||||
visitor.visit_string(key)
|
|
||||||
}
|
|
||||||
Some(State::ValueState(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::ValueState(value));
|
|
||||||
self.stack.push(State::KeyState(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::SyntaxError),
|
|
||||||
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(StartState) => {
|
|
||||||
self.stack.push(KeyOrEndState);
|
|
||||||
Some(Ok(de::Token::MapStart(self.len)))
|
|
||||||
}
|
|
||||||
Some(KeyOrEndState) => {
|
|
||||||
match self.iter.next() {
|
|
||||||
Some((key, value)) => {
|
|
||||||
self.stack.push(ValueState(value));
|
|
||||||
Some(Ok(de::Token::String(key)))
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
self.stack.push(EndState);
|
|
||||||
Some(Ok(de::Token::End))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some(ValueState(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_error(&mut self) -> Error {
|
|
||||||
EndOfStream
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn syntax_error(&mut self, _token: de::Token, _expected: &[de::TokenKind]) -> Error {
|
|
||||||
SyntaxError
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn unexpected_name_error(&mut self, _token: de::Token) -> Error {
|
|
||||||
SyntaxError
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn conversion_error(&mut self, _token: de::Token) -> Error {
|
|
||||||
SyntaxError
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn missing_field<
|
|
||||||
T: de::Deserialize<IsizeDeserializer, Error>
|
|
||||||
>(&mut self, _field: &'static str) -> Result<T, Error> {
|
|
||||||
Err(Error::SyntaxError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
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 range(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 range(0, 100) {
|
|
||||||
m.insert(i.to_string(), i);
|
|
||||||
}
|
|
||||||
run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run_deserializer<
|
|
||||||
D: Deserializer<Error=E>,
|
|
||||||
E: Debug,
|
|
||||||
T: Clone + PartialEq + Debug + Deserialize
|
|
||||||
>(mut d: D, value: T) {
|
|
||||||
let v: T = Deserialize::deserialize(&mut d).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(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 range(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 range(0, 100) {
|
|
||||||
m.insert(i.to_string(), i);
|
|
||||||
}
|
|
||||||
run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,726 +0,0 @@
|
|||||||
#![feature(custom_derive, plugin, test)]
|
|
||||||
#![plugin(serde2_macros)]
|
|
||||||
|
|
||||||
extern crate serde2;
|
|
||||||
extern crate "rustc-serialize" as rustc_serialize;
|
|
||||||
extern crate test;
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use test::Bencher;
|
|
||||||
|
|
||||||
use rustc_serialize::{Decoder, Decodable};
|
|
||||||
|
|
||||||
use serde2::de::{Deserializer, Deserialize};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, RustcDecodable)]
|
|
||||||
#[derive_deserialize]
|
|
||||||
struct Inner {
|
|
||||||
a: (),
|
|
||||||
b: usize,
|
|
||||||
c: HashMap<String, Option<char>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, RustcDecodable)]
|
|
||||||
#[derive_deserialize]
|
|
||||||
struct Outer {
|
|
||||||
inner: Vec<Inner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Error {
|
|
||||||
EndOfStream,
|
|
||||||
SyntaxError,
|
|
||||||
UnexpectedName,
|
|
||||||
ConversionError,
|
|
||||||
MissingField,
|
|
||||||
OtherError,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl serde2::de::Error for Error {
|
|
||||||
fn syntax_error() -> Error { Error::SyntaxError }
|
|
||||||
|
|
||||||
fn end_of_stream_error() -> Error { Error::EndOfStream }
|
|
||||||
|
|
||||||
fn missing_field_error(_: &'static str) -> Error {
|
|
||||||
Error::MissingField
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod decoder {
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use rustc_serialize::Decoder;
|
|
||||||
|
|
||||||
use super::{Outer, Inner, Error};
|
|
||||||
|
|
||||||
use self::State::{
|
|
||||||
OuterState,
|
|
||||||
InnerState,
|
|
||||||
NullState,
|
|
||||||
UsizeState,
|
|
||||||
CharState,
|
|
||||||
StringState,
|
|
||||||
FieldState,
|
|
||||||
VecState,
|
|
||||||
MapState,
|
|
||||||
OptionState,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
enum State {
|
|
||||||
OuterState(Outer),
|
|
||||||
InnerState(Inner),
|
|
||||||
NullState,
|
|
||||||
UsizeState(usize),
|
|
||||||
CharState(char),
|
|
||||||
StringState(String),
|
|
||||||
FieldState(&'static str),
|
|
||||||
VecState(Vec<Inner>),
|
|
||||||
MapState(HashMap<String, Option<char>>),
|
|
||||||
OptionState(bool),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct OuterDecoder {
|
|
||||||
stack: Vec<State>,
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OuterDecoder {
|
|
||||||
#[inline]
|
|
||||||
pub fn new(animal: Outer) -> OuterDecoder {
|
|
||||||
OuterDecoder {
|
|
||||||
stack: vec!(OuterState(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(NullState) => Ok(()),
|
|
||||||
_ => Err(Error::SyntaxError),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn read_usize(&mut self) -> Result<usize, Error> {
|
|
||||||
match self.stack.pop() {
|
|
||||||
Some(UsizeState(value)) => Ok(value),
|
|
||||||
_ => Err(Error::SyntaxError),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_isize(&mut self) -> Result<isize, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::SyntaxError) }
|
|
||||||
#[inline]
|
|
||||||
fn read_char(&mut self) -> Result<char, Error> {
|
|
||||||
match self.stack.pop() {
|
|
||||||
Some(CharState(c)) => Ok(c),
|
|
||||||
_ => Err(Error::SyntaxError),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn read_str(&mut self) -> Result<String, Error> {
|
|
||||||
match self.stack.pop() {
|
|
||||||
Some(StringState(value)) => Ok(value),
|
|
||||||
_ => Err(Error::SyntaxError),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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(OuterState(Outer { inner })) => {
|
|
||||||
if s_name == "Outer" {
|
|
||||||
self.stack.push(VecState(inner));
|
|
||||||
self.stack.push(FieldState("inner"));
|
|
||||||
f(self)
|
|
||||||
} else {
|
|
||||||
Err(Error::SyntaxError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some(InnerState(Inner { a: (), b, c })) => {
|
|
||||||
if s_name == "Inner" {
|
|
||||||
self.stack.push(MapState(c));
|
|
||||||
self.stack.push(FieldState("c"));
|
|
||||||
|
|
||||||
self.stack.push(UsizeState(b));
|
|
||||||
self.stack.push(FieldState("b"));
|
|
||||||
|
|
||||||
self.stack.push(NullState);
|
|
||||||
self.stack.push(FieldState("a"));
|
|
||||||
f(self)
|
|
||||||
} else {
|
|
||||||
Err(Error::SyntaxError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => Err(Error::SyntaxError),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[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(FieldState(name)) => {
|
|
||||||
if f_name == name {
|
|
||||||
f(self)
|
|
||||||
} else {
|
|
||||||
Err(Error::SyntaxError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => Err(Error::SyntaxError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
|
|
||||||
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
|
|
||||||
{
|
|
||||||
Err(Error::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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(OptionState(b)) => f(self, b),
|
|
||||||
_ => Err(Error::SyntaxError),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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(VecState(value)) => {
|
|
||||||
let len = value.len();
|
|
||||||
for inner in value.into_iter().rev() {
|
|
||||||
self.stack.push(InnerState(inner));
|
|
||||||
}
|
|
||||||
f(self, len)
|
|
||||||
}
|
|
||||||
_ => Err(Error::SyntaxError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[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(MapState(map)) => {
|
|
||||||
let len = map.len();
|
|
||||||
for (key, value) in map {
|
|
||||||
match value {
|
|
||||||
Some(c) => {
|
|
||||||
self.stack.push(CharState(c));
|
|
||||||
self.stack.push(OptionState(true));
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
self.stack.push(OptionState(false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.stack.push(StringState(key));
|
|
||||||
}
|
|
||||||
f(self, len)
|
|
||||||
}
|
|
||||||
_ => Err(Error::SyntaxError),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[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 serde2::de;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
enum State {
|
|
||||||
OuterState(Outer),
|
|
||||||
InnerState(Inner),
|
|
||||||
StrState(&'static str),
|
|
||||||
NullState,
|
|
||||||
UsizeState(usize),
|
|
||||||
CharState(char),
|
|
||||||
StringState(String),
|
|
||||||
OptionState(bool),
|
|
||||||
VecState(Vec<Inner>),
|
|
||||||
MapState(HashMap<String, Option<char>>),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct OuterDeserializer {
|
|
||||||
stack: Vec<State>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OuterDeserializer {
|
|
||||||
#[inline]
|
|
||||||
pub fn new(outer: Outer) -> OuterDeserializer {
|
|
||||||
OuterDeserializer {
|
|
||||||
stack: vec!(State::OuterState(outer)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl de::Deserializer for OuterDeserializer {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
||||||
where V: de::Visitor,
|
|
||||||
{
|
|
||||||
match self.stack.pop() {
|
|
||||||
Some(State::OuterState(Outer { inner })) => {
|
|
||||||
self.stack.push(State::VecState(inner));
|
|
||||||
self.stack.push(State::StrState("inner"));
|
|
||||||
|
|
||||||
visitor.visit_named_map("Outer", OuterMapVisitor {
|
|
||||||
de: self,
|
|
||||||
state: 0,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Some(State::InnerState(Inner { a: (), b, c })) => {
|
|
||||||
self.stack.push(State::MapState(c));
|
|
||||||
self.stack.push(State::StrState("c"));
|
|
||||||
|
|
||||||
self.stack.push(State::UsizeState(b));
|
|
||||||
self.stack.push(State::StrState("b"));
|
|
||||||
|
|
||||||
self.stack.push(State::NullState);
|
|
||||||
self.stack.push(State::StrState("a"));
|
|
||||||
|
|
||||||
visitor.visit_named_map("Inner", InnerMapVisitor {
|
|
||||||
de: self,
|
|
||||||
state: 0,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Some(State::VecState(value)) => {
|
|
||||||
visitor.visit_seq(OuterSeqVisitor {
|
|
||||||
de: self,
|
|
||||||
iter: value.into_iter(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Some(State::MapState(value)) => {
|
|
||||||
visitor.visit_map(MapVisitor {
|
|
||||||
de: self,
|
|
||||||
iter: value.into_iter(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Some(State::NullState) => {
|
|
||||||
visitor.visit_unit()
|
|
||||||
}
|
|
||||||
Some(State::UsizeState(x)) => {
|
|
||||||
visitor.visit_usize(x)
|
|
||||||
}
|
|
||||||
Some(State::CharState(x)) => {
|
|
||||||
visitor.visit_char(x)
|
|
||||||
}
|
|
||||||
Some(State::StrState(x)) => {
|
|
||||||
visitor.visit_str(x)
|
|
||||||
}
|
|
||||||
Some(State::StringState(x)) => {
|
|
||||||
visitor.visit_string(x)
|
|
||||||
}
|
|
||||||
Some(State::OptionState(false)) => {
|
|
||||||
visitor.visit_none()
|
|
||||||
}
|
|
||||||
Some(State::OptionState(true)) => {
|
|
||||||
visitor.visit_some(self)
|
|
||||||
}
|
|
||||||
None => Err(Error::EndOfStream),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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::InnerState(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::SyntaxError),
|
|
||||||
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 == 1 {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(Error::SyntaxError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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::CharState(value));
|
|
||||||
self.de.stack.push(State::OptionState(true));
|
|
||||||
self.de.stack.push(State::StringState(key));
|
|
||||||
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
|
|
||||||
}
|
|
||||||
Some((key, None)) => {
|
|
||||||
self.de.stack.push(State::OptionState(false));
|
|
||||||
self.de.stack.push(State::StringState(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::SyntaxError),
|
|
||||||
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_string(), Some('c'));
|
|
||||||
|
|
||||||
let outer = Outer {
|
|
||||||
inner: vec!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut d = decoder::OuterDecoder::new(outer.clone());
|
|
||||||
let value: Outer = Decodable::decode(&mut d).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(value, 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: Outer = Decodable::decode(&mut d).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(value, outer);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_decoder_1_5(b: &mut Bencher) {
|
|
||||||
b.iter(|| {
|
|
||||||
let mut map = HashMap::new();
|
|
||||||
map.insert("1".to_string(), Some('a'));
|
|
||||||
map.insert("2".to_string(), None);
|
|
||||||
map.insert("3".to_string(), Some('b'));
|
|
||||||
map.insert("4".to_string(), None);
|
|
||||||
map.insert("5".to_string(), Some('c'));
|
|
||||||
|
|
||||||
let outer = Outer {
|
|
||||||
inner: vec!(
|
|
||||||
Inner {
|
|
||||||
a: (),
|
|
||||||
b: 5,
|
|
||||||
c: map,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut d = decoder::OuterDecoder::new(outer.clone());
|
|
||||||
let value: Outer = Decodable::decode(&mut d).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(value, 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: Outer = Deserialize::deserialize(&mut d).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(value, 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: Outer = Deserialize::deserialize(&mut d).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(value, outer);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_deserializer_1_5(b: &mut Bencher) {
|
|
||||||
b.iter(|| {
|
|
||||||
let mut map = HashMap::new();
|
|
||||||
map.insert("1".to_string(), Some('a'));
|
|
||||||
map.insert("2".to_string(), None);
|
|
||||||
map.insert("3".to_string(), Some('b'));
|
|
||||||
map.insert("4".to_string(), None);
|
|
||||||
map.insert("5".to_string(), Some('c'));
|
|
||||||
|
|
||||||
let outer = Outer {
|
|
||||||
inner: vec!(
|
|
||||||
Inner {
|
|
||||||
a: (),
|
|
||||||
b: 5,
|
|
||||||
c: map,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut d = deserializer::OuterDeserializer::new(outer.clone());
|
|
||||||
let value: Outer = Deserialize::deserialize(&mut d).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(value, outer);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,615 +0,0 @@
|
|||||||
#![feature(core, plugin, test)]
|
|
||||||
#![plugin(serde2_macros)]
|
|
||||||
|
|
||||||
extern crate serde2;
|
|
||||||
extern crate "rustc-serialize" as rustc_serialize;
|
|
||||||
extern crate test;
|
|
||||||
|
|
||||||
use std::fmt::Debug;
|
|
||||||
use test::Bencher;
|
|
||||||
|
|
||||||
use rustc_serialize::{Decoder, Decodable};
|
|
||||||
|
|
||||||
use serde2::de::{Deserializer, Deserialize};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
|
||||||
pub enum Error {
|
|
||||||
EndOfStreamError,
|
|
||||||
SyntaxError,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl serde2::de::Error for Error {
|
|
||||||
fn syntax_error() -> Error { Error::SyntaxError }
|
|
||||||
|
|
||||||
fn end_of_stream_error() -> Error { Error::EndOfStreamError }
|
|
||||||
|
|
||||||
fn missing_field_error(_: &'static str) -> Error { Error::SyntaxError }
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
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::SyntaxError }
|
|
||||||
|
|
||||||
// Primitive types:
|
|
||||||
fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) }
|
|
||||||
#[inline]
|
|
||||||
fn read_usize(&mut self) -> Result<usize, Error> {
|
|
||||||
match self.iter.next() {
|
|
||||||
Some(value) => Ok(value),
|
|
||||||
None => Err(Error::EndOfStreamError),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_isize(&mut self) -> Result<isize, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_char(&mut self) -> Result<char, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_str(&mut self) -> Result<String, Error> { Err(Error::SyntaxError) }
|
|
||||||
|
|
||||||
// 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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
|
|
||||||
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
|
|
||||||
{
|
|
||||||
Err(Error::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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::SyntaxError }
|
|
||||||
|
|
||||||
// Primitive types:
|
|
||||||
fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_usize(&mut self) -> Result<usize, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::SyntaxError) }
|
|
||||||
#[inline]
|
|
||||||
fn read_u8(&mut self) -> Result<u8, Error> {
|
|
||||||
match self.iter.next() {
|
|
||||||
Some(value) => Ok(value),
|
|
||||||
None => Err(Error::EndOfStreamError),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn read_isize(&mut self) -> Result<isize, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_char(&mut self) -> Result<char, Error> { Err(Error::SyntaxError) }
|
|
||||||
fn read_str(&mut self) -> Result<String, Error> { Err(Error::SyntaxError) }
|
|
||||||
|
|
||||||
// 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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
|
|
||||||
F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
|
|
||||||
{
|
|
||||||
Err(Error::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SyntaxError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
mod deserializer {
|
|
||||||
//use std::num;
|
|
||||||
use std::vec;
|
|
||||||
|
|
||||||
use super::Error;
|
|
||||||
|
|
||||||
use serde2::de;
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
|
||||||
enum State {
|
|
||||||
StartState,
|
|
||||||
SepOrEndState,
|
|
||||||
EndState,
|
|
||||||
}
|
|
||||||
|
|
||||||
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::StartState,
|
|
||||||
iter: values.into_iter(),
|
|
||||||
len: len,
|
|
||||||
value: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl de::Deserializer for Deserializer<usize> {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
||||||
where V: de::Visitor,
|
|
||||||
{
|
|
||||||
match self.state {
|
|
||||||
State::StartState => {
|
|
||||||
self.state = State::SepOrEndState;
|
|
||||||
visitor.visit_seq(self)
|
|
||||||
}
|
|
||||||
State::SepOrEndState => {
|
|
||||||
visitor.visit_usize(self.value.take().unwrap())
|
|
||||||
}
|
|
||||||
State::EndState => {
|
|
||||||
Err(Error::EndOfStreamError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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::EndState;
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn end(&mut self) -> Result<(), Error> {
|
|
||||||
match self.iter.next() {
|
|
||||||
Some(_) => Err(Error::SyntaxError),
|
|
||||||
None => {
|
|
||||||
self.state = State::EndState;
|
|
||||||
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 visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
||||||
where V: de::Visitor,
|
|
||||||
{
|
|
||||||
match self.state {
|
|
||||||
State::StartState => {
|
|
||||||
self.state = State::SepOrEndState;
|
|
||||||
visitor.visit_seq(self)
|
|
||||||
}
|
|
||||||
State::SepOrEndState => {
|
|
||||||
visitor.visit_u8(self.value.take().unwrap())
|
|
||||||
}
|
|
||||||
State::EndState => {
|
|
||||||
Err(Error::EndOfStreamError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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::EndState;
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn end(&mut self) -> Result<(), Error> {
|
|
||||||
match self.iter.next() {
|
|
||||||
Some(_) => Err(Error::SyntaxError),
|
|
||||||
None => {
|
|
||||||
self.state = State::EndState;
|
|
||||||
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: Deserializer<Error=E>,
|
|
||||||
E: Debug,
|
|
||||||
T: Clone + PartialEq + Debug + Deserialize
|
|
||||||
>(mut d: D, value: T) {
|
|
||||||
let v: T = Deserialize::deserialize(&mut d).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(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> = range(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> = range(0u8, 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> = range(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> = range(0u8, 100).collect();
|
|
||||||
run_deserializer(deserializer::Deserializer::new(v.clone()), v)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/target
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "serde2_macros"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
name = "serde2_macros"
|
|
||||||
plugin = true
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
quasi = "0.1.0"
|
|
||||||
quasi_macros = "0.1.0"
|
|
||||||
aster = "0.1.2"
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,819 +0,0 @@
|
|||||||
use std::collections::{HashMap, BTreeMap};
|
|
||||||
use std::hash::Hash;
|
|
||||||
use std::marker::PhantomData;
|
|
||||||
use std::num::FromPrimitive;
|
|
||||||
use std::path;
|
|
||||||
use std::str;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
pub trait Error {
|
|
||||||
fn syntax_error() -> Self;
|
|
||||||
|
|
||||||
fn end_of_stream_error() -> Self;
|
|
||||||
|
|
||||||
fn missing_field_error(&'static str) -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Deserialize {
|
|
||||||
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
|
|
||||||
where D: Deserializer;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Deserializer {
|
|
||||||
type Error: Error;
|
|
||||||
|
|
||||||
fn visit<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor;
|
|
||||||
|
|
||||||
/// The `visit_option` method allows a `Deserialize` type to inform the
|
|
||||||
/// `Deserializer` that it's expecting an optional value. This allows
|
|
||||||
/// deserializers that encode an optional value as a nullable value to
|
|
||||||
/// convert the null value into a `None`, and a regular value as
|
|
||||||
/// `Some(value)`.
|
|
||||||
#[inline]
|
|
||||||
fn visit_option<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor,
|
|
||||||
{
|
|
||||||
self.visit(visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The `visit_enum` method allows a `Deserialize` type to inform the
|
|
||||||
/// `Deserializer` that it's expecting an enum value. This allows
|
|
||||||
/// deserializers that provide a custom enumeration serialization to
|
|
||||||
/// properly deserialize the type.
|
|
||||||
#[inline]
|
|
||||||
fn visit_enum<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor,
|
|
||||||
{
|
|
||||||
self.visit(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Visitor {
|
|
||||||
type Value;
|
|
||||||
|
|
||||||
fn visit_bool<E>(&mut self, _v: bool) -> Result<Self::Value, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
Err(Error::syntax_error())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_isize<E>(&mut self, v: isize) -> Result<Self::Value, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
self.visit_i64(v as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_i8<E>(&mut self, v: i8) -> Result<Self::Value, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
self.visit_i64(v as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_i16<E>(&mut self, v: i16) -> Result<Self::Value, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
self.visit_i64(v as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_i32<E>(&mut self, v: i32) -> Result<Self::Value, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
self.visit_i64(v as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_i64<E>(&mut self, _v: i64) -> Result<Self::Value, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
Err(Error::syntax_error())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_usize<E>(&mut self, v: usize) -> Result<Self::Value, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
self.visit_u64(v as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_u8<E>(&mut self, v: u8) -> Result<Self::Value, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
self.visit_u64(v as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_u16<E>(&mut self, v: u16) -> Result<Self::Value, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
self.visit_u64(v as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_u32<E>(&mut self, v: u32) -> Result<Self::Value, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
self.visit_u64(v as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_u64<E>(&mut self, _v: u64) -> Result<Self::Value, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
Err(Error::syntax_error())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_f32<E>(&mut self, v: f32) -> Result<Self::Value, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
self.visit_f64(v as f64)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_f64<E>(&mut self, _v: f64) -> Result<Self::Value, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
Err(Error::syntax_error())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_char<E>(&mut self, v: char) -> Result<Self::Value, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
// The unwraps in here should be safe.
|
|
||||||
let mut s = &mut [0; 4];
|
|
||||||
let len = v.encode_utf8(s).unwrap();
|
|
||||||
self.visit_str(str::from_utf8(&s[..len]).unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_str<E>(&mut self, _v: &str) -> Result<Self::Value, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
Err(Error::syntax_error())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_string<E>(&mut self, v: String) -> Result<Self::Value, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
self.visit_str(&v)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_unit<E>(&mut self) -> Result<Self::Value, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
Err(Error::syntax_error())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_named_unit<E>(&mut self, _name: &str) -> Result<Self::Value, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
self.visit_unit()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_none<E>(&mut self) -> Result<Self::Value, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
Err(Error::syntax_error())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_some<D>(&mut self, _deserializer: &mut D) -> Result<Self::Value, D::Error>
|
|
||||||
where D: Deserializer,
|
|
||||||
{
|
|
||||||
Err(Error::syntax_error())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_seq<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error>
|
|
||||||
where V: SeqVisitor,
|
|
||||||
{
|
|
||||||
Err(Error::syntax_error())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_named_seq<V>(&mut self, _name: &str, visitor: V) -> Result<Self::Value, V::Error>
|
|
||||||
where V: SeqVisitor,
|
|
||||||
{
|
|
||||||
self.visit_seq(visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_map<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error>
|
|
||||||
where V: MapVisitor,
|
|
||||||
{
|
|
||||||
Err(Error::syntax_error())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_named_map<V>(&mut self, _name: &str, visitor: V) -> Result<Self::Value, V::Error>
|
|
||||||
where V: MapVisitor,
|
|
||||||
{
|
|
||||||
self.visit_map(visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_enum<V>(&mut self,
|
|
||||||
_name: &str,
|
|
||||||
_variant: &str,
|
|
||||||
_visitor: V) -> Result<Self::Value, V::Error>
|
|
||||||
where V: EnumVisitor,
|
|
||||||
{
|
|
||||||
Err(Error::syntax_error())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_variant<V>(&mut self, _name: &str, _visitor: V) -> Result<Self::Value, V::Error>
|
|
||||||
where V: EnumVisitor,
|
|
||||||
{
|
|
||||||
Err(Error::syntax_error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
pub trait SeqVisitor {
|
|
||||||
type Error: Error;
|
|
||||||
|
|
||||||
fn visit<T>(&mut self) -> Result<Option<T>, Self::Error>
|
|
||||||
where T: Deserialize;
|
|
||||||
|
|
||||||
fn end(&mut self) -> Result<(), Self::Error>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
(0, None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, V> SeqVisitor for &'a mut V where V: SeqVisitor {
|
|
||||||
type Error = V::Error;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit<T>(&mut self) -> Result<Option<T>, V::Error>
|
|
||||||
where T: Deserialize
|
|
||||||
{
|
|
||||||
(**self).visit()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn end(&mut self) -> Result<(), V::Error> {
|
|
||||||
(**self).end()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
(**self).size_hint()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
pub trait MapVisitor {
|
|
||||||
type Error: Error;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit<K, V>(&mut self) -> Result<Option<(K, V)>, Self::Error>
|
|
||||||
where K: Deserialize,
|
|
||||||
V: Deserialize,
|
|
||||||
{
|
|
||||||
match try!(self.visit_key()) {
|
|
||||||
Some(key) => {
|
|
||||||
let value = try!(self.visit_value());
|
|
||||||
Ok(Some((key, value)))
|
|
||||||
}
|
|
||||||
None => Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_key<K>(&mut self) -> Result<Option<K>, Self::Error>
|
|
||||||
where K: Deserialize;
|
|
||||||
|
|
||||||
fn visit_value<V>(&mut self) -> Result<V, Self::Error>
|
|
||||||
where V: Deserialize;
|
|
||||||
|
|
||||||
fn end(&mut self) -> Result<(), Self::Error>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
(0, None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, V_> MapVisitor for &'a mut V_ where V_: MapVisitor {
|
|
||||||
type Error = V_::Error;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit<K, V>(&mut self) -> Result<Option<(K, V)>, V_::Error>
|
|
||||||
where K: Deserialize,
|
|
||||||
V: Deserialize,
|
|
||||||
{
|
|
||||||
(**self).visit()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_key<K>(&mut self) -> Result<Option<K>, V_::Error>
|
|
||||||
where K: Deserialize
|
|
||||||
{
|
|
||||||
(**self).visit_key()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_value<V>(&mut self) -> Result<V, V_::Error>
|
|
||||||
where V: Deserialize
|
|
||||||
{
|
|
||||||
(**self).visit_value()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn end(&mut self) -> Result<(), V_::Error> {
|
|
||||||
(**self).end()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
(**self).size_hint()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
pub trait EnumVisitor {
|
|
||||||
type Error: Error;
|
|
||||||
|
|
||||||
fn visit_unit(&mut self) -> Result<(), Self::Error> {
|
|
||||||
Err(Error::syntax_error())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_seq<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: EnumSeqVisitor,
|
|
||||||
{
|
|
||||||
Err(Error::syntax_error())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_map<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: EnumMapVisitor,
|
|
||||||
{
|
|
||||||
Err(Error::syntax_error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
pub trait EnumSeqVisitor {
|
|
||||||
type Value;
|
|
||||||
|
|
||||||
fn visit<V>(&mut self, visitor: V) -> Result<Self::Value, V::Error>
|
|
||||||
where V: SeqVisitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
pub trait EnumMapVisitor {
|
|
||||||
type Value;
|
|
||||||
|
|
||||||
fn visit<V>(&mut self, visitor: V) -> Result<Self::Value, V::Error>
|
|
||||||
where V: MapVisitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
struct UnitVisitor;
|
|
||||||
|
|
||||||
impl Visitor for UnitVisitor {
|
|
||||||
type Value = ();
|
|
||||||
|
|
||||||
fn visit_unit<E>(&mut self) -> Result<(), E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<(), V::Error>
|
|
||||||
where V: SeqVisitor,
|
|
||||||
{
|
|
||||||
visitor.end()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deserialize for () {
|
|
||||||
fn deserialize<D>(deserializer: &mut D) -> Result<(), D::Error>
|
|
||||||
where D: Deserializer,
|
|
||||||
{
|
|
||||||
deserializer.visit(UnitVisitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
struct BoolVisitor;
|
|
||||||
|
|
||||||
impl Visitor for BoolVisitor {
|
|
||||||
type Value = bool;
|
|
||||||
|
|
||||||
fn visit_bool<E>(&mut self, v: bool) -> Result<bool, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
Ok(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deserialize for bool {
|
|
||||||
fn deserialize<D>(deserializer: &mut D) -> Result<bool, D::Error>
|
|
||||||
where D: Deserializer,
|
|
||||||
{
|
|
||||||
deserializer.visit(BoolVisitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
macro_rules! impl_deserialize_num_method {
|
|
||||||
($src_ty:ty, $method:ident, $from_method:ident) => {
|
|
||||||
#[inline]
|
|
||||||
fn $method<E>(&mut self, v: $src_ty) -> Result<T, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
match FromPrimitive::$from_method(v) {
|
|
||||||
Some(v) => Ok(v),
|
|
||||||
None => Err(Error::syntax_error()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct PrimitiveVisitor<T> {
|
|
||||||
marker: PhantomData<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> PrimitiveVisitor<T> {
|
|
||||||
#[inline]
|
|
||||||
pub fn new() -> Self {
|
|
||||||
PrimitiveVisitor {
|
|
||||||
marker: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<
|
|
||||||
T: Deserialize + FromPrimitive
|
|
||||||
> self::Visitor for PrimitiveVisitor<T> {
|
|
||||||
type Value = T;
|
|
||||||
|
|
||||||
impl_deserialize_num_method!(isize, visit_isize, from_isize);
|
|
||||||
impl_deserialize_num_method!(i8, visit_i8, from_i8);
|
|
||||||
impl_deserialize_num_method!(i16, visit_i16, from_i16);
|
|
||||||
impl_deserialize_num_method!(i32, visit_i32, from_i32);
|
|
||||||
impl_deserialize_num_method!(i64, visit_i64, from_i64);
|
|
||||||
impl_deserialize_num_method!(usize, visit_usize, from_usize);
|
|
||||||
impl_deserialize_num_method!(u8, visit_u8, from_u8);
|
|
||||||
impl_deserialize_num_method!(u16, visit_u16, from_u16);
|
|
||||||
impl_deserialize_num_method!(u32, visit_u32, from_u32);
|
|
||||||
impl_deserialize_num_method!(u64, visit_u64, from_u64);
|
|
||||||
impl_deserialize_num_method!(f32, visit_f32, from_f32);
|
|
||||||
impl_deserialize_num_method!(f64, visit_f64, from_f64);
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! impl_deserialize_num {
|
|
||||||
($ty:ty) => {
|
|
||||||
impl Deserialize for $ty {
|
|
||||||
#[inline]
|
|
||||||
fn deserialize<D>(deserializer: &mut D) -> Result<$ty, D::Error>
|
|
||||||
where D: Deserializer,
|
|
||||||
{
|
|
||||||
deserializer.visit(PrimitiveVisitor::new())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_deserialize_num!(isize);
|
|
||||||
impl_deserialize_num!(i8);
|
|
||||||
impl_deserialize_num!(i16);
|
|
||||||
impl_deserialize_num!(i32);
|
|
||||||
impl_deserialize_num!(i64);
|
|
||||||
impl_deserialize_num!(usize);
|
|
||||||
impl_deserialize_num!(u8);
|
|
||||||
impl_deserialize_num!(u16);
|
|
||||||
impl_deserialize_num!(u32);
|
|
||||||
impl_deserialize_num!(u64);
|
|
||||||
impl_deserialize_num!(f32);
|
|
||||||
impl_deserialize_num!(f64);
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
struct CharVisitor;
|
|
||||||
|
|
||||||
impl Visitor for CharVisitor {
|
|
||||||
type Value = char;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_char<E>(&mut self, v: char) -> Result<char, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
Ok(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_str<E>(&mut self, v: &str) -> Result<char, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
let mut iter = v.chars();
|
|
||||||
if let Some(v) = iter.next() {
|
|
||||||
if iter.next().is_some() {
|
|
||||||
Err(Error::syntax_error())
|
|
||||||
} else {
|
|
||||||
Ok(v)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Err(Error::end_of_stream_error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deserialize for char {
|
|
||||||
#[inline]
|
|
||||||
fn deserialize<D>(deserializer: &mut D) -> Result<char, D::Error>
|
|
||||||
where D: Deserializer,
|
|
||||||
{
|
|
||||||
deserializer.visit(CharVisitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
struct StringVisitor;
|
|
||||||
|
|
||||||
impl Visitor for StringVisitor {
|
|
||||||
type Value = String;
|
|
||||||
|
|
||||||
fn visit_str<E>(&mut self, v: &str) -> Result<String, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
Ok(v.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_string<E>(&mut self, v: String) -> Result<String, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
Ok(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deserialize for String {
|
|
||||||
fn deserialize<D>(deserializer: &mut D) -> Result<String, D::Error>
|
|
||||||
where D: Deserializer,
|
|
||||||
{
|
|
||||||
deserializer.visit(StringVisitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
struct OptionVisitor<T> {
|
|
||||||
marker: PhantomData<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<
|
|
||||||
T: Deserialize,
|
|
||||||
> Visitor for OptionVisitor<T> {
|
|
||||||
type Value = Option<T>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_none<E>(&mut self) -> Result<Option<T>, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_some<D>(&mut self, deserializer: &mut D) -> Result<Option<T>, D::Error>
|
|
||||||
where D: Deserializer,
|
|
||||||
{
|
|
||||||
Ok(Some(try!(Deserialize::deserialize(deserializer))))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Deserialize for Option<T> where T: Deserialize {
|
|
||||||
fn deserialize<D>(deserializer: &mut D) -> Result<Option<T>, D::Error>
|
|
||||||
where D: Deserializer,
|
|
||||||
{
|
|
||||||
deserializer.visit_option(OptionVisitor { marker: PhantomData })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
pub struct VecVisitor<T> {
|
|
||||||
marker: PhantomData<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> VecVisitor<T> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
VecVisitor {
|
|
||||||
marker: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Visitor for VecVisitor<T> where T: Deserialize {
|
|
||||||
type Value = Vec<T>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<Vec<T>, V::Error>
|
|
||||||
where V: SeqVisitor,
|
|
||||||
{
|
|
||||||
let (len, _) = visitor.size_hint();
|
|
||||||
let mut values = Vec::with_capacity(len);
|
|
||||||
|
|
||||||
while let Some(value) = try!(visitor.visit()) {
|
|
||||||
values.push(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(values)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Deserialize> Deserialize for Vec<T> {
|
|
||||||
fn deserialize<D>(deserializer: &mut D) -> Result<Vec<T>, D::Error>
|
|
||||||
where D: Deserializer,
|
|
||||||
{
|
|
||||||
deserializer.visit(VecVisitor::new())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
macro_rules! tuple_impls {
|
|
||||||
() => {};
|
|
||||||
($($visitor:ident => ($($name:ident),+),)+) => {
|
|
||||||
$(
|
|
||||||
struct $visitor<$($name,)+> {
|
|
||||||
marker: PhantomData<($($name,)+)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<
|
|
||||||
$($name: Deserialize,)+
|
|
||||||
> Visitor for $visitor<$($name,)+> {
|
|
||||||
type Value = ($($name,)+);
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<($($name,)+), V::Error>
|
|
||||||
where V: SeqVisitor,
|
|
||||||
{
|
|
||||||
$(
|
|
||||||
let $name = match try!(visitor.visit()) {
|
|
||||||
Some(value) => value,
|
|
||||||
None => { return Err(Error::end_of_stream_error()); }
|
|
||||||
};
|
|
||||||
)+;
|
|
||||||
|
|
||||||
try!(visitor.end());
|
|
||||||
|
|
||||||
Ok(($($name,)+))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<
|
|
||||||
$($name: Deserialize),+
|
|
||||||
> Deserialize for ($($name,)+) {
|
|
||||||
#[inline]
|
|
||||||
fn deserialize<D>(deserializer: &mut D) -> Result<($($name,)+), D::Error>
|
|
||||||
where D: Deserializer,
|
|
||||||
{
|
|
||||||
deserializer.visit($visitor { marker: PhantomData })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tuple_impls! {
|
|
||||||
TupleVisitor1 => (T0),
|
|
||||||
TupleVisitor2 => (T0, T1),
|
|
||||||
TupleVisitor3 => (T0, T1, T2),
|
|
||||||
TupleVisitor4 => (T0, T1, T2, T3),
|
|
||||||
TupleVisitor5 => (T0, T1, T2, T3, T4),
|
|
||||||
TupleVisitor6 => (T0, T1, T2, T3, T4, T5),
|
|
||||||
TupleVisitor7 => (T0, T1, T2, T3, T4, T5, T6),
|
|
||||||
TupleVisitor8 => (T0, T1, T2, T3, T4, T5, T6, T7),
|
|
||||||
TupleVisitor9 => (T0, T1, T2, T3, T4, T5, T6, T7, T8),
|
|
||||||
TupleVisitor10 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9),
|
|
||||||
TupleVisitor11 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10),
|
|
||||||
TupleVisitor12 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11),
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
pub struct HashMapVisitor<K, V> {
|
|
||||||
marker: PhantomData<HashMap<K, V>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<K, V> HashMapVisitor<K, V> {
|
|
||||||
#[inline]
|
|
||||||
pub fn new() -> Self {
|
|
||||||
HashMapVisitor {
|
|
||||||
marker: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<K, V> Visitor for HashMapVisitor<K, V>
|
|
||||||
where K: Deserialize + Eq + Hash,
|
|
||||||
V: Deserialize,
|
|
||||||
{
|
|
||||||
type Value = HashMap<K, V>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_map<V_>(&mut self, mut visitor: V_) -> Result<HashMap<K, V>, V_::Error>
|
|
||||||
where V_: MapVisitor,
|
|
||||||
{
|
|
||||||
let (len, _) = visitor.size_hint();
|
|
||||||
let mut values = HashMap::with_capacity(len);
|
|
||||||
|
|
||||||
while let Some((key, value)) = try!(visitor.visit()) {
|
|
||||||
values.insert(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(values)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<K, V> Deserialize for HashMap<K, V>
|
|
||||||
where K: Deserialize + Eq + Hash,
|
|
||||||
V: Deserialize,
|
|
||||||
{
|
|
||||||
fn deserialize<D>(deserializer: &mut D) -> Result<HashMap<K, V>, D::Error>
|
|
||||||
where D: Deserializer,
|
|
||||||
{
|
|
||||||
deserializer.visit(HashMapVisitor::new())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
pub struct BTreeMapVisitor<K, V> {
|
|
||||||
marker: PhantomData<BTreeMap<K, V>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<K, V> BTreeMapVisitor<K, V> {
|
|
||||||
#[inline]
|
|
||||||
pub fn new() -> Self {
|
|
||||||
BTreeMapVisitor {
|
|
||||||
marker: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<K, V> Visitor for BTreeMapVisitor<K, V>
|
|
||||||
where K: Deserialize + Ord,
|
|
||||||
V: Deserialize
|
|
||||||
{
|
|
||||||
type Value = BTreeMap<K, V>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_map<Visitor>(&mut self, mut visitor: Visitor) -> Result<BTreeMap<K, V>, Visitor::Error>
|
|
||||||
where Visitor: MapVisitor,
|
|
||||||
{
|
|
||||||
let mut values = BTreeMap::new();
|
|
||||||
|
|
||||||
while let Some((key, value)) = try!(visitor.visit()) {
|
|
||||||
values.insert(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(values)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<
|
|
||||||
K: Deserialize + Eq + Ord,
|
|
||||||
V: Deserialize,
|
|
||||||
> Deserialize for BTreeMap<K, V> {
|
|
||||||
fn deserialize<D>(deserializer: &mut D) -> Result<BTreeMap<K, V>, D::Error>
|
|
||||||
where D: Deserializer,
|
|
||||||
{
|
|
||||||
deserializer.visit(BTreeMapVisitor::new())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
struct PathBufVisitor;
|
|
||||||
|
|
||||||
impl Visitor for PathBufVisitor {
|
|
||||||
type Value = path::PathBuf;
|
|
||||||
|
|
||||||
fn visit_str<E>(&mut self, v: &str) -> Result<path::PathBuf, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
Ok(path::PathBuf::new(&v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_string<E>(&mut self, v: String) -> Result<path::PathBuf, E>
|
|
||||||
where E: Error,
|
|
||||||
{
|
|
||||||
self.visit_str(&v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deserialize for path::PathBuf {
|
|
||||||
fn deserialize<D>(deserializer: &mut D) -> Result<path::PathBuf, D::Error>
|
|
||||||
where D: Deserializer,
|
|
||||||
{
|
|
||||||
deserializer.visit(PathBufVisitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
|
||||||
|
|
||||||
use ser::{self, Serialize};
|
|
||||||
use json::value::{self, Value};
|
|
||||||
|
|
||||||
pub struct ArrayBuilder {
|
|
||||||
array: Vec<Value>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ArrayBuilder {
|
|
||||||
pub fn new() -> ArrayBuilder {
|
|
||||||
ArrayBuilder { array: Vec::new() }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unwrap(self) -> Value {
|
|
||||||
Value::Array(self.array)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn push<T: ser::Serialize>(mut self, v: T) -> ArrayBuilder {
|
|
||||||
self.array.push(value::to_value(&v));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn push_array<F>(mut self, f: F) -> ArrayBuilder where
|
|
||||||
F: FnOnce(ArrayBuilder) -> ArrayBuilder
|
|
||||||
{
|
|
||||||
let builder = ArrayBuilder::new();
|
|
||||||
self.array.push(f(builder).unwrap());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn push_object<F>(mut self, f: F) -> ArrayBuilder where
|
|
||||||
F: FnOnce(ObjectBuilder) -> ObjectBuilder
|
|
||||||
{
|
|
||||||
let builder = ObjectBuilder::new();
|
|
||||||
self.array.push(f(builder).unwrap());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ObjectBuilder {
|
|
||||||
object: BTreeMap<String, Value>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ObjectBuilder {
|
|
||||||
pub fn new() -> ObjectBuilder {
|
|
||||||
ObjectBuilder { object: BTreeMap::new() }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unwrap(self) -> Value {
|
|
||||||
Value::Object(self.object)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert<V: ser::Serialize>(mut self, k: String, v: V) -> ObjectBuilder {
|
|
||||||
self.object.insert(k, value::to_value(&v));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_array<F>(mut self, key: String, f: F) -> ObjectBuilder where
|
|
||||||
F: FnOnce(ArrayBuilder) -> ArrayBuilder
|
|
||||||
{
|
|
||||||
let builder = ArrayBuilder::new();
|
|
||||||
self.object.insert(key, f(builder).unwrap());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_object<F>(mut self, key: String, f: F) -> ObjectBuilder where
|
|
||||||
F: FnOnce(ObjectBuilder) -> ObjectBuilder
|
|
||||||
{
|
|
||||||
let builder = ObjectBuilder::new();
|
|
||||||
self.object.insert(key, f(builder).unwrap());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,636 +0,0 @@
|
|||||||
use std::char;
|
|
||||||
use std::num::Float;
|
|
||||||
use unicode::str::Utf16Item;
|
|
||||||
use std::str;
|
|
||||||
|
|
||||||
use de;
|
|
||||||
use super::error::{Error, ErrorCode};
|
|
||||||
|
|
||||||
pub struct Deserializer<Iter> {
|
|
||||||
rdr: Iter,
|
|
||||||
ch: Option<u8>,
|
|
||||||
line: usize,
|
|
||||||
col: usize,
|
|
||||||
buf: Vec<u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Iter> Deserializer<Iter>
|
|
||||||
where Iter: Iterator<Item=u8>,
|
|
||||||
{
|
|
||||||
/// Creates the JSON parser.
|
|
||||||
#[inline]
|
|
||||||
pub fn new(rdr: Iter) -> Deserializer<Iter> {
|
|
||||||
let mut p = Deserializer {
|
|
||||||
rdr: rdr,
|
|
||||||
ch: Some(b'\x00'),
|
|
||||||
line: 1,
|
|
||||||
col: 0,
|
|
||||||
buf: Vec::with_capacity(128),
|
|
||||||
};
|
|
||||||
p.bump();
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn end(&mut self) -> Result<(), Error> {
|
|
||||||
self.parse_whitespace();
|
|
||||||
if self.eof() {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(self.error(ErrorCode::TrailingCharacters))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn eof(&self) -> bool { self.ch.is_none() }
|
|
||||||
|
|
||||||
fn ch_or_null(&self) -> u8 { self.ch.unwrap_or(b'\x00') }
|
|
||||||
|
|
||||||
fn bump(&mut self) {
|
|
||||||
self.ch = self.rdr.next();
|
|
||||||
|
|
||||||
if self.ch_is(b'\n') {
|
|
||||||
self.line += 1;
|
|
||||||
self.col = 1;
|
|
||||||
} else {
|
|
||||||
self.col += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn next_char(&mut self) -> Option<u8> {
|
|
||||||
self.bump();
|
|
||||||
self.ch
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ch_is(&self, c: u8) -> bool {
|
|
||||||
self.ch == Some(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn error(&mut self, reason: ErrorCode) -> Error {
|
|
||||||
Error::SyntaxError(reason, self.line, self.col)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_whitespace(&mut self) {
|
|
||||||
while self.ch_is(b' ') ||
|
|
||||||
self.ch_is(b'\n') ||
|
|
||||||
self.ch_is(b'\t') ||
|
|
||||||
self.ch_is(b'\r') { self.bump(); }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_value<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
||||||
where V: de::Visitor,
|
|
||||||
{
|
|
||||||
self.parse_whitespace();
|
|
||||||
|
|
||||||
if self.eof() {
|
|
||||||
return Err(self.error(ErrorCode::EOFWhileParsingValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
match self.ch_or_null() {
|
|
||||||
b'n' => {
|
|
||||||
try!(self.parse_ident(b"ull"));
|
|
||||||
visitor.visit_unit()
|
|
||||||
}
|
|
||||||
b't' => {
|
|
||||||
try!(self.parse_ident(b"rue"));
|
|
||||||
visitor.visit_bool(true)
|
|
||||||
}
|
|
||||||
b'f' => {
|
|
||||||
try!(self.parse_ident(b"alse"));
|
|
||||||
visitor.visit_bool(false)
|
|
||||||
}
|
|
||||||
b'0' ... b'9' | b'-' => self.parse_number(visitor),
|
|
||||||
b'"' => {
|
|
||||||
try!(self.parse_string());
|
|
||||||
let s = str::from_utf8(&self.buf).unwrap();
|
|
||||||
visitor.visit_str(s)
|
|
||||||
}
|
|
||||||
b'[' => {
|
|
||||||
self.bump();
|
|
||||||
visitor.visit_seq(SeqVisitor::new(self))
|
|
||||||
}
|
|
||||||
b'{' => {
|
|
||||||
self.bump();
|
|
||||||
visitor.visit_map(MapVisitor::new(self))
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
Err(self.error(ErrorCode::ExpectedSomeValue))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_ident(&mut self, ident: &[u8]) -> Result<(), Error> {
|
|
||||||
if ident.iter().all(|c| Some(*c) == self.next_char()) {
|
|
||||||
self.bump();
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(self.error(ErrorCode::ExpectedSomeIdent))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_number<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
||||||
where V: de::Visitor,
|
|
||||||
{
|
|
||||||
let mut neg = 1;
|
|
||||||
|
|
||||||
if self.ch_is(b'-') {
|
|
||||||
self.bump();
|
|
||||||
neg = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
let res = try!(self.parse_integer());
|
|
||||||
|
|
||||||
if self.ch_is(b'.') || self.ch_is(b'e') || self.ch_is(b'E') {
|
|
||||||
let neg = neg as f64;
|
|
||||||
let mut res = res as f64;
|
|
||||||
|
|
||||||
if self.ch_is(b'.') {
|
|
||||||
res = try!(self.parse_decimal(res));
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.ch_is(b'e') || self.ch_is(b'E') {
|
|
||||||
res = try!(self.parse_exponent(res));
|
|
||||||
}
|
|
||||||
|
|
||||||
visitor.visit_f64(neg * res)
|
|
||||||
} else {
|
|
||||||
visitor.visit_i64(neg * res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_integer(&mut self) -> Result<i64, Error> {
|
|
||||||
let mut res = 0;
|
|
||||||
|
|
||||||
match self.ch_or_null() {
|
|
||||||
b'0' => {
|
|
||||||
self.bump();
|
|
||||||
|
|
||||||
// There can be only one leading '0'.
|
|
||||||
match self.ch_or_null() {
|
|
||||||
b'0' ... b'9' => {
|
|
||||||
return Err(self.error(ErrorCode::InvalidNumber));
|
|
||||||
}
|
|
||||||
_ => ()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
b'1' ... b'9' => {
|
|
||||||
while !self.eof() {
|
|
||||||
match self.ch_or_null() {
|
|
||||||
c @ b'0' ... b'9' => {
|
|
||||||
res *= 10;
|
|
||||||
res += (c as i64) - (b'0' as i64);
|
|
||||||
self.bump();
|
|
||||||
}
|
|
||||||
_ => break,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => { return Err(self.error(ErrorCode::InvalidNumber)); }
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_decimal(&mut self, res: f64) -> Result<f64, Error> {
|
|
||||||
self.bump();
|
|
||||||
|
|
||||||
// Make sure a digit follows the decimal place.
|
|
||||||
match self.ch_or_null() {
|
|
||||||
b'0' ... b'9' => (),
|
|
||||||
_ => { return Err(self.error(ErrorCode::InvalidNumber)); }
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut res = res;
|
|
||||||
let mut dec = 1.0;
|
|
||||||
while !self.eof() {
|
|
||||||
match self.ch_or_null() {
|
|
||||||
c @ b'0' ... b'9' => {
|
|
||||||
dec /= 10.0;
|
|
||||||
res += (((c as u64) - (b'0' as u64)) as f64) * dec;
|
|
||||||
self.bump();
|
|
||||||
}
|
|
||||||
_ => break,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_exponent(&mut self, mut res: f64) -> Result<f64, Error> {
|
|
||||||
self.bump();
|
|
||||||
|
|
||||||
let mut exp = 0;
|
|
||||||
let mut neg_exp = false;
|
|
||||||
|
|
||||||
if self.ch_is(b'+') {
|
|
||||||
self.bump();
|
|
||||||
} else if self.ch_is(b'-') {
|
|
||||||
self.bump();
|
|
||||||
neg_exp = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure a digit follows the exponent place.
|
|
||||||
match self.ch_or_null() {
|
|
||||||
b'0' ... b'9' => (),
|
|
||||||
_ => { return Err(self.error(ErrorCode::InvalidNumber)); }
|
|
||||||
}
|
|
||||||
while !self.eof() {
|
|
||||||
match self.ch_or_null() {
|
|
||||||
c @ b'0' ... b'9' => {
|
|
||||||
exp *= 10;
|
|
||||||
exp += (c as i32) - (b'0' as i32);
|
|
||||||
|
|
||||||
self.bump();
|
|
||||||
}
|
|
||||||
_ => break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let exp: f64 = 10_f64.powi(exp);
|
|
||||||
if neg_exp {
|
|
||||||
res /= exp;
|
|
||||||
} else {
|
|
||||||
res *= exp;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn decode_hex_escape(&mut self) -> Result<u16, Error> {
|
|
||||||
let mut i = 0;
|
|
||||||
let mut n = 0u16;
|
|
||||||
while i < 4 && !self.eof() {
|
|
||||||
self.bump();
|
|
||||||
n = match self.ch_or_null() {
|
|
||||||
c @ b'0' ... b'9' => n * 16_u16 + ((c as u16) - (b'0' as u16)),
|
|
||||||
b'a' | b'A' => n * 16_u16 + 10_u16,
|
|
||||||
b'b' | b'B' => n * 16_u16 + 11_u16,
|
|
||||||
b'c' | b'C' => n * 16_u16 + 12_u16,
|
|
||||||
b'd' | b'D' => n * 16_u16 + 13_u16,
|
|
||||||
b'e' | b'E' => n * 16_u16 + 14_u16,
|
|
||||||
b'f' | b'F' => n * 16_u16 + 15_u16,
|
|
||||||
_ => { return Err(self.error(ErrorCode::InvalidEscape)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error out if we didn't parse 4 digits.
|
|
||||||
if i != 4 {
|
|
||||||
return Err(self.error(ErrorCode::InvalidEscape));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(n)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_string(&mut self) -> Result<(), Error> {
|
|
||||||
self.buf.clear();
|
|
||||||
|
|
||||||
let mut escape = false;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let ch = match self.next_char() {
|
|
||||||
Some(ch) => ch,
|
|
||||||
None => { return Err(self.error(ErrorCode::EOFWhileParsingString)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
if escape {
|
|
||||||
match ch {
|
|
||||||
b'"' => self.buf.push(b'"'),
|
|
||||||
b'\\' => self.buf.push(b'\\'),
|
|
||||||
b'/' => self.buf.push(b'/'),
|
|
||||||
b'b' => self.buf.push(b'\x08'),
|
|
||||||
b'f' => self.buf.push(b'\x0c'),
|
|
||||||
b'n' => self.buf.push(b'\n'),
|
|
||||||
b'r' => self.buf.push(b'\r'),
|
|
||||||
b't' => self.buf.push(b'\t'),
|
|
||||||
b'u' => {
|
|
||||||
let c = match try!(self.decode_hex_escape()) {
|
|
||||||
0xDC00 ... 0xDFFF => {
|
|
||||||
return Err(self.error(ErrorCode::LoneLeadingSurrogateInHexEscape));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Non-BMP characters are encoded as a sequence of
|
|
||||||
// two hex escapes, representing UTF-16 surrogates.
|
|
||||||
n1 @ 0xD800 ... 0xDBFF => {
|
|
||||||
let c1 = self.next_char();
|
|
||||||
let c2 = self.next_char();
|
|
||||||
match (c1, c2) {
|
|
||||||
(Some(b'\\'), Some(b'u')) => (),
|
|
||||||
_ => {
|
|
||||||
return Err(self.error(ErrorCode::UnexpectedEndOfHexEscape));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let buf = &[n1, try!(self.decode_hex_escape())];
|
|
||||||
match ::unicode::str::utf16_items(buf).next() {
|
|
||||||
Some(Utf16Item::ScalarValue(c)) => c,
|
|
||||||
_ => {
|
|
||||||
return Err(self.error(ErrorCode::LoneLeadingSurrogateInHexEscape));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
n => match char::from_u32(n as u32) {
|
|
||||||
Some(c) => c,
|
|
||||||
None => {
|
|
||||||
return Err(self.error(ErrorCode::InvalidUnicodeCodePoint));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let buf = &mut [0; 4];
|
|
||||||
let len = c.encode_utf8(buf).unwrap_or(0);
|
|
||||||
self.buf.extend(buf[..len].iter().map(|b| *b));
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return Err(self.error(ErrorCode::InvalidEscape));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
escape = false;
|
|
||||||
} else {
|
|
||||||
match ch {
|
|
||||||
b'"' => {
|
|
||||||
self.bump();
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
b'\\' => {
|
|
||||||
escape = true;
|
|
||||||
}
|
|
||||||
ch => {
|
|
||||||
self.buf.push(ch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_object_colon(&mut self) -> Result<(), Error> {
|
|
||||||
self.parse_whitespace();
|
|
||||||
|
|
||||||
if self.ch_is(b':') {
|
|
||||||
self.bump();
|
|
||||||
Ok(())
|
|
||||||
} else if self.eof() {
|
|
||||||
Err(self.error(ErrorCode::EOFWhileParsingObject))
|
|
||||||
} else {
|
|
||||||
Err(self.error(ErrorCode::ExpectedColon))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Iter> de::Deserializer for Deserializer<Iter>
|
|
||||||
where Iter: Iterator<Item=u8>,
|
|
||||||
{
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit<V>(&mut self, visitor: V) -> Result<V::Value, Error>
|
|
||||||
where V: de::Visitor,
|
|
||||||
{
|
|
||||||
self.parse_value(visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
||||||
where V: de::Visitor,
|
|
||||||
{
|
|
||||||
self.parse_whitespace();
|
|
||||||
|
|
||||||
if self.eof() {
|
|
||||||
return Err(self.error(ErrorCode::EOFWhileParsingValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.ch_is(b'n') {
|
|
||||||
try!(self.parse_ident(b"ull"));
|
|
||||||
visitor.visit_none()
|
|
||||||
} else {
|
|
||||||
visitor.visit_some(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_enum<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
||||||
where V: de::Visitor,
|
|
||||||
{
|
|
||||||
self.parse_whitespace();
|
|
||||||
|
|
||||||
if self.ch_is(b'{') {
|
|
||||||
self.bump();
|
|
||||||
self.parse_whitespace();
|
|
||||||
|
|
||||||
try!(self.parse_string());
|
|
||||||
try!(self.parse_object_colon());
|
|
||||||
|
|
||||||
let variant = str::from_utf8(&self.buf).unwrap().to_string();
|
|
||||||
|
|
||||||
let value = try!(visitor.visit_variant(&variant, EnumVisitor {
|
|
||||||
de: self,
|
|
||||||
}));
|
|
||||||
|
|
||||||
self.parse_whitespace();
|
|
||||||
|
|
||||||
if self.ch_is(b'}') {
|
|
||||||
self.bump();
|
|
||||||
Ok(value)
|
|
||||||
} else {
|
|
||||||
return Err(self.error(ErrorCode::ExpectedSomeValue));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Err(self.error(ErrorCode::ExpectedSomeValue))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SeqVisitor<'a, Iter: 'a> {
|
|
||||||
de: &'a mut Deserializer<Iter>,
|
|
||||||
first: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, Iter> SeqVisitor<'a, Iter> {
|
|
||||||
fn new(de: &'a mut Deserializer<Iter>) -> Self {
|
|
||||||
SeqVisitor {
|
|
||||||
de: de,
|
|
||||||
first: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter>
|
|
||||||
where Iter: Iterator<Item=u8>
|
|
||||||
{
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
|
||||||
where T: de::Deserialize,
|
|
||||||
{
|
|
||||||
self.de.parse_whitespace();
|
|
||||||
|
|
||||||
if self.de.ch_is(b']') {
|
|
||||||
self.de.bump();
|
|
||||||
return Ok(None);
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.first {
|
|
||||||
self.first = false;
|
|
||||||
} else {
|
|
||||||
if self.de.ch_is(b',') {
|
|
||||||
self.de.bump();
|
|
||||||
} else if self.de.eof() {
|
|
||||||
return Err(self.de.error(ErrorCode::EOFWhileParsingList));
|
|
||||||
} else {
|
|
||||||
return Err(self.de.error(ErrorCode::ExpectedListCommaOrEnd));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let value = try!(de::Deserialize::deserialize(self.de));
|
|
||||||
Ok(Some(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end(&mut self) -> Result<(), Error> {
|
|
||||||
self.de.parse_whitespace();
|
|
||||||
|
|
||||||
if self.de.ch_is(b']') {
|
|
||||||
self.de.bump();
|
|
||||||
Ok(())
|
|
||||||
} else if self.de.eof() {
|
|
||||||
Err(self.de.error(ErrorCode::EOFWhileParsingList))
|
|
||||||
} else {
|
|
||||||
Err(self.de.error(ErrorCode::TrailingCharacters))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MapVisitor<'a, Iter: 'a> {
|
|
||||||
de: &'a mut Deserializer<Iter>,
|
|
||||||
first: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, Iter> MapVisitor<'a, Iter> {
|
|
||||||
fn new(de: &'a mut Deserializer<Iter>) -> Self {
|
|
||||||
MapVisitor {
|
|
||||||
de: de,
|
|
||||||
first: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter>
|
|
||||||
where Iter: Iterator<Item=u8>
|
|
||||||
{
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
|
|
||||||
where K: de::Deserialize,
|
|
||||||
{
|
|
||||||
self.de.parse_whitespace();
|
|
||||||
|
|
||||||
if self.de.ch_is(b'}') {
|
|
||||||
self.de.bump();
|
|
||||||
return Ok(None);
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.first {
|
|
||||||
self.first = false;
|
|
||||||
} else {
|
|
||||||
if self.de.ch_is(b',') {
|
|
||||||
self.de.bump();
|
|
||||||
self.de.parse_whitespace();
|
|
||||||
} else if self.de.eof() {
|
|
||||||
return Err(self.de.error(ErrorCode::EOFWhileParsingObject));
|
|
||||||
} else {
|
|
||||||
return Err(self.de.error(ErrorCode::ExpectedObjectCommaOrEnd));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.de.eof() {
|
|
||||||
return Err(self.de.error(ErrorCode::EOFWhileParsingValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
if !self.de.ch_is(b'"') {
|
|
||||||
return Err(self.de.error(ErrorCode::KeyMustBeAString));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_value<V>(&mut self) -> Result<V, Error>
|
|
||||||
where V: de::Deserialize,
|
|
||||||
{
|
|
||||||
try!(self.de.parse_object_colon());
|
|
||||||
|
|
||||||
Ok(try!(de::Deserialize::deserialize(self.de)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end(&mut self) -> Result<(), Error> {
|
|
||||||
self.de.parse_whitespace();
|
|
||||||
|
|
||||||
if self.de.ch_is(b']') {
|
|
||||||
self.de.bump();
|
|
||||||
Ok(())
|
|
||||||
} else if self.de.eof() {
|
|
||||||
Err(self.de.error(ErrorCode::EOFWhileParsingList))
|
|
||||||
} else {
|
|
||||||
Err(self.de.error(ErrorCode::TrailingCharacters))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct EnumVisitor<'a, Iter: 'a> {
|
|
||||||
de: &'a mut Deserializer<Iter>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, Iter> de::EnumVisitor for EnumVisitor<'a, Iter>
|
|
||||||
where Iter: Iterator<Item=u8>,
|
|
||||||
{
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn visit_unit(&mut self) -> Result<(), Error> {
|
|
||||||
de::Deserialize::deserialize(self.de)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
||||||
where V: de::EnumSeqVisitor,
|
|
||||||
{
|
|
||||||
self.de.parse_whitespace();
|
|
||||||
|
|
||||||
if self.de.ch_is(b'[') {
|
|
||||||
self.de.bump();
|
|
||||||
visitor.visit(SeqVisitor::new(self.de))
|
|
||||||
} else {
|
|
||||||
Err(self.de.error(ErrorCode::ExpectedSomeValue))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
||||||
where V: de::EnumMapVisitor,
|
|
||||||
{
|
|
||||||
self.de.parse_whitespace();
|
|
||||||
|
|
||||||
if self.de.ch_is(b'{') {
|
|
||||||
self.de.bump();
|
|
||||||
visitor.visit(MapVisitor::new(self.de))
|
|
||||||
} else {
|
|
||||||
Err(self.de.error(ErrorCode::ExpectedSomeValue))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Decodes a json value from an `Iterator<u8>`.
|
|
||||||
pub fn from_iter<I, T>(iter: I) -> Result<T, Error>
|
|
||||||
where I: Iterator<Item=u8>,
|
|
||||||
T: de::Deserialize
|
|
||||||
{
|
|
||||||
let mut de = Deserializer::new(iter);
|
|
||||||
let value = try!(de::Deserialize::deserialize(&mut de));
|
|
||||||
|
|
||||||
// Make sure the whole stream has been consumed.
|
|
||||||
try!(de.end());
|
|
||||||
Ok(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Decodes a json value from a string
|
|
||||||
pub fn from_str<'a, T>(s: &'a str) -> Result<T, Error>
|
|
||||||
where T: de::Deserialize
|
|
||||||
{
|
|
||||||
from_iter(s.bytes())
|
|
||||||
}
|
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
use std::error;
|
|
||||||
use std::fmt;
|
|
||||||
use std::io;
|
|
||||||
|
|
||||||
use de;
|
|
||||||
|
|
||||||
/// The errors that can arise while parsing a JSON stream.
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
|
||||||
pub enum ErrorCode {
|
|
||||||
EOFWhileParsingList,
|
|
||||||
EOFWhileParsingObject,
|
|
||||||
EOFWhileParsingString,
|
|
||||||
EOFWhileParsingValue,
|
|
||||||
ExpectedColon,
|
|
||||||
ExpectedConversion,
|
|
||||||
ExpectedEnumEnd,
|
|
||||||
ExpectedEnumEndToken,
|
|
||||||
ExpectedEnumMapStart,
|
|
||||||
ExpectedEnumToken,
|
|
||||||
ExpectedEnumVariantString,
|
|
||||||
ExpectedListCommaOrEnd,
|
|
||||||
ExpectedName,
|
|
||||||
ExpectedObjectCommaOrEnd,
|
|
||||||
ExpectedSomeIdent,
|
|
||||||
ExpectedSomeValue,
|
|
||||||
InvalidEscape,
|
|
||||||
InvalidNumber,
|
|
||||||
InvalidUnicodeCodePoint,
|
|
||||||
KeyMustBeAString,
|
|
||||||
LoneLeadingSurrogateInHexEscape,
|
|
||||||
MissingField(&'static str),
|
|
||||||
NotFourDigit,
|
|
||||||
NotUtf8,
|
|
||||||
TrailingCharacters,
|
|
||||||
UnexpectedEndOfHexEscape,
|
|
||||||
UnknownVariant,
|
|
||||||
UnrecognizedHex,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for ErrorCode {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
use std::fmt::Debug;
|
|
||||||
|
|
||||||
match *self {
|
|
||||||
//ErrorCode::ConversionError(ref token) => write!(f, "failed to convert {}", token),
|
|
||||||
ErrorCode::EOFWhileParsingList => "EOF While parsing list".fmt(f),
|
|
||||||
ErrorCode::EOFWhileParsingObject => "EOF While parsing object".fmt(f),
|
|
||||||
ErrorCode::EOFWhileParsingString => "EOF While parsing string".fmt(f),
|
|
||||||
ErrorCode::EOFWhileParsingValue => "EOF While parsing value".fmt(f),
|
|
||||||
ErrorCode::ExpectedColon => "expected `:`".fmt(f),
|
|
||||||
ErrorCode::ExpectedConversion => "expected conversion".fmt(f),
|
|
||||||
ErrorCode::ExpectedEnumEnd => "expected enum end".fmt(f),
|
|
||||||
ErrorCode::ExpectedEnumEndToken => "expected enum map end".fmt(f),
|
|
||||||
ErrorCode::ExpectedEnumMapStart => "expected enum map start".fmt(f),
|
|
||||||
ErrorCode::ExpectedEnumToken => "expected enum token".fmt(f),
|
|
||||||
ErrorCode::ExpectedEnumVariantString => "expected variant".fmt(f),
|
|
||||||
ErrorCode::ExpectedListCommaOrEnd => "expected `,` or `]`".fmt(f),
|
|
||||||
ErrorCode::ExpectedName => "expected name".fmt(f),
|
|
||||||
ErrorCode::ExpectedObjectCommaOrEnd => "expected `,` or `}`".fmt(f),
|
|
||||||
ErrorCode::ExpectedSomeIdent => "expected ident".fmt(f),
|
|
||||||
ErrorCode::ExpectedSomeValue => "expected value".fmt(f),
|
|
||||||
//ErrorCode::ExpectedTokens(ref token, tokens) => write!(f, "expected {}, found {}", tokens, token),
|
|
||||||
ErrorCode::InvalidEscape => "invalid escape".fmt(f),
|
|
||||||
ErrorCode::InvalidNumber => "invalid number".fmt(f),
|
|
||||||
ErrorCode::InvalidUnicodeCodePoint => "invalid unicode code point".fmt(f),
|
|
||||||
ErrorCode::KeyMustBeAString => "key must be a string".fmt(f),
|
|
||||||
ErrorCode::LoneLeadingSurrogateInHexEscape => "lone leading surrogate in hex escape".fmt(f),
|
|
||||||
ErrorCode::MissingField(ref field) => write!(f, "missing field \"{}\"", field),
|
|
||||||
ErrorCode::NotFourDigit => "invalid \\u escape (not four digits)".fmt(f),
|
|
||||||
ErrorCode::NotUtf8 => "contents not utf-8".fmt(f),
|
|
||||||
ErrorCode::TrailingCharacters => "trailing characters".fmt(f),
|
|
||||||
ErrorCode::UnexpectedEndOfHexEscape => "unexpected end of hex escape".fmt(f),
|
|
||||||
//ErrorCode::UnexpectedName(ref name) => write!(f, "unexpected name {}", name),
|
|
||||||
ErrorCode::UnknownVariant => "unknown variant".fmt(f),
|
|
||||||
ErrorCode::UnrecognizedHex => "invalid \\u escape (unrecognized hex)".fmt(f),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
|
||||||
pub enum Error {
|
|
||||||
/// msg, line, col
|
|
||||||
SyntaxError(ErrorCode, usize, usize),
|
|
||||||
IoError(io::Error),
|
|
||||||
/*
|
|
||||||
ExpectedError(String, String),
|
|
||||||
*/
|
|
||||||
MissingFieldError(&'static str),
|
|
||||||
/*
|
|
||||||
UnknownVariantError(String),
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
impl error::Error for Error {
|
|
||||||
fn description(&self) -> &str {
|
|
||||||
match *self {
|
|
||||||
Error::SyntaxError(..) => "syntax error",
|
|
||||||
Error::IoError(ref error) => error.description(),
|
|
||||||
/*
|
|
||||||
Error::ExpectedError(ref expected, _) => &expected,
|
|
||||||
*/
|
|
||||||
Error::MissingFieldError(_) => "missing field",
|
|
||||||
/*
|
|
||||||
Error::UnknownVariantError(_) => "unknown variant",
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cause(&self) -> Option<&error::Error> {
|
|
||||||
match *self {
|
|
||||||
Error::IoError(ref error) => Some(error),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match *self {
|
|
||||||
Error::SyntaxError(ref code, line, col) => {
|
|
||||||
write!(fmt, "{:?} at line {} column {}", code, line, col)
|
|
||||||
}
|
|
||||||
Error::IoError(ref error) => fmt::Display::fmt(error, fmt),
|
|
||||||
/*
|
|
||||||
Error::ExpectedError(ref expected, ref found) => {
|
|
||||||
Some(format!("expected {}, found {}", expected, found))
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
Error::MissingFieldError(ref field) => {
|
|
||||||
write!(fmt, "missing field {}", field)
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
Error::UnknownVariantError(ref variant) => {
|
|
||||||
Some(format!("unknown variant {}", variant))
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl error::FromError<io::Error> for Error {
|
|
||||||
fn from_error(error: io::Error) -> Error {
|
|
||||||
Error::IoError(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl de::Error for Error {
|
|
||||||
fn syntax_error() -> Error {
|
|
||||||
Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end_of_stream_error() -> Error {
|
|
||||||
Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 0, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn missing_field_error(field: &'static str) -> Error {
|
|
||||||
Error::MissingFieldError(field)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
pub use self::de::{Deserializer, from_str};
|
|
||||||
pub use self::error::{Error, ErrorCode};
|
|
||||||
pub use self::ser::{
|
|
||||||
Serializer,
|
|
||||||
to_writer,
|
|
||||||
to_writer_pretty,
|
|
||||||
to_vec,
|
|
||||||
to_vec_pretty,
|
|
||||||
to_string,
|
|
||||||
to_string_pretty,
|
|
||||||
escape_str,
|
|
||||||
};
|
|
||||||
pub use self::value::{Value, to_value, from_value};
|
|
||||||
|
|
||||||
pub mod builder;
|
|
||||||
pub mod de;
|
|
||||||
pub mod error;
|
|
||||||
pub mod ser;
|
|
||||||
pub mod value;
|
|
||||||
@@ -1,457 +0,0 @@
|
|||||||
use std::{f32, f64};
|
|
||||||
use std::io;
|
|
||||||
use std::num::{Float, FpCategory};
|
|
||||||
use std::string::FromUtf8Error;
|
|
||||||
|
|
||||||
use ser;
|
|
||||||
|
|
||||||
/// A structure for implementing serialization to JSON.
|
|
||||||
pub struct Serializer<W> {
|
|
||||||
writer: W,
|
|
||||||
format: Format,
|
|
||||||
current_indent: usize,
|
|
||||||
indent: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, PartialEq)]
|
|
||||||
enum Format {
|
|
||||||
Compact,
|
|
||||||
Pretty,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<W: io::Write> Serializer<W> {
|
|
||||||
/// Creates a new JSON visitr whose output will be written to the writer
|
|
||||||
/// specified.
|
|
||||||
#[inline]
|
|
||||||
pub fn new(writer: W) -> Serializer<W> {
|
|
||||||
Serializer {
|
|
||||||
writer: writer,
|
|
||||||
format: Format::Compact,
|
|
||||||
current_indent: 0,
|
|
||||||
indent: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new JSON visitr whose output will be written to the writer
|
|
||||||
/// specified.
|
|
||||||
#[inline]
|
|
||||||
pub fn new_pretty(writer: W) -> Serializer<W> {
|
|
||||||
Serializer {
|
|
||||||
writer: writer,
|
|
||||||
format: Format::Pretty,
|
|
||||||
current_indent: 0,
|
|
||||||
indent: 2,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Unwrap the `Writer` from the `Serializer`.
|
|
||||||
#[inline]
|
|
||||||
pub fn into_inner(self) -> W {
|
|
||||||
self.writer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<W: io::Write> ser::Serializer for Serializer<W> {
|
|
||||||
type Value = ();
|
|
||||||
type Error = io::Error;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit<T>(&mut self, value: &T) -> io::Result<()>
|
|
||||||
where T: ser::Serialize,
|
|
||||||
{
|
|
||||||
value.visit(&mut Visitor {
|
|
||||||
writer: &mut self.writer,
|
|
||||||
format: self.format,
|
|
||||||
current_indent: self.current_indent,
|
|
||||||
indent: self.indent,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Visitor<'a, W: 'a> {
|
|
||||||
writer: &'a mut W,
|
|
||||||
format: Format,
|
|
||||||
current_indent: usize,
|
|
||||||
indent: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, W> Visitor<'a, W> where W: io::Write, {
|
|
||||||
fn serialize_sep(&mut self, first: bool) -> io::Result<()> {
|
|
||||||
match self.format {
|
|
||||||
Format::Compact => {
|
|
||||||
if first {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
self.writer.write_all(b",")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Format::Pretty => {
|
|
||||||
if first {
|
|
||||||
self.current_indent += self.indent;
|
|
||||||
try!(self.writer.write_all(b"\n"));
|
|
||||||
} else {
|
|
||||||
try!(self.writer.write_all(b",\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
spaces(&mut self.writer, self.current_indent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_colon(&mut self) -> io::Result<()> {
|
|
||||||
match self.format {
|
|
||||||
Format::Compact => self.writer.write_all(b":"),
|
|
||||||
Format::Pretty => self.writer.write_all(b": "),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_end(&mut self, current_indent: usize, s: &[u8]) -> io::Result<()> {
|
|
||||||
if self.format == Format::Pretty && current_indent != self.current_indent {
|
|
||||||
self.current_indent -= self.indent;
|
|
||||||
try!(self.writer.write(b"\n"));
|
|
||||||
try!(spaces(&mut self.writer, self.current_indent));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.writer.write_all(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, W> ser::Visitor for Visitor<'a, W> where W: io::Write, {
|
|
||||||
type Value = ();
|
|
||||||
type Error = io::Error;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_bool(&mut self, value: bool) -> io::Result<()> {
|
|
||||||
if value {
|
|
||||||
self.writer.write_all(b"true")
|
|
||||||
} else {
|
|
||||||
self.writer.write_all(b"false")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_isize(&mut self, value: isize) -> io::Result<()> {
|
|
||||||
write!(self.writer, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_i8(&mut self, value: i8) -> io::Result<()> {
|
|
||||||
write!(self.writer, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_i16(&mut self, value: i16) -> io::Result<()> {
|
|
||||||
write!(self.writer, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_i32(&mut self, value: i32) -> io::Result<()> {
|
|
||||||
write!(self.writer, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_i64(&mut self, value: i64) -> io::Result<()> {
|
|
||||||
write!(self.writer, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_usize(&mut self, value: usize) -> io::Result<()> {
|
|
||||||
write!(self.writer, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_u8(&mut self, value: u8) -> io::Result<()> {
|
|
||||||
write!(self.writer, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_u16(&mut self, value: u16) -> io::Result<()> {
|
|
||||||
write!(self.writer, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_u32(&mut self, value: u32) -> io::Result<()> {
|
|
||||||
write!(self.writer, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_u64(&mut self, value: u64) -> io::Result<()> {
|
|
||||||
write!(self.writer, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_f32(&mut self, value: f32) -> io::Result<()> {
|
|
||||||
fmt_f32_or_null(self.writer, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_f64(&mut self, value: f64) -> io::Result<()> {
|
|
||||||
fmt_f64_or_null(self.writer, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_char(&mut self, value: char) -> io::Result<()> {
|
|
||||||
escape_char(self.writer, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_str(&mut self, value: &str) -> io::Result<()> {
|
|
||||||
escape_str(self.writer, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_none(&mut self) -> io::Result<()> {
|
|
||||||
self.visit_unit()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_some<V>(&mut self, value: V) -> io::Result<()>
|
|
||||||
where V: ser::Serialize
|
|
||||||
{
|
|
||||||
value.visit(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_unit(&mut self) -> io::Result<()> {
|
|
||||||
self.writer.write_all(b"null")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_enum_unit(&mut self, _name: &str, variant: &str) -> io::Result<()> {
|
|
||||||
let current_indent = self.current_indent;
|
|
||||||
|
|
||||||
try!(self.writer.write_all(b"{"));
|
|
||||||
try!(self.serialize_sep(true));
|
|
||||||
try!(self.visit_str(variant));
|
|
||||||
try!(self.serialize_colon());
|
|
||||||
try!(self.writer.write_all(b"[]"));
|
|
||||||
self.serialize_end(current_indent, b"}")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_seq<V>(&mut self, mut visitor: V) -> io::Result<()>
|
|
||||||
where V: ser::SeqVisitor,
|
|
||||||
{
|
|
||||||
let current_indent = self.current_indent;
|
|
||||||
|
|
||||||
try!(self.writer.write_all(b"["));
|
|
||||||
|
|
||||||
while let Some(()) = try!(visitor.visit(self)) { }
|
|
||||||
|
|
||||||
self.serialize_end(current_indent, b"]")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_enum_seq<V>(&mut self, _name: &str, variant: &str, visitor: V) -> io::Result<()>
|
|
||||||
where V: ser::SeqVisitor,
|
|
||||||
{
|
|
||||||
let current_indent = self.current_indent;
|
|
||||||
|
|
||||||
try!(self.writer.write_all(b"{"));
|
|
||||||
try!(self.serialize_sep(true));
|
|
||||||
try!(self.visit_str(variant));
|
|
||||||
try!(self.serialize_colon());
|
|
||||||
try!(self.visit_seq(visitor));
|
|
||||||
self.serialize_end(current_indent, b"}")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_seq_elt<T>(&mut self, first: bool, value: T) -> io::Result<()>
|
|
||||||
where T: ser::Serialize,
|
|
||||||
{
|
|
||||||
try!(self.serialize_sep(first));
|
|
||||||
|
|
||||||
value.visit(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_map<V>(&mut self, mut visitor: V) -> io::Result<()>
|
|
||||||
where V: ser::MapVisitor,
|
|
||||||
{
|
|
||||||
let current_indent = self.current_indent;
|
|
||||||
|
|
||||||
try!(self.writer.write_all(b"{"));
|
|
||||||
|
|
||||||
while let Some(()) = try!(visitor.visit(self)) { }
|
|
||||||
|
|
||||||
self.serialize_end(current_indent, b"}")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_enum_map<V>(&mut self, _name: &str, variant: &str, visitor: V) -> io::Result<()>
|
|
||||||
where V: ser::MapVisitor,
|
|
||||||
{
|
|
||||||
let current_indent = self.current_indent;
|
|
||||||
|
|
||||||
try!(self.writer.write_all(b"{"));
|
|
||||||
try!(self.serialize_sep(true));
|
|
||||||
try!(self.visit_str(variant));
|
|
||||||
try!(self.serialize_colon());
|
|
||||||
try!(self.visit_map(visitor));
|
|
||||||
self.serialize_end(current_indent, b"}")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_map_elt<K, V>(&mut self, first: bool, key: K, value: V) -> io::Result<()>
|
|
||||||
where K: ser::Serialize,
|
|
||||||
V: ser::Serialize,
|
|
||||||
{
|
|
||||||
try!(self.serialize_sep(first));
|
|
||||||
try!(key.visit(self));
|
|
||||||
try!(self.serialize_colon());
|
|
||||||
value.visit(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn escape_bytes<W>(wr: &mut W, bytes: &[u8]) -> io::Result<()>
|
|
||||||
where W: io::Write
|
|
||||||
{
|
|
||||||
try!(wr.write_all(b"\""));
|
|
||||||
|
|
||||||
let mut start = 0;
|
|
||||||
|
|
||||||
for (i, byte) in bytes.iter().enumerate() {
|
|
||||||
let escaped = match *byte {
|
|
||||||
b'"' => b"\\\"",
|
|
||||||
b'\\' => b"\\\\",
|
|
||||||
b'\x08' => b"\\b",
|
|
||||||
b'\x0c' => b"\\f",
|
|
||||||
b'\n' => b"\\n",
|
|
||||||
b'\r' => b"\\r",
|
|
||||||
b'\t' => b"\\t",
|
|
||||||
_ => { continue; }
|
|
||||||
};
|
|
||||||
|
|
||||||
if start < i {
|
|
||||||
try!(wr.write_all(&bytes[start..i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
try!(wr.write_all(escaped));
|
|
||||||
|
|
||||||
start = i + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if start != bytes.len() {
|
|
||||||
try!(wr.write_all(&bytes[start..]));
|
|
||||||
}
|
|
||||||
|
|
||||||
try!(wr.write_all(b"\""));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn escape_str<W>(wr: &mut W, value: &str) -> io::Result<()>
|
|
||||||
where W: io::Write
|
|
||||||
{
|
|
||||||
escape_bytes(wr, value.as_bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn escape_char<W>(wr: &mut W, value: char) -> io::Result<()>
|
|
||||||
where W: io::Write
|
|
||||||
{
|
|
||||||
let buf = &mut [0; 4];
|
|
||||||
value.encode_utf8(buf);
|
|
||||||
escape_bytes(wr, buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fmt_f32_or_null<W>(wr: &mut W, value: f32) -> io::Result<()>
|
|
||||||
where W: io::Write
|
|
||||||
{
|
|
||||||
match value.classify() {
|
|
||||||
FpCategory::Nan | FpCategory::Infinite => wr.write_all(b"null"),
|
|
||||||
_ => wr.write_all(f32::to_str_digits(value, 6).as_bytes()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fmt_f64_or_null<W>(wr: &mut W, value: f64) -> io::Result<()>
|
|
||||||
where W: io::Write
|
|
||||||
{
|
|
||||||
match value.classify() {
|
|
||||||
FpCategory::Nan | FpCategory::Infinite => wr.write_all(b"null"),
|
|
||||||
_ => wr.write_all(f64::to_str_digits(value, 6).as_bytes()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Encode the specified struct into a json `[u8]` writer.
|
|
||||||
#[inline]
|
|
||||||
pub fn to_writer<W, T>(writer: &mut W, value: &T) -> io::Result<()>
|
|
||||||
where W: io::Write,
|
|
||||||
T: ser::Serialize,
|
|
||||||
{
|
|
||||||
let mut ser = Serializer::new(writer);
|
|
||||||
try!(ser::Serializer::visit(&mut ser, value));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Encode the specified struct into a json `[u8]` writer.
|
|
||||||
#[inline]
|
|
||||||
pub fn to_writer_pretty<W, T>(writer: &mut W, value: &T) -> io::Result<()>
|
|
||||||
where W: io::Write,
|
|
||||||
T: ser::Serialize,
|
|
||||||
{
|
|
||||||
let mut ser = Serializer::new_pretty(writer);
|
|
||||||
try!(ser::Serializer::visit(&mut ser, value));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Encode the specified struct into a json `[u8]` buffer.
|
|
||||||
#[inline]
|
|
||||||
pub fn to_vec<T>(value: &T) -> Vec<u8>
|
|
||||||
where T: ser::Serialize,
|
|
||||||
{
|
|
||||||
// We are writing to a Vec, which doesn't fail. So we can ignore
|
|
||||||
// the error.
|
|
||||||
let mut writer = Vec::with_capacity(128);
|
|
||||||
to_writer(&mut writer, value).unwrap();
|
|
||||||
writer
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Encode the specified struct into a json `[u8]` buffer.
|
|
||||||
#[inline]
|
|
||||||
pub fn to_vec_pretty<T>(value: &T) -> Vec<u8>
|
|
||||||
where T: ser::Serialize,
|
|
||||||
{
|
|
||||||
// We are writing to a Vec, which doesn't fail. So we can ignore
|
|
||||||
// the error.
|
|
||||||
let mut writer = Vec::with_capacity(128);
|
|
||||||
to_writer_pretty(&mut writer, value).unwrap();
|
|
||||||
writer
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Encode the specified struct into a json `String` buffer.
|
|
||||||
#[inline]
|
|
||||||
pub fn to_string<T>(value: &T) -> Result<String, FromUtf8Error>
|
|
||||||
where T: ser::Serialize
|
|
||||||
{
|
|
||||||
let vec = to_vec(value);
|
|
||||||
String::from_utf8(vec)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Encode the specified struct into a json `String` buffer.
|
|
||||||
#[inline]
|
|
||||||
pub fn to_string_pretty<T>(value: &T) -> Result<String, FromUtf8Error>
|
|
||||||
where T: ser::Serialize
|
|
||||||
{
|
|
||||||
let vec = to_vec_pretty(value);
|
|
||||||
String::from_utf8(vec)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn spaces<W>(wr: &mut W, mut n: usize) -> io::Result<()>
|
|
||||||
where W: io::Write,
|
|
||||||
{
|
|
||||||
const LEN: usize = 16;
|
|
||||||
const BUF: &'static [u8; LEN] = &[b' '; 16];
|
|
||||||
|
|
||||||
while n >= LEN {
|
|
||||||
try!(wr.write_all(BUF));
|
|
||||||
n -= LEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if n > 0 {
|
|
||||||
wr.write_all(&BUF[..n])
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,604 +0,0 @@
|
|||||||
use std::collections::{BTreeMap, btree_map};
|
|
||||||
use std::fmt;
|
|
||||||
use std::io;
|
|
||||||
use std::str;
|
|
||||||
use std::vec;
|
|
||||||
|
|
||||||
use de;
|
|
||||||
use ser;
|
|
||||||
use super::error::Error;
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
|
||||||
pub enum Value {
|
|
||||||
Null,
|
|
||||||
Bool(bool),
|
|
||||||
I64(i64),
|
|
||||||
F64(f64),
|
|
||||||
String(String),
|
|
||||||
Array(Vec<Value>),
|
|
||||||
Object(BTreeMap<String, Value>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ser::Serialize for Value {
|
|
||||||
#[inline]
|
|
||||||
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
|
||||||
where V: ser::Visitor,
|
|
||||||
{
|
|
||||||
match *self {
|
|
||||||
Value::Null => visitor.visit_unit(),
|
|
||||||
Value::Bool(v) => visitor.visit_bool(v),
|
|
||||||
Value::I64(v) => visitor.visit_i64(v),
|
|
||||||
Value::F64(v) => visitor.visit_f64(v),
|
|
||||||
Value::String(ref v) => visitor.visit_str(&v),
|
|
||||||
Value::Array(ref v) => v.visit(visitor),
|
|
||||||
Value::Object(ref v) => v.visit(visitor),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl de::Deserialize for Value {
|
|
||||||
#[inline]
|
|
||||||
fn deserialize<D>(deserializer: &mut D) -> Result<Value, D::Error>
|
|
||||||
where D: de::Deserializer,
|
|
||||||
{
|
|
||||||
struct ValueVisitor;
|
|
||||||
|
|
||||||
impl de::Visitor for ValueVisitor {
|
|
||||||
type Value = Value;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_bool<E>(&mut self, value: bool) -> Result<Value, E> {
|
|
||||||
Ok(Value::Bool(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_i64<E>(&mut self, value: i64) -> Result<Value, E> {
|
|
||||||
Ok(Value::I64(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_f64<E>(&mut self, value: f64) -> Result<Value, E> {
|
|
||||||
Ok(Value::F64(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_str<E>(&mut self, value: &str) -> Result<Value, E>
|
|
||||||
where E: de::Error,
|
|
||||||
{
|
|
||||||
self.visit_string(value.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_string<E>(&mut self, value: String) -> Result<Value, E> {
|
|
||||||
Ok(Value::String(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_none<E>(&mut self) -> Result<Value, E> {
|
|
||||||
Ok(Value::Null)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_some<D>(&mut self, deserializer: &mut D) -> Result<Value, D::Error>
|
|
||||||
where D: de::Deserializer,
|
|
||||||
{
|
|
||||||
de::Deserialize::deserialize(deserializer)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_unit<E>(&mut self) -> Result<Value, E> {
|
|
||||||
Ok(Value::Null)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_seq<V>(&mut self, visitor: V) -> Result<Value, V::Error>
|
|
||||||
where V: de::SeqVisitor,
|
|
||||||
{
|
|
||||||
let values = try!(de::VecVisitor::new().visit_seq(visitor));
|
|
||||||
Ok(Value::Array(values))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_map<V>(&mut self, visitor: V) -> Result<Value, V::Error>
|
|
||||||
where V: de::MapVisitor,
|
|
||||||
{
|
|
||||||
let values = try!(de::BTreeMapVisitor::new().visit_map(visitor));
|
|
||||||
Ok(Value::Object(values))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deserializer.visit(ValueVisitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct WriterFormatter<'a, 'b: 'a> {
|
|
||||||
inner: &'a mut fmt::Formatter<'b>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'b> io::Write for WriterFormatter<'a, 'b> {
|
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
|
||||||
match self.inner.write_str(str::from_utf8(buf).unwrap()) {
|
|
||||||
Ok(_) => Ok(buf.len()),
|
|
||||||
Err(_) => Err(io::Error::last_os_error()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flush(&mut self) -> io::Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for Value {
|
|
||||||
/// Serializes a json value into a string
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
let mut wr = WriterFormatter { inner: f };
|
|
||||||
super::ser::to_writer(&mut wr, self).map_err(|_| fmt::Error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
enum State {
|
|
||||||
Value(Value),
|
|
||||||
Array(Vec<Value>),
|
|
||||||
Object(BTreeMap<String, Value>),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Serializer {
|
|
||||||
state: Vec<State>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Serializer {
|
|
||||||
pub fn new() -> Serializer {
|
|
||||||
Serializer {
|
|
||||||
state: Vec::with_capacity(4),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unwrap(mut self) -> Value {
|
|
||||||
match self.state.pop().unwrap() {
|
|
||||||
State::Value(value) => value,
|
|
||||||
state => panic!("expected value, found {:?}", state),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ser::Serializer for Serializer {
|
|
||||||
type Value = ();
|
|
||||||
type Error = ();
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit<T>(&mut self, value: &T) -> Result<(), ()>
|
|
||||||
where T: ser::Serialize,
|
|
||||||
{
|
|
||||||
try!(value.visit(self));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ser::Visitor for Serializer {
|
|
||||||
type Value = ();
|
|
||||||
type Error = ();
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_bool(&mut self, value: bool) -> Result<(), ()> {
|
|
||||||
self.state.push(State::Value(Value::Bool(value)));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_i64(&mut self, value: i64) -> Result<(), ()> {
|
|
||||||
self.state.push(State::Value(Value::I64(value)));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_u64(&mut self, value: u64) -> Result<(), ()> {
|
|
||||||
self.state.push(State::Value(Value::I64(value as i64)));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_f64(&mut self, value: f64) -> Result<(), ()> {
|
|
||||||
self.state.push(State::Value(Value::F64(value as f64)));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_char(&mut self, value: char) -> Result<(), ()> {
|
|
||||||
self.state.push(State::Value(Value::String(value.to_string())));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_str(&mut self, value: &str) -> Result<(), ()> {
|
|
||||||
self.state.push(State::Value(Value::String(value.to_string())));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_none(&mut self) -> Result<(), ()> {
|
|
||||||
self.visit_unit()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_some<V>(&mut self, value: V) -> Result<(), ()>
|
|
||||||
where V: ser::Serialize,
|
|
||||||
{
|
|
||||||
value.visit(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_unit(&mut self) -> Result<(), ()> {
|
|
||||||
self.state.push(State::Value(Value::Null));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_enum_unit(&mut self, _name: &str, variant: &str) -> Result<(), ()> {
|
|
||||||
let mut values = BTreeMap::new();
|
|
||||||
values.insert(variant.to_string(), Value::Array(vec![]));
|
|
||||||
|
|
||||||
self.state.push(State::Value(Value::Object(values)));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<(), ()>
|
|
||||||
where V: ser::SeqVisitor,
|
|
||||||
{
|
|
||||||
let len = match visitor.size_hint() {
|
|
||||||
(_, Some(len)) => len,
|
|
||||||
(len, None) => len,
|
|
||||||
};
|
|
||||||
|
|
||||||
let values = Vec::with_capacity(len);
|
|
||||||
|
|
||||||
self.state.push(State::Array(values));
|
|
||||||
|
|
||||||
while let Some(()) = try!(visitor.visit(self)) { }
|
|
||||||
|
|
||||||
let values = match self.state.pop().unwrap() {
|
|
||||||
State::Array(values) => values,
|
|
||||||
state => panic!("Expected array, found {:?}", state),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.state.push(State::Value(Value::Array(values)));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_enum_seq<V>(&mut self, _name: &str, variant: &str, visitor: V) -> Result<(), ()>
|
|
||||||
where V: ser::SeqVisitor,
|
|
||||||
{
|
|
||||||
try!(self.visit_seq(visitor));
|
|
||||||
|
|
||||||
let value = match self.state.pop().unwrap() {
|
|
||||||
State::Value(value) => value,
|
|
||||||
state => panic!("expected value, found {:?}", state),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut object = BTreeMap::new();
|
|
||||||
|
|
||||||
object.insert(variant.to_string(), value);
|
|
||||||
|
|
||||||
self.state.push(State::Value(Value::Object(object)));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_seq_elt<T>(&mut self, _first: bool, value: T) -> Result<(), ()>
|
|
||||||
where T: ser::Serialize,
|
|
||||||
{
|
|
||||||
try!(value.visit(self));
|
|
||||||
|
|
||||||
let value = match self.state.pop().unwrap() {
|
|
||||||
State::Value(value) => value,
|
|
||||||
state => panic!("expected value, found {:?}", state),
|
|
||||||
};
|
|
||||||
|
|
||||||
match *self.state.last_mut().unwrap() {
|
|
||||||
State::Array(ref mut values) => { values.push(value); }
|
|
||||||
ref state => panic!("expected array, found {:?}", state),
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_map<V>(&mut self, mut visitor: V) -> Result<(), ()>
|
|
||||||
where V: ser::MapVisitor,
|
|
||||||
{
|
|
||||||
let values = BTreeMap::new();
|
|
||||||
|
|
||||||
self.state.push(State::Object(values));
|
|
||||||
|
|
||||||
while let Some(()) = try!(visitor.visit(self)) { }
|
|
||||||
|
|
||||||
let values = match self.state.pop().unwrap() {
|
|
||||||
State::Object(values) => values,
|
|
||||||
state => panic!("expected object, found {:?}", state),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.state.push(State::Value(Value::Object(values)));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_enum_map<V>(&mut self, _name: &str, variant: &str, visitor: V) -> Result<(), ()>
|
|
||||||
where V: ser::MapVisitor,
|
|
||||||
{
|
|
||||||
try!(self.visit_map(visitor));
|
|
||||||
|
|
||||||
let value = match self.state.pop().unwrap() {
|
|
||||||
State::Value(value) => value,
|
|
||||||
state => panic!("expected value, found {:?}", state),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut object = BTreeMap::new();
|
|
||||||
|
|
||||||
object.insert(variant.to_string(), value);
|
|
||||||
|
|
||||||
self.state.push(State::Value(Value::Object(object)));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_map_elt<K, V>(&mut self, _first: bool, key: K, value: V) -> Result<(), ()>
|
|
||||||
where K: ser::Serialize,
|
|
||||||
V: ser::Serialize,
|
|
||||||
{
|
|
||||||
try!(key.visit(self));
|
|
||||||
|
|
||||||
let key = match self.state.pop().unwrap() {
|
|
||||||
State::Value(Value::String(value)) => value,
|
|
||||||
state => panic!("expected key, found {:?}", state),
|
|
||||||
};
|
|
||||||
|
|
||||||
try!(value.visit(self));
|
|
||||||
|
|
||||||
let value = match self.state.pop().unwrap() {
|
|
||||||
State::Value(value) => value,
|
|
||||||
state => panic!("expected value, found {:?}", state),
|
|
||||||
};
|
|
||||||
|
|
||||||
match *self.state.last_mut().unwrap() {
|
|
||||||
State::Object(ref mut values) => { values.insert(key, value); }
|
|
||||||
ref state => panic!("expected object, found {:?}", state),
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Deserializer {
|
|
||||||
value: Option<Value>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deserializer {
|
|
||||||
/// Creates a new deserializer instance for deserializing the specified JSON value.
|
|
||||||
pub fn new(value: Value) -> Deserializer {
|
|
||||||
Deserializer {
|
|
||||||
value: Some(value),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl de::Deserializer for Deserializer {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
||||||
where V: de::Visitor,
|
|
||||||
{
|
|
||||||
let value = match self.value.take() {
|
|
||||||
Some(value) => value,
|
|
||||||
None => { return Err(de::Error::end_of_stream_error()); }
|
|
||||||
};
|
|
||||||
|
|
||||||
match value {
|
|
||||||
Value::Null => visitor.visit_unit(),
|
|
||||||
Value::Bool(v) => visitor.visit_bool(v),
|
|
||||||
Value::I64(v) => visitor.visit_i64(v),
|
|
||||||
Value::F64(v) => visitor.visit_f64(v),
|
|
||||||
Value::String(v) => visitor.visit_string(v),
|
|
||||||
Value::Array(v) => {
|
|
||||||
let len = v.len();
|
|
||||||
visitor.visit_seq(SeqDeserializer {
|
|
||||||
de: self,
|
|
||||||
iter: v.into_iter(),
|
|
||||||
len: len,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Value::Object(v) => {
|
|
||||||
let len = v.len();
|
|
||||||
visitor.visit_map(MapDeserializer {
|
|
||||||
de: self,
|
|
||||||
iter: v.into_iter(),
|
|
||||||
value: None,
|
|
||||||
len: len,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
||||||
where V: de::Visitor,
|
|
||||||
{
|
|
||||||
match self.value {
|
|
||||||
Some(Value::Null) => visitor.visit_none(),
|
|
||||||
Some(_) => visitor.visit_some(self),
|
|
||||||
None => Err(de::Error::end_of_stream_error()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_enum<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
||||||
where V: de::Visitor,
|
|
||||||
{
|
|
||||||
let value = match self.value.take() {
|
|
||||||
Some(Value::Object(value)) => value,
|
|
||||||
Some(_) => { return Err(de::Error::syntax_error()); }
|
|
||||||
None => { return Err(de::Error::end_of_stream_error()); }
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut iter = value.into_iter();
|
|
||||||
|
|
||||||
let value = match iter.next() {
|
|
||||||
Some((variant, Value::Array(fields))) => {
|
|
||||||
let len = fields.len();
|
|
||||||
try!(visitor.visit_variant(&variant, SeqDeserializer {
|
|
||||||
de: self,
|
|
||||||
iter: fields.into_iter(),
|
|
||||||
len: len,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
Some((variant, Value::Object(fields))) => {
|
|
||||||
let len = fields.len();
|
|
||||||
try!(visitor.visit_variant(&variant, MapDeserializer {
|
|
||||||
de: self,
|
|
||||||
iter: fields.into_iter(),
|
|
||||||
value: None,
|
|
||||||
len: len,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
Some(_) => { return Err(de::Error::syntax_error()); }
|
|
||||||
None => { return Err(de::Error::syntax_error()); }
|
|
||||||
};
|
|
||||||
|
|
||||||
match iter.next() {
|
|
||||||
Some(_) => Err(de::Error::syntax_error()),
|
|
||||||
None => Ok(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SeqDeserializer<'a> {
|
|
||||||
de: &'a mut Deserializer,
|
|
||||||
iter: vec::IntoIter<Value>,
|
|
||||||
len: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> de::SeqVisitor for SeqDeserializer<'a> {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
|
||||||
where T: de::Deserialize
|
|
||||||
{
|
|
||||||
match self.iter.next() {
|
|
||||||
Some(value) => {
|
|
||||||
self.len -= 1;
|
|
||||||
self.de.value = Some(value);
|
|
||||||
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
|
|
||||||
}
|
|
||||||
None => Ok(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end(&mut self) -> Result<(), Error> {
|
|
||||||
if self.len == 0 {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(de::Error::end_of_stream_error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
(self.len, Some(self.len))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> de::EnumVisitor for SeqDeserializer<'a> {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn visit_unit(&mut self) -> Result<(), Error> {
|
|
||||||
if self.len == 0 {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(de::Error::syntax_error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
||||||
where V: de::EnumSeqVisitor,
|
|
||||||
{
|
|
||||||
visitor.visit(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MapDeserializer<'a> {
|
|
||||||
de: &'a mut Deserializer,
|
|
||||||
iter: btree_map::IntoIter<String, Value>,
|
|
||||||
value: Option<Value>,
|
|
||||||
len: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> de::MapVisitor for MapDeserializer<'a> {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn visit_key<T>(&mut self) -> Result<Option<T>, Error>
|
|
||||||
where T: de::Deserialize
|
|
||||||
{
|
|
||||||
match self.iter.next() {
|
|
||||||
Some((key, value)) => {
|
|
||||||
self.len -= 1;
|
|
||||||
self.value = Some(value);
|
|
||||||
self.de.value = Some(Value::String(key));
|
|
||||||
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
|
|
||||||
}
|
|
||||||
None => Ok(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_value<T>(&mut self) -> Result<T, Error>
|
|
||||||
where T: de::Deserialize
|
|
||||||
{
|
|
||||||
let value = self.value.take().unwrap();
|
|
||||||
self.de.value = Some(value);
|
|
||||||
Ok(try!(de::Deserialize::deserialize(self.de)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end(&mut self) -> Result<(), Error> {
|
|
||||||
if self.len == 0 {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(de::Error::end_of_stream_error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
(self.len, Some(self.len))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> de::EnumVisitor for MapDeserializer<'a> {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn visit_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
||||||
where V: de::EnumMapVisitor,
|
|
||||||
{
|
|
||||||
visitor.visit(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Shortcut function to encode a `T` into a JSON `Value`
|
|
||||||
pub fn to_value<T>(value: &T) -> Value
|
|
||||||
where T: ser::Serialize
|
|
||||||
{
|
|
||||||
let mut ser = Serializer::new();
|
|
||||||
ser::Serializer::visit(&mut ser, value).ok().unwrap();
|
|
||||||
ser.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Shortcut function to decode a JSON `Value` into a `T`
|
|
||||||
pub fn from_value<T>(value: Value) -> Result<T, Error>
|
|
||||||
where T: de::Deserialize
|
|
||||||
{
|
|
||||||
let mut de = Deserializer::new(value);
|
|
||||||
de::Deserialize::deserialize(&mut de)
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
#![feature(core, io, path, std_misc, unicode)]
|
|
||||||
|
|
||||||
extern crate unicode;
|
|
||||||
|
|
||||||
pub use ser::{Serialize, Serializer};
|
|
||||||
pub use de::{Deserialize, Deserializer, Error};
|
|
||||||
|
|
||||||
pub mod ser;
|
|
||||||
pub mod de;
|
|
||||||
pub mod json;
|
|
||||||
@@ -1,660 +0,0 @@
|
|||||||
use std::collections::hash_state::HashState;
|
|
||||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
|
||||||
use std::hash::Hash;
|
|
||||||
use std::path;
|
|
||||||
use std::rc::Rc;
|
|
||||||
use std::str;
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
pub trait Serialize {
|
|
||||||
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
|
||||||
where V: Visitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
pub trait Serializer {
|
|
||||||
type Value;
|
|
||||||
type Error;
|
|
||||||
|
|
||||||
fn visit<T>(&mut self, value: &T) -> Result<Self::Value, Self::Error>
|
|
||||||
where T: Serialize;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
pub trait Visitor {
|
|
||||||
type Value;
|
|
||||||
type Error;
|
|
||||||
|
|
||||||
fn visit_bool(&mut self, v: bool) -> Result<Self::Value, Self::Error>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_isize(&mut self, v: isize) -> Result<Self::Value, Self::Error> {
|
|
||||||
self.visit_i64(v as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_i8(&mut self, v: i8) -> Result<Self::Value, Self::Error> {
|
|
||||||
self.visit_i64(v as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_i16(&mut self, v: i16) -> Result<Self::Value, Self::Error> {
|
|
||||||
self.visit_i64(v as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_i32(&mut self, v: i32) -> Result<Self::Value, Self::Error> {
|
|
||||||
self.visit_i64(v as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_i64(&mut self, v: i64) -> Result<Self::Value, Self::Error>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_usize(&mut self, v: usize) -> Result<Self::Value, Self::Error> {
|
|
||||||
self.visit_u64(v as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_u8(&mut self, v: u8) -> Result<Self::Value, Self::Error> {
|
|
||||||
self.visit_u64(v as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_u16(&mut self, v: u16) -> Result<Self::Value, Self::Error> {
|
|
||||||
self.visit_u64(v as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_u32(&mut self, v: u32) -> Result<Self::Value, Self::Error> {
|
|
||||||
self.visit_u64(v as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_u64(&mut self, v: u64) -> Result<Self::Value, Self::Error>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_f32(&mut self, v: f32) -> Result<Self::Value, Self::Error> {
|
|
||||||
self.visit_f64(v as f64)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_f64(&mut self, v: f64) -> Result<Self::Value, Self::Error>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_char(&mut self, v: char) -> Result<Self::Value, Self::Error> {
|
|
||||||
// The unwraps in here should be safe.
|
|
||||||
let mut s = &mut [0; 4];
|
|
||||||
let len = v.encode_utf8(s).unwrap();
|
|
||||||
self.visit_str(str::from_utf8(&s[..len]).unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_str(&mut self, value: &str) -> Result<Self::Value, Self::Error>;
|
|
||||||
|
|
||||||
fn visit_unit(&mut self) -> Result<Self::Value, Self::Error>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_named_unit(&mut self, _name: &str) -> Result<Self::Value, Self::Error> {
|
|
||||||
self.visit_unit()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_enum_unit(&mut self,
|
|
||||||
_name: &str,
|
|
||||||
_variant: &str) -> Result<Self::Value, Self::Error> {
|
|
||||||
self.visit_unit()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_none(&mut self) -> Result<Self::Value, Self::Error>;
|
|
||||||
|
|
||||||
fn visit_some<V>(&mut self, value: V) -> Result<Self::Value, Self::Error>
|
|
||||||
where V: Serialize;
|
|
||||||
|
|
||||||
fn visit_seq<V>(&mut self, visitor: V) -> Result<Self::Value, Self::Error>
|
|
||||||
where V: SeqVisitor;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_named_seq<V>(&mut self,
|
|
||||||
_name: &'static str,
|
|
||||||
visitor: V) -> Result<Self::Value, Self::Error>
|
|
||||||
where V: SeqVisitor,
|
|
||||||
{
|
|
||||||
self.visit_seq(visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_enum_seq<V>(&mut self,
|
|
||||||
_name: &'static str,
|
|
||||||
_variant: &'static str,
|
|
||||||
visitor: V) -> Result<Self::Value, Self::Error>
|
|
||||||
where V: SeqVisitor,
|
|
||||||
{
|
|
||||||
self.visit_seq(visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_seq_elt<T>(&mut self,
|
|
||||||
first: bool,
|
|
||||||
value: T) -> Result<Self::Value, Self::Error>
|
|
||||||
where T: Serialize;
|
|
||||||
|
|
||||||
fn visit_map<V>(&mut self, visitor: V) -> Result<Self::Value, Self::Error>
|
|
||||||
where V: MapVisitor;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_named_map<V>(&mut self,
|
|
||||||
_name: &'static str,
|
|
||||||
visitor: V) -> Result<Self::Value, Self::Error>
|
|
||||||
where V: MapVisitor,
|
|
||||||
{
|
|
||||||
self.visit_map(visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_enum_map<V>(&mut self,
|
|
||||||
_name: &'static str,
|
|
||||||
_variant: &'static str,
|
|
||||||
visitor: V) -> Result<Self::Value, Self::Error>
|
|
||||||
where V: MapVisitor,
|
|
||||||
{
|
|
||||||
self.visit_map(visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_map_elt<K, V>(&mut self,
|
|
||||||
first: bool,
|
|
||||||
key: K,
|
|
||||||
value: V) -> Result<Self::Value, Self::Error>
|
|
||||||
where K: Serialize,
|
|
||||||
V: Serialize;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait SeqVisitor {
|
|
||||||
fn visit<V>(&mut self, visitor: &mut V) -> Result<Option<V::Value>, V::Error>
|
|
||||||
where V: Visitor;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
(0, None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait MapVisitor {
|
|
||||||
fn visit<V>(&mut self, visitor: &mut V) -> Result<Option<V::Value>, V::Error>
|
|
||||||
where V: Visitor;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
(0, None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
macro_rules! impl_visit {
|
|
||||||
($ty:ty, $method:ident) => {
|
|
||||||
impl Serialize for $ty {
|
|
||||||
#[inline]
|
|
||||||
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
|
||||||
where V: Visitor,
|
|
||||||
{
|
|
||||||
visitor.$method(*self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_visit!(bool, visit_bool);
|
|
||||||
impl_visit!(isize, visit_isize);
|
|
||||||
impl_visit!(i8, visit_i8);
|
|
||||||
impl_visit!(i16, visit_i16);
|
|
||||||
impl_visit!(i32, visit_i32);
|
|
||||||
impl_visit!(i64, visit_i64);
|
|
||||||
impl_visit!(usize, visit_usize);
|
|
||||||
impl_visit!(u8, visit_u8);
|
|
||||||
impl_visit!(u16, visit_u16);
|
|
||||||
impl_visit!(u32, visit_u32);
|
|
||||||
impl_visit!(u64, visit_u64);
|
|
||||||
impl_visit!(f32, visit_f32);
|
|
||||||
impl_visit!(f64, visit_f64);
|
|
||||||
impl_visit!(char, visit_char);
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
impl<'a> Serialize for &'a str {
|
|
||||||
#[inline]
|
|
||||||
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
|
||||||
where V: Visitor,
|
|
||||||
{
|
|
||||||
visitor.visit_str(*self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Serialize for String {
|
|
||||||
#[inline]
|
|
||||||
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
|
||||||
where V: Visitor,
|
|
||||||
{
|
|
||||||
(&self[..]).visit(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
impl<T> Serialize for Option<T> where T: Serialize {
|
|
||||||
#[inline]
|
|
||||||
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
|
||||||
where V: Visitor,
|
|
||||||
{
|
|
||||||
match *self {
|
|
||||||
Some(ref value) => visitor.visit_some(value),
|
|
||||||
None => visitor.visit_none(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
pub struct SeqIteratorVisitor<Iter> {
|
|
||||||
iter: Iter,
|
|
||||||
first: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, Iter> SeqIteratorVisitor<Iter>
|
|
||||||
where Iter: Iterator<Item=T>
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
pub fn new(iter: Iter) -> SeqIteratorVisitor<Iter> {
|
|
||||||
SeqIteratorVisitor {
|
|
||||||
iter: iter,
|
|
||||||
first: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, Iter> SeqVisitor for SeqIteratorVisitor<Iter>
|
|
||||||
where T: Serialize,
|
|
||||||
Iter: Iterator<Item=T>,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn visit<V>(&mut self, visitor: &mut V) -> Result<Option<V::Value>, V::Error>
|
|
||||||
where V: Visitor,
|
|
||||||
{
|
|
||||||
let first = self.first;
|
|
||||||
self.first = false;
|
|
||||||
|
|
||||||
match self.iter.next() {
|
|
||||||
Some(value) => {
|
|
||||||
let value = try!(visitor.visit_seq_elt(first, value));
|
|
||||||
Ok(Some(value))
|
|
||||||
}
|
|
||||||
None => Ok(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
self.iter.size_hint()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
impl<'a, T> Serialize for &'a [T]
|
|
||||||
where T: Serialize,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
|
||||||
where V: Visitor,
|
|
||||||
{
|
|
||||||
visitor.visit_seq(SeqIteratorVisitor::new(self.iter()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Serialize for Vec<T> where T: Serialize {
|
|
||||||
#[inline]
|
|
||||||
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
|
||||||
where V: Visitor,
|
|
||||||
{
|
|
||||||
(&self[..]).visit(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Serialize for BTreeSet<T> where T: Serialize {
|
|
||||||
#[inline]
|
|
||||||
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
|
||||||
where V: Visitor,
|
|
||||||
{
|
|
||||||
visitor.visit_seq(SeqIteratorVisitor::new(self.iter()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, S> Serialize for HashSet<T, S>
|
|
||||||
where T: Serialize + Eq + Hash,
|
|
||||||
S: HashState,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn visit<V: Visitor>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
|
|
||||||
visitor.visit_seq(SeqIteratorVisitor::new(self.iter()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
impl Serialize for () {
|
|
||||||
#[inline]
|
|
||||||
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
|
||||||
where V: Visitor,
|
|
||||||
{
|
|
||||||
visitor.visit_unit()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// FIXME(rust #19630) Remove this work-around
|
|
||||||
macro_rules! e {
|
|
||||||
($e:expr) => { $e }
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! tuple_impls {
|
|
||||||
($(
|
|
||||||
$TupleVisitor:ident ($len:expr, $($T:ident),+) {
|
|
||||||
$($state:pat => $idx:tt,)+
|
|
||||||
}
|
|
||||||
)+) => {
|
|
||||||
$(
|
|
||||||
pub struct $TupleVisitor<'a, $($T: 'a),+> {
|
|
||||||
tuple: &'a ($($T,)+),
|
|
||||||
state: u8,
|
|
||||||
first: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, $($T: 'a),+> $TupleVisitor<'a, $($T),+> {
|
|
||||||
pub fn new(tuple: &'a ($($T,)+)) -> $TupleVisitor<'a, $($T),+> {
|
|
||||||
$TupleVisitor {
|
|
||||||
tuple: tuple,
|
|
||||||
state: 0,
|
|
||||||
first: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, $($T),+> SeqVisitor for $TupleVisitor<'a, $($T),+>
|
|
||||||
where $($T: Serialize),+
|
|
||||||
{
|
|
||||||
fn visit<V>(&mut self, visitor: &mut V) -> Result<Option<V::Value>, V::Error>
|
|
||||||
where V: Visitor,
|
|
||||||
{
|
|
||||||
let first = self.first;
|
|
||||||
self.first = false;
|
|
||||||
|
|
||||||
match self.state {
|
|
||||||
$(
|
|
||||||
$state => {
|
|
||||||
self.state += 1;
|
|
||||||
Ok(Some(try!(visitor.visit_seq_elt(first, &e!(self.tuple.$idx)))))
|
|
||||||
}
|
|
||||||
)+
|
|
||||||
_ => {
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
($len, Some($len))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<$($T),+> Serialize for ($($T,)+)
|
|
||||||
where $($T: Serialize),+
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn visit<V: Visitor>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
|
|
||||||
visitor.visit_seq($TupleVisitor::new(self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tuple_impls! {
|
|
||||||
TupleVisitor1 (1, T0) {
|
|
||||||
0 => 0,
|
|
||||||
}
|
|
||||||
TupleVisitor2 (2, T0, T1) {
|
|
||||||
0 => 0,
|
|
||||||
1 => 1,
|
|
||||||
}
|
|
||||||
TupleVisitor3 (3, T0, T1, T2) {
|
|
||||||
0 => 0,
|
|
||||||
1 => 1,
|
|
||||||
2 => 2,
|
|
||||||
}
|
|
||||||
TupleVisitor4 (4, T0, T1, T2, T3) {
|
|
||||||
0 => 0,
|
|
||||||
1 => 1,
|
|
||||||
2 => 2,
|
|
||||||
3 => 3,
|
|
||||||
}
|
|
||||||
TupleVisitor5 (5, T0, T1, T2, T3, T4) {
|
|
||||||
0 => 0,
|
|
||||||
1 => 1,
|
|
||||||
2 => 2,
|
|
||||||
3 => 3,
|
|
||||||
4 => 4,
|
|
||||||
}
|
|
||||||
TupleVisitor6 (6, T0, T1, T2, T3, T4, T5) {
|
|
||||||
0 => 0,
|
|
||||||
1 => 1,
|
|
||||||
2 => 2,
|
|
||||||
3 => 3,
|
|
||||||
4 => 4,
|
|
||||||
5 => 5,
|
|
||||||
}
|
|
||||||
TupleVisitor7 (7, T0, T1, T2, T3, T4, T5, T6) {
|
|
||||||
0 => 0,
|
|
||||||
1 => 1,
|
|
||||||
2 => 2,
|
|
||||||
3 => 3,
|
|
||||||
4 => 4,
|
|
||||||
5 => 5,
|
|
||||||
6 => 6,
|
|
||||||
}
|
|
||||||
TupleVisitor8 (8, T0, T1, T2, T3, T4, T5, T6, T7) {
|
|
||||||
0 => 0,
|
|
||||||
1 => 1,
|
|
||||||
2 => 2,
|
|
||||||
3 => 3,
|
|
||||||
4 => 4,
|
|
||||||
5 => 5,
|
|
||||||
6 => 6,
|
|
||||||
7 => 7,
|
|
||||||
}
|
|
||||||
TupleVisitor9 (9, T0, T1, T2, T3, T4, T5, T6, T7, T8) {
|
|
||||||
0 => 0,
|
|
||||||
1 => 1,
|
|
||||||
2 => 2,
|
|
||||||
3 => 3,
|
|
||||||
4 => 4,
|
|
||||||
5 => 5,
|
|
||||||
6 => 6,
|
|
||||||
7 => 7,
|
|
||||||
8 => 8,
|
|
||||||
}
|
|
||||||
TupleVisitor10 (10, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) {
|
|
||||||
0 => 0,
|
|
||||||
1 => 1,
|
|
||||||
2 => 2,
|
|
||||||
3 => 3,
|
|
||||||
4 => 4,
|
|
||||||
5 => 5,
|
|
||||||
6 => 6,
|
|
||||||
7 => 7,
|
|
||||||
8 => 8,
|
|
||||||
9 => 9,
|
|
||||||
}
|
|
||||||
TupleVisitor11 (11, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) {
|
|
||||||
0 => 0,
|
|
||||||
1 => 1,
|
|
||||||
2 => 2,
|
|
||||||
3 => 3,
|
|
||||||
4 => 4,
|
|
||||||
5 => 5,
|
|
||||||
6 => 6,
|
|
||||||
7 => 7,
|
|
||||||
8 => 8,
|
|
||||||
9 => 9,
|
|
||||||
10 => 10,
|
|
||||||
}
|
|
||||||
TupleVisitor12 (12, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) {
|
|
||||||
0 => 0,
|
|
||||||
1 => 1,
|
|
||||||
2 => 2,
|
|
||||||
3 => 3,
|
|
||||||
4 => 4,
|
|
||||||
5 => 5,
|
|
||||||
6 => 6,
|
|
||||||
7 => 7,
|
|
||||||
8 => 8,
|
|
||||||
9 => 9,
|
|
||||||
10 => 10,
|
|
||||||
11 => 11,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
pub struct MapIteratorVisitor<Iter> {
|
|
||||||
iter: Iter,
|
|
||||||
first: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<K, V, Iter> MapIteratorVisitor<Iter>
|
|
||||||
where Iter: Iterator<Item=(K, V)>
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
pub fn new(iter: Iter) -> MapIteratorVisitor<Iter> {
|
|
||||||
MapIteratorVisitor {
|
|
||||||
iter: iter,
|
|
||||||
first: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<K, V, I> MapVisitor for MapIteratorVisitor<I>
|
|
||||||
where K: Serialize,
|
|
||||||
V: Serialize,
|
|
||||||
I: Iterator<Item=(K, V)>,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn visit<V_>(&mut self, visitor: &mut V_) -> Result<Option<V_::Value>, V_::Error>
|
|
||||||
where V_: Visitor,
|
|
||||||
{
|
|
||||||
let first = self.first;
|
|
||||||
self.first = false;
|
|
||||||
|
|
||||||
match self.iter.next() {
|
|
||||||
Some((key, value)) => {
|
|
||||||
let value = try!(visitor.visit_map_elt(first, key, value));
|
|
||||||
Ok(Some(value))
|
|
||||||
}
|
|
||||||
None => Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
self.iter.size_hint()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
impl<K, V> Serialize for BTreeMap<K, V>
|
|
||||||
where K: Serialize + Ord,
|
|
||||||
V: Serialize,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn visit<V_: Visitor>(&self, visitor: &mut V_) -> Result<V_::Value, V_::Error> {
|
|
||||||
visitor.visit_map(MapIteratorVisitor::new(self.iter()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<K, V, S> Serialize for HashMap<K, V, S>
|
|
||||||
where K: Serialize + Eq + Hash,
|
|
||||||
V: Serialize,
|
|
||||||
S: HashState,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn visit<V_: Visitor>(&self, visitor: &mut V_) -> Result<V_::Value, V_::Error> {
|
|
||||||
visitor.visit_map(MapIteratorVisitor::new(self.iter()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
impl<'a, T> Serialize for &'a T where T: Serialize {
|
|
||||||
#[inline]
|
|
||||||
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
|
||||||
where V: Visitor,
|
|
||||||
{
|
|
||||||
(**self).visit(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T> Serialize for &'a mut T where T: Serialize {
|
|
||||||
#[inline]
|
|
||||||
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
|
||||||
where V: Visitor,
|
|
||||||
{
|
|
||||||
(**self).visit(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Serialize for Box<T> where T: Serialize {
|
|
||||||
#[inline]
|
|
||||||
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
|
||||||
where V: Visitor,
|
|
||||||
{
|
|
||||||
(**self).visit(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Serialize for Rc<T> where T: Serialize, {
|
|
||||||
#[inline]
|
|
||||||
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
|
||||||
where V: Visitor,
|
|
||||||
{
|
|
||||||
(**self).visit(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Serialize for Arc<T> where T: Serialize, {
|
|
||||||
#[inline]
|
|
||||||
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
|
||||||
where V: Visitor,
|
|
||||||
{
|
|
||||||
(**self).visit(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
impl Serialize for path::Path {
|
|
||||||
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
|
||||||
where V: Visitor,
|
|
||||||
{
|
|
||||||
self.to_str().unwrap().visit(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Serialize for path::PathBuf {
|
|
||||||
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
|
||||||
where V: Visitor,
|
|
||||||
{
|
|
||||||
self.to_str().unwrap().visit(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
/target
|
||||||
|
/Cargo.lock
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_macros"
|
name = "serde_macros"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
|
||||||
|
|
||||||
[[lib]]
|
[lib]
|
||||||
name = "serde_macros"
|
name = "serde_macros"
|
||||||
path = "src/lib.rs"
|
|
||||||
plugin = true
|
plugin = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
quasi = "0.1.0"
|
||||||
|
quasi_macros = "0.1.0"
|
||||||
|
aster = "0.1.2"
|
||||||
|
|||||||
+1250
-316
File diff suppressed because it is too large
Load Diff
+20
-71
@@ -10,7 +10,8 @@
|
|||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use json::value::{ToJson, Value};
|
use ser::{self, Serialize};
|
||||||
|
use json::value::{self, Value};
|
||||||
|
|
||||||
pub struct ArrayBuilder {
|
pub struct ArrayBuilder {
|
||||||
array: Vec<Value>,
|
array: Vec<Value>,
|
||||||
@@ -25,24 +26,25 @@ impl ArrayBuilder {
|
|||||||
Value::Array(self.array)
|
Value::Array(self.array)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push<T: ToJson>(self, value: T) -> ArrayBuilder {
|
pub fn push<T: ser::Serialize>(mut self, v: T) -> ArrayBuilder {
|
||||||
let mut builder = self;
|
self.array.push(value::to_value(&v));
|
||||||
builder.array.push(value.to_json());
|
self
|
||||||
builder
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_array<F>(self, f: F) -> ArrayBuilder where
|
pub fn push_array<F>(mut self, f: F) -> ArrayBuilder where
|
||||||
F: FnOnce(ArrayBuilder) -> ArrayBuilder
|
F: FnOnce(ArrayBuilder) -> ArrayBuilder
|
||||||
{
|
{
|
||||||
let builder = ArrayBuilder::new();
|
let builder = ArrayBuilder::new();
|
||||||
self.push(f(builder).unwrap())
|
self.array.push(f(builder).unwrap());
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_object<F>(self, f: F) -> ArrayBuilder where
|
pub fn push_object<F>(mut self, f: F) -> ArrayBuilder where
|
||||||
F: FnOnce(ObjectBuilder) -> ObjectBuilder
|
F: FnOnce(ObjectBuilder) -> ObjectBuilder
|
||||||
{
|
{
|
||||||
let builder = ObjectBuilder::new();
|
let builder = ObjectBuilder::new();
|
||||||
self.push(f(builder).unwrap())
|
self.array.push(f(builder).unwrap());
|
||||||
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,77 +61,24 @@ impl ObjectBuilder {
|
|||||||
Value::Object(self.object)
|
Value::Object(self.object)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert<V: ToJson>(self, key: String, value: V) -> ObjectBuilder {
|
pub fn insert<V: ser::Serialize>(mut self, k: String, v: V) -> ObjectBuilder {
|
||||||
let mut builder = self;
|
self.object.insert(k, value::to_value(&v));
|
||||||
builder.object.insert(key, value.to_json());
|
self
|
||||||
builder
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_array<F>(self, key: String, f: F) -> ObjectBuilder where
|
pub fn insert_array<F>(mut self, key: String, f: F) -> ObjectBuilder where
|
||||||
F: FnOnce(ArrayBuilder) -> ArrayBuilder
|
F: FnOnce(ArrayBuilder) -> ArrayBuilder
|
||||||
{
|
{
|
||||||
let builder = ArrayBuilder::new();
|
let builder = ArrayBuilder::new();
|
||||||
self.insert(key, f(builder).unwrap())
|
self.object.insert(key, f(builder).unwrap());
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_object<F>(self, key: String, f: F) -> ObjectBuilder where
|
pub fn insert_object<F>(mut self, key: String, f: F) -> ObjectBuilder where
|
||||||
F: FnOnce(ObjectBuilder) -> ObjectBuilder
|
F: FnOnce(ObjectBuilder) -> ObjectBuilder
|
||||||
{
|
{
|
||||||
let builder = ObjectBuilder::new();
|
let builder = ObjectBuilder::new();
|
||||||
self.insert(key, f(builder).unwrap())
|
self.object.insert(key, f(builder).unwrap());
|
||||||
}
|
self
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use std::collections::BTreeMap;
|
|
||||||
|
|
||||||
use json::value::Value;
|
|
||||||
use super::{ArrayBuilder, ObjectBuilder};
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_array_builder() {
|
|
||||||
let value = ArrayBuilder::new().unwrap();
|
|
||||||
assert_eq!(value, Value::Array(Vec::new()));
|
|
||||||
|
|
||||||
let value = ArrayBuilder::new()
|
|
||||||
.push(1is)
|
|
||||||
.push(2is)
|
|
||||||
.push(3is)
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!(value, Value::Array(vec!(Value::Integer(1), Value::Integer(2), Value::Integer(3))));
|
|
||||||
|
|
||||||
let value = ArrayBuilder::new()
|
|
||||||
.push_array(|bld| bld.push(1is).push(2is).push(3is))
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!(value, Value::Array(vec!(Value::Array(vec!(Value::Integer(1), Value::Integer(2), Value::Integer(3))))));
|
|
||||||
|
|
||||||
let value = ArrayBuilder::new()
|
|
||||||
.push_object(|bld|
|
|
||||||
bld
|
|
||||||
.insert("a".to_string(), 1is)
|
|
||||||
.insert("b".to_string(), 2is))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut map = BTreeMap::new();
|
|
||||||
map.insert("a".to_string(), Value::Integer(1));
|
|
||||||
map.insert("b".to_string(), Value::Integer(2));
|
|
||||||
assert_eq!(value, Value::Array(vec!(Value::Object(map))));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_object_builder() {
|
|
||||||
let value = ObjectBuilder::new().unwrap();
|
|
||||||
assert_eq!(value, Value::Object(BTreeMap::new()));
|
|
||||||
|
|
||||||
let value = ObjectBuilder::new()
|
|
||||||
.insert("a".to_string(), 1is)
|
|
||||||
.insert("b".to_string(), 2is)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut map = BTreeMap::new();
|
|
||||||
map.insert("a".to_string(), Value::Integer(1));
|
|
||||||
map.insert("b".to_string(), Value::Integer(2));
|
|
||||||
assert_eq!(value, Value::Object(map));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+288
-316
@@ -1,110 +1,50 @@
|
|||||||
use std::str;
|
use std::char;
|
||||||
use std::num::Float;
|
use std::num::Float;
|
||||||
use unicode::str::Utf16Item;
|
use unicode::str::Utf16Item;
|
||||||
use std::char;
|
use std::str;
|
||||||
|
|
||||||
use de;
|
use de;
|
||||||
|
|
||||||
use super::error::{Error, ErrorCode};
|
use super::error::{Error, ErrorCode};
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
pub struct Deserializer<Iter> {
|
||||||
enum State {
|
|
||||||
// Parse a value.
|
|
||||||
Value,
|
|
||||||
// Parse a value or ']'.
|
|
||||||
ListStart,
|
|
||||||
// Parse ',' or ']' after an element in a list.
|
|
||||||
ListCommaOrEnd,
|
|
||||||
// Parse a key:value or an ']'.
|
|
||||||
ObjectStart,
|
|
||||||
// Parse ',' or ']' after an element in an object.
|
|
||||||
ObjectCommaOrEnd,
|
|
||||||
// Parse a key in an object.
|
|
||||||
//ObjectKey,
|
|
||||||
// Parse a value in an object.
|
|
||||||
ObjectValue,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A streaming JSON parser implemented as an iterator of JsonEvent, consuming
|
|
||||||
/// an iterator of char.
|
|
||||||
pub struct Parser<Iter> {
|
|
||||||
rdr: Iter,
|
rdr: Iter,
|
||||||
ch: Option<u8>,
|
ch: Option<u8>,
|
||||||
line: usize,
|
line: usize,
|
||||||
col: usize,
|
col: usize,
|
||||||
// A state machine is kept to make it possible to interupt and resume parsing.
|
|
||||||
state_stack: Vec<State>,
|
|
||||||
buf: Vec<u8>,
|
buf: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Iter: Iterator<Item=u8>> Iterator for Parser<Iter> {
|
impl<Iter> Deserializer<Iter>
|
||||||
type Item = Result<de::Token, Error>;
|
where Iter: Iterator<Item=u8>,
|
||||||
|
{
|
||||||
#[inline]
|
|
||||||
fn next(&mut self) -> Option<Result<de::Token, Error>> {
|
|
||||||
let state = match self.state_stack.pop() {
|
|
||||||
Some(state) => state,
|
|
||||||
None => {
|
|
||||||
// If we have no state left, then we're expecting the structure
|
|
||||||
// to be done, so make sure there are no trailing characters.
|
|
||||||
|
|
||||||
self.parse_whitespace();
|
|
||||||
|
|
||||||
if self.eof() {
|
|
||||||
return None;
|
|
||||||
} else {
|
|
||||||
return Some(Err(self.error(ErrorCode::TrailingCharacters)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
match state {
|
|
||||||
State::Value => Some(self.parse_value()),
|
|
||||||
State::ListStart => Some(self.parse_list_start()),
|
|
||||||
State::ListCommaOrEnd => Some(self.parse_list_comma_or_end()),
|
|
||||||
State::ObjectStart => {
|
|
||||||
match self.parse_object_start() {
|
|
||||||
Ok(Some(s)) => Some(Ok(de::Token::String(s.to_string()))),
|
|
||||||
Ok(None) => Some(Ok(de::Token::End)),
|
|
||||||
Err(err) => Some(Err(err)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
State::ObjectCommaOrEnd => {
|
|
||||||
match self.parse_object_comma_or_end() {
|
|
||||||
Ok(Some(s)) => Some(Ok(de::Token::String(s.to_string()))),
|
|
||||||
Ok(None) => Some(Ok(de::Token::End)),
|
|
||||||
Err(err) => Some(Err(err)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//State::ObjectKey => Some(self.parse_object_key()),
|
|
||||||
State::ObjectValue => Some(self.parse_object_value()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Iter: Iterator<Item=u8>> Parser<Iter> {
|
|
||||||
/// Creates the JSON parser.
|
/// Creates the JSON parser.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(rdr: Iter) -> Parser<Iter> {
|
pub fn new(rdr: Iter) -> Deserializer<Iter> {
|
||||||
let mut p = Parser {
|
let mut p = Deserializer {
|
||||||
rdr: rdr,
|
rdr: rdr,
|
||||||
ch: Some(b'\x00'),
|
ch: Some(b'\x00'),
|
||||||
line: 1,
|
line: 1,
|
||||||
col: 0,
|
col: 0,
|
||||||
state_stack: vec!(State::Value),
|
|
||||||
buf: Vec::with_capacity(128),
|
buf: Vec::with_capacity(128),
|
||||||
};
|
};
|
||||||
p.bump();
|
p.bump();
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
|
pub fn end(&mut self) -> Result<(), Error> {
|
||||||
|
self.parse_whitespace();
|
||||||
|
if self.eof() {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(self.error(ErrorCode::TrailingCharacters))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn eof(&self) -> bool { self.ch.is_none() }
|
fn eof(&self) -> bool { self.ch.is_none() }
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn ch_or_null(&self) -> u8 { self.ch.unwrap_or(b'\x00') }
|
fn ch_or_null(&self) -> u8 { self.ch.unwrap_or(b'\x00') }
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn bump(&mut self) {
|
fn bump(&mut self) {
|
||||||
self.ch = self.rdr.next();
|
self.ch = self.rdr.next();
|
||||||
|
|
||||||
@@ -116,23 +56,19 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next_char(&mut self) -> Option<u8> {
|
fn next_char(&mut self) -> Option<u8> {
|
||||||
self.bump();
|
self.bump();
|
||||||
self.ch
|
self.ch
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn ch_is(&self, c: u8) -> bool {
|
fn ch_is(&self, c: u8) -> bool {
|
||||||
self.ch == Some(c)
|
self.ch == Some(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn error(&mut self, reason: ErrorCode) -> Error {
|
fn error(&mut self, reason: ErrorCode) -> Error {
|
||||||
Error::SyntaxError(reason, self.line, self.col)
|
Error::SyntaxError(reason, self.line, self.col)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn parse_whitespace(&mut self) {
|
fn parse_whitespace(&mut self) {
|
||||||
while self.ch_is(b' ') ||
|
while self.ch_is(b' ') ||
|
||||||
self.ch_is(b'\n') ||
|
self.ch_is(b'\n') ||
|
||||||
@@ -140,8 +76,9 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
|
|||||||
self.ch_is(b'\r') { self.bump(); }
|
self.ch_is(b'\r') { self.bump(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn parse_value<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
fn parse_value(&mut self) -> Result<de::Token, Error> {
|
where V: de::Visitor,
|
||||||
|
{
|
||||||
self.parse_whitespace();
|
self.parse_whitespace();
|
||||||
|
|
||||||
if self.eof() {
|
if self.eof() {
|
||||||
@@ -149,22 +86,31 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match self.ch_or_null() {
|
match self.ch_or_null() {
|
||||||
b'n' => self.parse_ident(b"ull", de::Token::Null),
|
b'n' => {
|
||||||
b't' => self.parse_ident(b"rue", de::Token::Bool(true)),
|
try!(self.parse_ident(b"ull"));
|
||||||
b'f' => self.parse_ident(b"alse", de::Token::Bool(false)),
|
visitor.visit_unit()
|
||||||
b'0' ... b'9' | b'-' => self.parse_number(),
|
}
|
||||||
|
b't' => {
|
||||||
|
try!(self.parse_ident(b"rue"));
|
||||||
|
visitor.visit_bool(true)
|
||||||
|
}
|
||||||
|
b'f' => {
|
||||||
|
try!(self.parse_ident(b"alse"));
|
||||||
|
visitor.visit_bool(false)
|
||||||
|
}
|
||||||
|
b'0' ... b'9' | b'-' => self.parse_number(visitor),
|
||||||
b'"' => {
|
b'"' => {
|
||||||
Ok(de::Token::String(try!(self.parse_string()).to_string()))
|
try!(self.parse_string());
|
||||||
|
let s = str::from_utf8(&self.buf).unwrap();
|
||||||
|
visitor.visit_str(s)
|
||||||
}
|
}
|
||||||
b'[' => {
|
b'[' => {
|
||||||
self.bump();
|
self.bump();
|
||||||
self.state_stack.push(State::ListStart);
|
visitor.visit_seq(SeqVisitor::new(self))
|
||||||
Ok(de::Token::SeqStart(0))
|
|
||||||
}
|
}
|
||||||
b'{' => {
|
b'{' => {
|
||||||
self.bump();
|
self.bump();
|
||||||
self.state_stack.push(State::ObjectStart);
|
visitor.visit_map(MapVisitor::new(self))
|
||||||
Ok(de::Token::MapStart(0))
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
Err(self.error(ErrorCode::ExpectedSomeValue))
|
Err(self.error(ErrorCode::ExpectedSomeValue))
|
||||||
@@ -172,18 +118,18 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn parse_ident(&mut self, ident: &[u8]) -> Result<(), Error> {
|
||||||
fn parse_ident(&mut self, ident: &[u8], token: de::Token) -> Result<de::Token, Error> {
|
|
||||||
if ident.iter().all(|c| Some(*c) == self.next_char()) {
|
if ident.iter().all(|c| Some(*c) == self.next_char()) {
|
||||||
self.bump();
|
self.bump();
|
||||||
Ok(token)
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(self.error(ErrorCode::ExpectedSomeIdent))
|
Err(self.error(ErrorCode::ExpectedSomeIdent))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn parse_number<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
fn parse_number(&mut self) -> Result<de::Token, Error> {
|
where V: de::Visitor,
|
||||||
|
{
|
||||||
let mut neg = 1;
|
let mut neg = 1;
|
||||||
|
|
||||||
if self.ch_is(b'-') {
|
if self.ch_is(b'-') {
|
||||||
@@ -205,13 +151,12 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
|
|||||||
res = try!(self.parse_exponent(res));
|
res = try!(self.parse_exponent(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(de::Token::F64(neg * res))
|
visitor.visit_f64(neg * res)
|
||||||
} else {
|
} else {
|
||||||
Ok(de::Token::I64(neg * res))
|
visitor.visit_i64(neg * res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn parse_integer(&mut self) -> Result<i64, Error> {
|
fn parse_integer(&mut self) -> Result<i64, Error> {
|
||||||
let mut res = 0;
|
let mut res = 0;
|
||||||
|
|
||||||
@@ -245,7 +190,6 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
|
|||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn parse_decimal(&mut self, res: f64) -> Result<f64, Error> {
|
fn parse_decimal(&mut self, res: f64) -> Result<f64, Error> {
|
||||||
self.bump();
|
self.bump();
|
||||||
|
|
||||||
@@ -261,7 +205,7 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
|
|||||||
match self.ch_or_null() {
|
match self.ch_or_null() {
|
||||||
c @ b'0' ... b'9' => {
|
c @ b'0' ... b'9' => {
|
||||||
dec /= 10.0;
|
dec /= 10.0;
|
||||||
res += (((c as isize) - (b'0' as isize)) as f64) * dec;
|
res += (((c as u64) - (b'0' as u64)) as f64) * dec;
|
||||||
self.bump();
|
self.bump();
|
||||||
}
|
}
|
||||||
_ => break,
|
_ => break,
|
||||||
@@ -271,11 +215,10 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
|
|||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn parse_exponent(&mut self, mut res: f64) -> Result<f64, Error> {
|
fn parse_exponent(&mut self, mut res: f64) -> Result<f64, Error> {
|
||||||
self.bump();
|
self.bump();
|
||||||
|
|
||||||
let mut exp = 0us;
|
let mut exp = 0;
|
||||||
let mut neg_exp = false;
|
let mut neg_exp = false;
|
||||||
|
|
||||||
if self.ch_is(b'+') {
|
if self.ch_is(b'+') {
|
||||||
@@ -294,7 +237,7 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
|
|||||||
match self.ch_or_null() {
|
match self.ch_or_null() {
|
||||||
c @ b'0' ... b'9' => {
|
c @ b'0' ... b'9' => {
|
||||||
exp *= 10;
|
exp *= 10;
|
||||||
exp += (c as usize) - (b'0' as usize);
|
exp += (c as i32) - (b'0' as i32);
|
||||||
|
|
||||||
self.bump();
|
self.bump();
|
||||||
}
|
}
|
||||||
@@ -302,7 +245,7 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let exp: f64 = 10_f64.powi(exp as i32);
|
let exp: f64 = 10_f64.powi(exp);
|
||||||
if neg_exp {
|
if neg_exp {
|
||||||
res /= exp;
|
res /= exp;
|
||||||
} else {
|
} else {
|
||||||
@@ -312,11 +255,10 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
|
|||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn decode_hex_escape(&mut self) -> Result<u16, Error> {
|
fn decode_hex_escape(&mut self) -> Result<u16, Error> {
|
||||||
let mut i = 0us;
|
let mut i = 0;
|
||||||
let mut n = 0u16;
|
let mut n = 0u16;
|
||||||
while i < 4us && !self.eof() {
|
while i < 4 && !self.eof() {
|
||||||
self.bump();
|
self.bump();
|
||||||
n = match self.ch_or_null() {
|
n = match self.ch_or_null() {
|
||||||
c @ b'0' ... b'9' => n * 16_u16 + ((c as u16) - (b'0' as u16)),
|
c @ b'0' ... b'9' => n * 16_u16 + ((c as u16) - (b'0' as u16)),
|
||||||
@@ -329,19 +271,18 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
|
|||||||
_ => { return Err(self.error(ErrorCode::InvalidEscape)); }
|
_ => { return Err(self.error(ErrorCode::InvalidEscape)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
i += 1us;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error out if we didn't parse 4 digits.
|
// Error out if we didn't parse 4 digits.
|
||||||
if i != 4us {
|
if i != 4 {
|
||||||
return Err(self.error(ErrorCode::InvalidEscape));
|
return Err(self.error(ErrorCode::InvalidEscape));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(n)
|
Ok(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn parse_string(&mut self) -> Result<(), Error> {
|
||||||
fn parse_string(&mut self) -> Result<&str, Error> {
|
|
||||||
self.buf.clear();
|
self.buf.clear();
|
||||||
|
|
||||||
let mut escape = false;
|
let mut escape = false;
|
||||||
@@ -397,7 +338,7 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let buf = &mut [0u8; 4];
|
let buf = &mut [0; 4];
|
||||||
let len = c.encode_utf8(buf).unwrap_or(0);
|
let len = c.encode_utf8(buf).unwrap_or(0);
|
||||||
self.buf.extend(buf[..len].iter().map(|b| *b));
|
self.buf.extend(buf[..len].iter().map(|b| *b));
|
||||||
}
|
}
|
||||||
@@ -410,7 +351,7 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
|
|||||||
match ch {
|
match ch {
|
||||||
b'"' => {
|
b'"' => {
|
||||||
self.bump();
|
self.bump();
|
||||||
return Ok(str::from_utf8(&self.buf).unwrap());
|
return Ok(());
|
||||||
}
|
}
|
||||||
b'\\' => {
|
b'\\' => {
|
||||||
escape = true;
|
escape = true;
|
||||||
@@ -423,92 +364,12 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn parse_object_colon(&mut self) -> Result<(), Error> {
|
||||||
fn parse_list_start(&mut self) -> Result<de::Token, Error> {
|
|
||||||
self.parse_whitespace();
|
|
||||||
|
|
||||||
if self.ch_is(b']') {
|
|
||||||
self.bump();
|
|
||||||
Ok(de::Token::End)
|
|
||||||
} else {
|
|
||||||
self.state_stack.push(State::ListCommaOrEnd);
|
|
||||||
self.parse_value()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn parse_list_comma_or_end(&mut self) -> Result<de::Token, Error> {
|
|
||||||
self.parse_whitespace();
|
|
||||||
|
|
||||||
if self.ch_is(b',') {
|
|
||||||
self.bump();
|
|
||||||
self.state_stack.push(State::ListCommaOrEnd);
|
|
||||||
self.parse_value()
|
|
||||||
} else if self.ch_is(b']') {
|
|
||||||
self.bump();
|
|
||||||
Ok(de::Token::End)
|
|
||||||
} else if self.eof() {
|
|
||||||
Err(self.error(ErrorCode::EOFWhileParsingList))
|
|
||||||
} else {
|
|
||||||
Err(self.error(ErrorCode::ExpectedListCommaOrEnd))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn parse_object_start(&mut self) -> Result<Option<&str>, Error> {
|
|
||||||
self.parse_whitespace();
|
|
||||||
|
|
||||||
if self.ch_is(b'}') {
|
|
||||||
self.bump();
|
|
||||||
Ok(None)
|
|
||||||
} else {
|
|
||||||
Ok(Some(try!(self.parse_object_key())))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn parse_object_comma_or_end(&mut self) -> Result<Option<&str>, Error> {
|
|
||||||
self.parse_whitespace();
|
|
||||||
|
|
||||||
if self.ch_is(b',') {
|
|
||||||
self.bump();
|
|
||||||
Ok(Some(try!(self.parse_object_key())))
|
|
||||||
} else if self.ch_is(b'}') {
|
|
||||||
self.bump();
|
|
||||||
Ok(None)
|
|
||||||
} else if self.eof() {
|
|
||||||
Err(self.error(ErrorCode::EOFWhileParsingObject))
|
|
||||||
} else {
|
|
||||||
Err(self.error(ErrorCode::ExpectedObjectCommaOrEnd))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn parse_object_key(&mut self) -> Result<&str, Error> {
|
|
||||||
self.parse_whitespace();
|
|
||||||
|
|
||||||
if self.eof() {
|
|
||||||
return Err(self.error(ErrorCode::EOFWhileParsingString));
|
|
||||||
}
|
|
||||||
|
|
||||||
match self.ch_or_null() {
|
|
||||||
b'"' => {
|
|
||||||
self.state_stack.push(State::ObjectValue);
|
|
||||||
|
|
||||||
Ok(try!(self.parse_string()))
|
|
||||||
}
|
|
||||||
_ => Err(self.error(ErrorCode::KeyMustBeAString)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn parse_object_value(&mut self) -> Result<de::Token, Error> {
|
|
||||||
self.parse_whitespace();
|
self.parse_whitespace();
|
||||||
|
|
||||||
if self.ch_is(b':') {
|
if self.ch_is(b':') {
|
||||||
self.bump();
|
self.bump();
|
||||||
self.state_stack.push(State::ObjectCommaOrEnd);
|
Ok(())
|
||||||
self.parse_value()
|
|
||||||
} else if self.eof() {
|
} else if self.eof() {
|
||||||
Err(self.error(ErrorCode::EOFWhileParsingObject))
|
Err(self.error(ErrorCode::EOFWhileParsingObject))
|
||||||
} else {
|
} else {
|
||||||
@@ -517,148 +378,259 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Iter: Iterator<Item=u8>> de::Deserializer<Error> for Parser<Iter> {
|
impl<Iter> de::Deserializer for Deserializer<Iter>
|
||||||
fn end_of_stream_error(&mut self) -> Error {
|
where Iter: Iterator<Item=u8>,
|
||||||
Error::SyntaxError(ErrorCode::EOFWhileParsingValue, self.line, self.col)
|
{
|
||||||
}
|
type Error = Error;
|
||||||
|
|
||||||
fn syntax_error(&mut self, token: de::Token, expected: &'static [de::TokenKind]) -> Error {
|
#[inline]
|
||||||
Error::SyntaxError(ErrorCode::ExpectedTokens(token, expected), self.line, self.col)
|
fn visit<V>(&mut self, visitor: V) -> Result<V::Value, Error>
|
||||||
}
|
where V: de::Visitor,
|
||||||
|
{
|
||||||
fn unexpected_name_error(&mut self, token: de::Token) -> Error {
|
self.parse_value(visitor)
|
||||||
Error::SyntaxError(ErrorCode::UnexpectedName(token), self.line, self.col)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn conversion_error(&mut self, token: de::Token) -> Error {
|
|
||||||
Error::SyntaxError(ErrorCode::ConversionError(token), self.line, self.col)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn missing_field<
|
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
T: de::Deserialize<Parser<Iter>, Error>
|
where V: de::Visitor,
|
||||||
>(&mut self, _field: &'static str) -> Result<T, Error> {
|
{
|
||||||
// JSON can represent `null` values as a missing value, so this isn't
|
self.parse_whitespace();
|
||||||
// necessarily an error.
|
|
||||||
de::Deserialize::deserialize_token(self, de::Token::Null)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special case treating options as a nullable value.
|
if self.eof() {
|
||||||
#[inline]
|
return Err(self.error(ErrorCode::EOFWhileParsingValue));
|
||||||
fn expect_option<
|
|
||||||
U: de::Deserialize<Parser<Iter>, Error>
|
|
||||||
>(&mut self, token: de::Token) -> Result<Option<U>, Error> {
|
|
||||||
match token {
|
|
||||||
de::Token::Null => Ok(None),
|
|
||||||
token => {
|
|
||||||
let value: U = try!(de::Deserialize::deserialize_token(self, token));
|
|
||||||
Ok(Some(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special case treating enums as a `{"<variant-name>": [<fields>]}`.
|
|
||||||
#[inline]
|
|
||||||
fn expect_enum_start(&mut self,
|
|
||||||
token: de::Token,
|
|
||||||
_name: &str,
|
|
||||||
variants: &[&str]) -> Result<usize, Error> {
|
|
||||||
match token {
|
|
||||||
de::Token::MapStart(_) => { }
|
|
||||||
_ => { return Err(self.error(ErrorCode::ExpectedEnumMapStart)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Enums only have one field in them, which is the variant name.
|
|
||||||
let variant = match try!(self.expect_token()) {
|
|
||||||
de::Token::String(variant) => variant,
|
|
||||||
_ => { return Err(self.error(ErrorCode::ExpectedEnumVariantString)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// The variant's field is a list of the values.
|
|
||||||
match try!(self.expect_token()) {
|
|
||||||
de::Token::SeqStart(_) => { }
|
|
||||||
_ => { return Err(self.error(ErrorCode::ExpectedEnumToken)); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match variants.iter().position(|v| *v == &variant[]) {
|
if self.ch_is(b'n') {
|
||||||
Some(idx) => Ok(idx),
|
try!(self.parse_ident(b"ull"));
|
||||||
None => Err(self.error(ErrorCode::UnknownVariant)),
|
visitor.visit_none()
|
||||||
}
|
} else {
|
||||||
}
|
visitor.visit_some(self)
|
||||||
|
|
||||||
fn expect_enum_end(&mut self) -> Result<(), Error> {
|
|
||||||
// There will be one `End` for the list, and one for the object.
|
|
||||||
match try!(self.expect_token()) {
|
|
||||||
de::Token::End => {
|
|
||||||
match try!(self.expect_token()) {
|
|
||||||
de::Token::End => Ok(()),
|
|
||||||
_ => Err(self.error(ErrorCode::ExpectedEnumEndToken)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => Err(self.error(ErrorCode::ExpectedEnumEnd)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn expect_struct_start(&mut self, token: de::Token, _name: &str) -> Result<(), Error> {
|
fn visit_enum<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
match token {
|
where V: de::Visitor,
|
||||||
de::Token::MapStart(_) => Ok(()),
|
{
|
||||||
_ => {
|
self.parse_whitespace();
|
||||||
static EXPECTED_TOKENS: &'static [de::TokenKind] = &[
|
|
||||||
de::TokenKind::MapStartKind,
|
if self.ch_is(b'{') {
|
||||||
];
|
self.bump();
|
||||||
Err(self.syntax_error(token, EXPECTED_TOKENS))
|
self.parse_whitespace();
|
||||||
|
|
||||||
|
try!(self.parse_string());
|
||||||
|
try!(self.parse_object_colon());
|
||||||
|
|
||||||
|
let variant = str::from_utf8(&self.buf).unwrap().to_string();
|
||||||
|
|
||||||
|
let value = try!(visitor.visit_variant(&variant, EnumVisitor {
|
||||||
|
de: self,
|
||||||
|
}));
|
||||||
|
|
||||||
|
self.parse_whitespace();
|
||||||
|
|
||||||
|
if self.ch_is(b'}') {
|
||||||
|
self.bump();
|
||||||
|
Ok(value)
|
||||||
|
} else {
|
||||||
|
return Err(self.error(ErrorCode::ExpectedSomeValue));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Err(self.error(ErrorCode::ExpectedSomeValue))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SeqVisitor<'a, Iter: 'a> {
|
||||||
|
de: &'a mut Deserializer<Iter>,
|
||||||
|
first: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Iter> SeqVisitor<'a, Iter> {
|
||||||
|
fn new(de: &'a mut Deserializer<Iter>) -> Self {
|
||||||
|
SeqVisitor {
|
||||||
|
de: de,
|
||||||
|
first: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter>
|
||||||
|
where Iter: Iterator<Item=u8>
|
||||||
|
{
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
||||||
|
where T: de::Deserialize,
|
||||||
|
{
|
||||||
|
self.de.parse_whitespace();
|
||||||
|
|
||||||
|
if self.de.ch_is(b']') {
|
||||||
|
self.de.bump();
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.first {
|
||||||
|
self.first = false;
|
||||||
|
} else {
|
||||||
|
if self.de.ch_is(b',') {
|
||||||
|
self.de.bump();
|
||||||
|
} else if self.de.eof() {
|
||||||
|
return Err(self.de.error(ErrorCode::EOFWhileParsingList));
|
||||||
|
} else {
|
||||||
|
return Err(self.de.error(ErrorCode::ExpectedListCommaOrEnd));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let value = try!(de::Deserialize::deserialize(self.de));
|
||||||
|
Ok(Some(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(&mut self) -> Result<(), Error> {
|
||||||
|
self.de.parse_whitespace();
|
||||||
|
|
||||||
|
if self.de.ch_is(b']') {
|
||||||
|
self.de.bump();
|
||||||
|
Ok(())
|
||||||
|
} else if self.de.eof() {
|
||||||
|
Err(self.de.error(ErrorCode::EOFWhileParsingList))
|
||||||
|
} else {
|
||||||
|
Err(self.de.error(ErrorCode::TrailingCharacters))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MapVisitor<'a, Iter: 'a> {
|
||||||
|
de: &'a mut Deserializer<Iter>,
|
||||||
|
first: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Iter> MapVisitor<'a, Iter> {
|
||||||
|
fn new(de: &'a mut Deserializer<Iter>) -> Self {
|
||||||
|
MapVisitor {
|
||||||
|
de: de,
|
||||||
|
first: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter>
|
||||||
|
where Iter: Iterator<Item=u8>
|
||||||
|
{
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
|
||||||
|
where K: de::Deserialize,
|
||||||
|
{
|
||||||
|
self.de.parse_whitespace();
|
||||||
|
|
||||||
|
if self.de.ch_is(b'}') {
|
||||||
|
self.de.bump();
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.first {
|
||||||
|
self.first = false;
|
||||||
|
} else {
|
||||||
|
if self.de.ch_is(b',') {
|
||||||
|
self.de.bump();
|
||||||
|
self.de.parse_whitespace();
|
||||||
|
} else if self.de.eof() {
|
||||||
|
return Err(self.de.error(ErrorCode::EOFWhileParsingObject));
|
||||||
|
} else {
|
||||||
|
return Err(self.de.error(ErrorCode::ExpectedObjectCommaOrEnd));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.de.eof() {
|
||||||
|
return Err(self.de.error(ErrorCode::EOFWhileParsingValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self.de.ch_is(b'"') {
|
||||||
|
return Err(self.de.error(ErrorCode::KeyMustBeAString));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_value<V>(&mut self) -> Result<V, Error>
|
||||||
|
where V: de::Deserialize,
|
||||||
|
{
|
||||||
|
try!(self.de.parse_object_colon());
|
||||||
|
|
||||||
|
Ok(try!(de::Deserialize::deserialize(self.de)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(&mut self) -> Result<(), Error> {
|
||||||
|
self.de.parse_whitespace();
|
||||||
|
|
||||||
|
if self.de.ch_is(b']') {
|
||||||
|
self.de.bump();
|
||||||
|
Ok(())
|
||||||
|
} else if self.de.eof() {
|
||||||
|
Err(self.de.error(ErrorCode::EOFWhileParsingList))
|
||||||
|
} else {
|
||||||
|
Err(self.de.error(ErrorCode::TrailingCharacters))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct EnumVisitor<'a, Iter: 'a> {
|
||||||
|
de: &'a mut Deserializer<Iter>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Iter> de::EnumVisitor for EnumVisitor<'a, Iter>
|
||||||
|
where Iter: Iterator<Item=u8>,
|
||||||
|
{
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn visit_unit(&mut self) -> Result<(), Error> {
|
||||||
|
de::Deserialize::deserialize(self.de)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
|
where V: de::EnumSeqVisitor,
|
||||||
|
{
|
||||||
|
self.de.parse_whitespace();
|
||||||
|
|
||||||
|
if self.de.ch_is(b'[') {
|
||||||
|
self.de.bump();
|
||||||
|
visitor.visit(SeqVisitor::new(self.de))
|
||||||
|
} else {
|
||||||
|
Err(self.de.error(ErrorCode::ExpectedSomeValue))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn visit_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
fn expect_struct_field_or_end(&mut self,
|
where V: de::EnumMapVisitor,
|
||||||
fields: &'static [&'static str]
|
{
|
||||||
) -> Result<Option<Option<usize>>, Error> {
|
self.de.parse_whitespace();
|
||||||
let result = match self.state_stack.pop() {
|
|
||||||
Some(State::ObjectStart) => {
|
|
||||||
try!(self.parse_object_start())
|
|
||||||
}
|
|
||||||
Some(State::ObjectCommaOrEnd) => {
|
|
||||||
try!(self.parse_object_comma_or_end())
|
|
||||||
}
|
|
||||||
_ => panic!("invalid internal state"),
|
|
||||||
};
|
|
||||||
|
|
||||||
let s = match result {
|
if self.de.ch_is(b'{') {
|
||||||
Some(s) => s,
|
self.de.bump();
|
||||||
None => { return Ok(None); }
|
visitor.visit(MapVisitor::new(self.de))
|
||||||
};
|
} else {
|
||||||
|
Err(self.de.error(ErrorCode::ExpectedSomeValue))
|
||||||
Ok(Some(fields.iter().position(|field| *field == &s[])))
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decodes a json value from an `Iterator<u8>`.
|
/// Decodes a json value from an `Iterator<u8>`.
|
||||||
pub fn from_iter<
|
pub fn from_iter<I, T>(iter: I) -> Result<T, Error>
|
||||||
Iter: Iterator<Item=u8>,
|
where I: Iterator<Item=u8>,
|
||||||
T: de::Deserialize<Parser<Iter>, Error>
|
T: de::Deserialize
|
||||||
>(iter: Iter) -> Result<T, Error> {
|
{
|
||||||
let mut parser = Parser::new(iter);
|
let mut de = Deserializer::new(iter);
|
||||||
let value = try!(de::Deserialize::deserialize(&mut parser));
|
let value = try!(de::Deserialize::deserialize(&mut de));
|
||||||
|
|
||||||
// Make sure the whole stream has been consumed.
|
// Make sure the whole stream has been consumed.
|
||||||
match parser.next() {
|
try!(de.end());
|
||||||
Some(Ok(_token)) => Err(parser.error(ErrorCode::TrailingCharacters)),
|
Ok(value)
|
||||||
Some(Err(err)) => Err(err),
|
|
||||||
None => Ok(value),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decodes a json value from a string
|
/// Decodes a json value from a string
|
||||||
pub fn from_str<
|
pub fn from_str<'a, T>(s: &'a str) -> Result<T, Error>
|
||||||
'a,
|
where T: de::Deserialize
|
||||||
T: de::Deserialize<Parser<str::Bytes<'a>>, Error>
|
{
|
||||||
>(s: &'a str) -> Result<T, Error> {
|
|
||||||
from_iter(s.bytes())
|
from_iter(s.bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
}
|
|
||||||
|
|||||||
+47
-14
@@ -2,12 +2,11 @@ use std::error;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use de::{Token, TokenKind};
|
use de;
|
||||||
|
|
||||||
/// The errors that can arise while parsing a JSON stream.
|
/// The errors that can arise while parsing a JSON stream.
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
pub enum ErrorCode {
|
pub enum ErrorCode {
|
||||||
ConversionError(Token),
|
|
||||||
EOFWhileParsingList,
|
EOFWhileParsingList,
|
||||||
EOFWhileParsingObject,
|
EOFWhileParsingObject,
|
||||||
EOFWhileParsingString,
|
EOFWhileParsingString,
|
||||||
@@ -24,7 +23,6 @@ pub enum ErrorCode {
|
|||||||
ExpectedObjectCommaOrEnd,
|
ExpectedObjectCommaOrEnd,
|
||||||
ExpectedSomeIdent,
|
ExpectedSomeIdent,
|
||||||
ExpectedSomeValue,
|
ExpectedSomeValue,
|
||||||
ExpectedTokens(Token, &'static [TokenKind]),
|
|
||||||
InvalidEscape,
|
InvalidEscape,
|
||||||
InvalidNumber,
|
InvalidNumber,
|
||||||
InvalidUnicodeCodePoint,
|
InvalidUnicodeCodePoint,
|
||||||
@@ -35,15 +33,16 @@ pub enum ErrorCode {
|
|||||||
NotUtf8,
|
NotUtf8,
|
||||||
TrailingCharacters,
|
TrailingCharacters,
|
||||||
UnexpectedEndOfHexEscape,
|
UnexpectedEndOfHexEscape,
|
||||||
UnexpectedName(Token),
|
|
||||||
UnknownVariant,
|
UnknownVariant,
|
||||||
UnrecognizedHex,
|
UnrecognizedHex,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for ErrorCode {
|
impl fmt::Debug for ErrorCode {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
match *self {
|
match *self {
|
||||||
ErrorCode::ConversionError(ref token) => write!(f, "failed to convert {:?}", token),
|
//ErrorCode::ConversionError(ref token) => write!(f, "failed to convert {}", token),
|
||||||
ErrorCode::EOFWhileParsingList => "EOF While parsing list".fmt(f),
|
ErrorCode::EOFWhileParsingList => "EOF While parsing list".fmt(f),
|
||||||
ErrorCode::EOFWhileParsingObject => "EOF While parsing object".fmt(f),
|
ErrorCode::EOFWhileParsingObject => "EOF While parsing object".fmt(f),
|
||||||
ErrorCode::EOFWhileParsingString => "EOF While parsing string".fmt(f),
|
ErrorCode::EOFWhileParsingString => "EOF While parsing string".fmt(f),
|
||||||
@@ -60,7 +59,7 @@ impl fmt::Debug for ErrorCode {
|
|||||||
ErrorCode::ExpectedObjectCommaOrEnd => "expected `,` or `}`".fmt(f),
|
ErrorCode::ExpectedObjectCommaOrEnd => "expected `,` or `}`".fmt(f),
|
||||||
ErrorCode::ExpectedSomeIdent => "expected ident".fmt(f),
|
ErrorCode::ExpectedSomeIdent => "expected ident".fmt(f),
|
||||||
ErrorCode::ExpectedSomeValue => "expected value".fmt(f),
|
ErrorCode::ExpectedSomeValue => "expected value".fmt(f),
|
||||||
ErrorCode::ExpectedTokens(ref token, tokens) => write!(f, "expected {:?}, found {:?}", tokens, token),
|
//ErrorCode::ExpectedTokens(ref token, tokens) => write!(f, "expected {}, found {}", tokens, token),
|
||||||
ErrorCode::InvalidEscape => "invalid escape".fmt(f),
|
ErrorCode::InvalidEscape => "invalid escape".fmt(f),
|
||||||
ErrorCode::InvalidNumber => "invalid number".fmt(f),
|
ErrorCode::InvalidNumber => "invalid number".fmt(f),
|
||||||
ErrorCode::InvalidUnicodeCodePoint => "invalid unicode code point".fmt(f),
|
ErrorCode::InvalidUnicodeCodePoint => "invalid unicode code point".fmt(f),
|
||||||
@@ -71,7 +70,7 @@ impl fmt::Debug for ErrorCode {
|
|||||||
ErrorCode::NotUtf8 => "contents not utf-8".fmt(f),
|
ErrorCode::NotUtf8 => "contents not utf-8".fmt(f),
|
||||||
ErrorCode::TrailingCharacters => "trailing characters".fmt(f),
|
ErrorCode::TrailingCharacters => "trailing characters".fmt(f),
|
||||||
ErrorCode::UnexpectedEndOfHexEscape => "unexpected end of hex escape".fmt(f),
|
ErrorCode::UnexpectedEndOfHexEscape => "unexpected end of hex escape".fmt(f),
|
||||||
ErrorCode::UnexpectedName(ref name) => write!(f, "unexpected name {:?}", name),
|
//ErrorCode::UnexpectedName(ref name) => write!(f, "unexpected name {}", name),
|
||||||
ErrorCode::UnknownVariant => "unknown variant".fmt(f),
|
ErrorCode::UnknownVariant => "unknown variant".fmt(f),
|
||||||
ErrorCode::UnrecognizedHex => "invalid \\u escape (unrecognized hex)".fmt(f),
|
ErrorCode::UnrecognizedHex => "invalid \\u escape (unrecognized hex)".fmt(f),
|
||||||
}
|
}
|
||||||
@@ -83,39 +82,59 @@ pub enum Error {
|
|||||||
/// msg, line, col
|
/// msg, line, col
|
||||||
SyntaxError(ErrorCode, usize, usize),
|
SyntaxError(ErrorCode, usize, usize),
|
||||||
IoError(io::Error),
|
IoError(io::Error),
|
||||||
|
/*
|
||||||
ExpectedError(String, String),
|
ExpectedError(String, String),
|
||||||
MissingFieldError(String),
|
*/
|
||||||
|
MissingFieldError(&'static str),
|
||||||
|
/*
|
||||||
UnknownVariantError(String),
|
UnknownVariantError(String),
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
impl error::Error for Error {
|
impl error::Error for Error {
|
||||||
fn description(&self) -> &str {
|
fn description(&self) -> &str {
|
||||||
match *self {
|
match *self {
|
||||||
Error::SyntaxError(..) => "syntax error",
|
Error::SyntaxError(..) => "syntax error",
|
||||||
Error::IoError(_) => "Input/Output error",
|
Error::IoError(ref error) => error.description(),
|
||||||
|
/*
|
||||||
Error::ExpectedError(ref expected, _) => &expected,
|
Error::ExpectedError(ref expected, _) => &expected,
|
||||||
|
*/
|
||||||
Error::MissingFieldError(_) => "missing field",
|
Error::MissingFieldError(_) => "missing field",
|
||||||
|
/*
|
||||||
Error::UnknownVariantError(_) => "unknown variant",
|
Error::UnknownVariantError(_) => "unknown variant",
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cause(&self) -> Option<&error::Error> {
|
||||||
|
match *self {
|
||||||
|
Error::IoError(ref error) => Some(error),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
Error::SyntaxError(ref code, line, col) => {
|
Error::SyntaxError(ref code, line, col) => {
|
||||||
write!(fmt, "{:?} at line {:?} column {:?}", code, line, col)
|
write!(fmt, "{:?} at line {} column {}", code, line, col)
|
||||||
}
|
}
|
||||||
Error::IoError(ref error) => fmt::Display::fmt(error, fmt),
|
Error::IoError(ref error) => fmt::Display::fmt(error, fmt),
|
||||||
|
/*
|
||||||
Error::ExpectedError(ref expected, ref found) => {
|
Error::ExpectedError(ref expected, ref found) => {
|
||||||
write!(fmt, "expected {:?}, found {:?}", expected, found)
|
Some(format!("expected {}, found {}", expected, found))
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
Error::MissingFieldError(ref field) => {
|
Error::MissingFieldError(ref field) => {
|
||||||
write!(fmt, "missing field {:?}", field)
|
write!(fmt, "missing field {}", field)
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
Error::UnknownVariantError(ref variant) => {
|
Error::UnknownVariantError(ref variant) => {
|
||||||
write!(fmt, "unknown variant {:?}", variant)
|
Some(format!("unknown variant {}", variant))
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,3 +144,17 @@ impl error::FromError<io::Error> for Error {
|
|||||||
Error::IoError(error)
|
Error::IoError(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl de::Error for Error {
|
||||||
|
fn syntax_error() -> Error {
|
||||||
|
Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end_of_stream_error() -> Error {
|
||||||
|
Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn missing_field_error(field: &'static str) -> Error {
|
||||||
|
Error::MissingFieldError(field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+7
-305
@@ -1,317 +1,19 @@
|
|||||||
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
pub use self::de::{Deserializer, from_str};
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
// Rust JSON serialization library
|
|
||||||
// Copyright (c) 2011 Google Inc.
|
|
||||||
|
|
||||||
#![forbid(non_camel_case_types)]
|
|
||||||
#![allow(missing_docs)]
|
|
||||||
|
|
||||||
/*!
|
|
||||||
JSON parsing and serialization
|
|
||||||
|
|
||||||
# What is JSON?
|
|
||||||
|
|
||||||
JSON (JavaScript Object Notation) is a way to write data in Javascript.
|
|
||||||
Like XML it allows one to serialize structured data in a text format that can be read by humans
|
|
||||||
easily.
|
|
||||||
Its native compatibility with JavaScript and its simple syntax make it used widely.
|
|
||||||
|
|
||||||
Json data are serialized in a form of "key":"value".
|
|
||||||
Data types that can be serialized are JavaScript types :
|
|
||||||
boolean (`true` or `false`), number (`f64`), string, array, object, null.
|
|
||||||
An object is a series of string keys mapping to values, in `"key": value` format.
|
|
||||||
Arrays are enclosed in square brackets (&[ ... ]) and objects in curly brackets ({ ... }).
|
|
||||||
A simple JSON document serializing a person, his/her age, address and phone numbers could look like:
|
|
||||||
|
|
||||||
```ignore
|
|
||||||
{
|
|
||||||
"FirstName": "John",
|
|
||||||
"LastName": "Doe",
|
|
||||||
"Age": 43,
|
|
||||||
"Address": {
|
|
||||||
"Street": "Downing Street 10",
|
|
||||||
"City": "London",
|
|
||||||
"Country": "Great Britain"
|
|
||||||
},
|
|
||||||
"PhoneNumbers": [
|
|
||||||
"+44 1234567",
|
|
||||||
"+44 2345678"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
# Rust Type-based Serializing and Deserializing
|
|
||||||
|
|
||||||
Rust provides a mechanism for low boilerplate serializing and deserializing
|
|
||||||
of values to and from JSON via the serialization API.
|
|
||||||
To be able to serialize a piece of data, it must implement the `serde::Serialize` trait.
|
|
||||||
To be able to deserialize a piece of data, it must implement the `serde::Deserialize` trait.
|
|
||||||
The Rust compiler provides an annotation to automatically generate
|
|
||||||
the code for these traits: `#[derive_serialize]` and `#[derive_deserialize]`.
|
|
||||||
|
|
||||||
To serialize using `Serialize`:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#![feature(plugin)]
|
|
||||||
#![plugin(serde_macros)]
|
|
||||||
|
|
||||||
extern crate serde;
|
|
||||||
|
|
||||||
use std::io::WriteExt;
|
|
||||||
use serde::json;
|
|
||||||
use serde::Serialize;
|
|
||||||
|
|
||||||
#[derive_serialize]
|
|
||||||
pub struct TestStruct {
|
|
||||||
data_str: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let to_serialize_object = TestStruct {
|
|
||||||
data_str: "example of string to serialize".to_string()
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut wr = Vec::new();
|
|
||||||
{
|
|
||||||
let mut serializer = json::Serializer::new(wr.by_ref());
|
|
||||||
match to_serialize_object.serialize(&mut serializer) {
|
|
||||||
Ok(()) => (),
|
|
||||||
Err(e) => panic!("json serialization error: {:?}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Two wrapper functions are provided to serialize a `Serialize` object
|
|
||||||
into a string (String) or buffer (~[u8]): `json::to_string(value)` and
|
|
||||||
`json::to_vec(value)`.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use serde::json;
|
|
||||||
let to_serialize_object = "example of string to serialize";
|
|
||||||
let serialized_str: String = json::to_string(&to_serialize_object).unwrap();
|
|
||||||
```
|
|
||||||
|
|
||||||
JSON API provide an enum `json::Value` and a trait `ToJson` to serialize
|
|
||||||
object. The trait `ToJson` serialize object into a container `json::Value` and
|
|
||||||
the API provide writer to serialize them into a stream or a string ...
|
|
||||||
|
|
||||||
When using `ToJson` the `Serialize` trait implementation is not mandatory.
|
|
||||||
|
|
||||||
A basic `ToJson` example using a BTreeMap of attribute name / attribute value:
|
|
||||||
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#![feature(plugin)]
|
|
||||||
#![plugin(serde_macros)]
|
|
||||||
|
|
||||||
extern crate serde;
|
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
|
||||||
use serde::json::{ToJson, Value};
|
|
||||||
|
|
||||||
pub struct MyStruct {
|
|
||||||
attr1: u8,
|
|
||||||
attr2: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToJson for MyStruct {
|
|
||||||
fn to_json( &self ) -> Value {
|
|
||||||
let mut d = BTreeMap::new();
|
|
||||||
d.insert("attr1".to_string(), self.attr1.to_json());
|
|
||||||
d.insert("attr2".to_string(), self.attr2.to_json());
|
|
||||||
d.to_json()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let test = MyStruct {attr1: 1, attr2:"test".to_string()};
|
|
||||||
let json: Value = test.to_json();
|
|
||||||
let json_str: String = json.to_string();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Or you can use the helper type `ObjectBuilder`:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#![feature(plugin)]
|
|
||||||
#![plugin(serde_macros)]
|
|
||||||
|
|
||||||
extern crate serde;
|
|
||||||
|
|
||||||
use serde::json::{ObjectBuilder, ToJson, Value};
|
|
||||||
|
|
||||||
pub struct MyStruct {
|
|
||||||
attr1: u8,
|
|
||||||
attr2: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToJson for MyStruct {
|
|
||||||
fn to_json( &self ) -> Value {
|
|
||||||
ObjectBuilder::new()
|
|
||||||
.insert("attr1".to_string(), &self.attr1)
|
|
||||||
.insert("attr2".to_string(), &self.attr2)
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let test = MyStruct {attr1: 1, attr2:"test".to_string()};
|
|
||||||
let json: Value = test.to_json();
|
|
||||||
let json_str: String = json.to_string();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
To deserialize a JSON string using `Deserialize` trait:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#![feature(plugin)]
|
|
||||||
#![plugin(serde_macros)]
|
|
||||||
|
|
||||||
extern crate serde;
|
|
||||||
|
|
||||||
use serde::json;
|
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
#[derive_deserialize]
|
|
||||||
pub struct MyStruct {
|
|
||||||
attr1: u8,
|
|
||||||
attr2: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let json_str_to_deserialize = "{ \"attr1\": 1, \"attr2\": \"toto\" }";
|
|
||||||
let mut parser = json::Parser::new(json_str_to_deserialize.bytes());
|
|
||||||
let deserialized_object: MyStruct = match Deserialize::deserialize(&mut parser) {
|
|
||||||
Ok(v) => v,
|
|
||||||
Err(e) => panic!("Decoding error: {:?}", e)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
# Examples of use
|
|
||||||
|
|
||||||
## Using Autoserialization
|
|
||||||
|
|
||||||
Create a struct called `TestStruct1` and serialize and deserialize it to and from JSON
|
|
||||||
using the serialization API, using the derived serialization code.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#![feature(plugin)]
|
|
||||||
#![plugin(serde_macros)]
|
|
||||||
|
|
||||||
extern crate serde;
|
|
||||||
|
|
||||||
use serde::json;
|
|
||||||
|
|
||||||
#[derive_serialize]
|
|
||||||
#[derive_deserialize]
|
|
||||||
pub struct TestStruct1 {
|
|
||||||
data_int: u8,
|
|
||||||
data_str: String,
|
|
||||||
data_vector: Vec<u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
// To serialize use the `json::to_string` to serialize an object in a string.
|
|
||||||
// It calls the generated `Serialize` impl.
|
|
||||||
fn main() {
|
|
||||||
let to_serialize_object = TestStruct1 {
|
|
||||||
data_int: 1,
|
|
||||||
data_str: "toto".to_string(),
|
|
||||||
data_vector: vec![2,3,4,5]
|
|
||||||
};
|
|
||||||
let serialized_str: String = json::to_string(&to_serialize_object).unwrap();
|
|
||||||
|
|
||||||
// To deserialize use the `json::from_str` function.
|
|
||||||
|
|
||||||
let deserialized_object: TestStruct1 = match json::from_str(&serialized_str) {
|
|
||||||
Ok(deserialized_object) => deserialized_object,
|
|
||||||
Err(e) => panic!("json deserialization error: {:?}", e),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Using `ToJson`
|
|
||||||
|
|
||||||
This example use the ToJson impl to deserialize the JSON string.
|
|
||||||
Example of `ToJson` trait implementation for TestStruct1.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
#![feature(plugin)]
|
|
||||||
#![plugin(serde_macros)]
|
|
||||||
|
|
||||||
extern crate serde;
|
|
||||||
|
|
||||||
use serde::json::ToJson;
|
|
||||||
use serde::json;
|
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
#[derive_serialize] // generate Serialize impl
|
|
||||||
#[derive_deserialize] // generate Deserialize impl
|
|
||||||
pub struct TestStruct1 {
|
|
||||||
data_int: u8,
|
|
||||||
data_str: String,
|
|
||||||
data_vector: Vec<u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToJson for TestStruct1 {
|
|
||||||
fn to_json( &self ) -> json::Value {
|
|
||||||
json::builder::ObjectBuilder::new()
|
|
||||||
.insert("data_int".to_string(), &self.data_int)
|
|
||||||
.insert("data_str".to_string(), &self.data_str)
|
|
||||||
.insert("data_vector".to_string(), &self.data_vector)
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
// Serialization using our impl of to_json
|
|
||||||
|
|
||||||
let test: TestStruct1 = TestStruct1 {
|
|
||||||
data_int: 1,
|
|
||||||
data_str: "toto".to_string(),
|
|
||||||
data_vector: vec![2,3,4,5],
|
|
||||||
};
|
|
||||||
let json: json::Value = test.to_json();
|
|
||||||
let json_str: String = json.to_string();
|
|
||||||
|
|
||||||
// Deserialize like before.
|
|
||||||
|
|
||||||
let mut parser = json::Parser::new(json_str.bytes());
|
|
||||||
let deserialized: TestStruct1 = Deserialize::deserialize(&mut parser).unwrap();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
pub use self::builder::{ArrayBuilder, ObjectBuilder};
|
|
||||||
pub use self::de::{
|
|
||||||
Parser,
|
|
||||||
from_str,
|
|
||||||
};
|
|
||||||
pub use self::error::{Error, ErrorCode};
|
pub use self::error::{Error, ErrorCode};
|
||||||
pub use self::ser::{
|
pub use self::ser::{
|
||||||
Serializer,
|
Serializer,
|
||||||
PrettySerializer,
|
|
||||||
to_writer,
|
to_writer,
|
||||||
|
to_writer_pretty,
|
||||||
to_vec,
|
to_vec,
|
||||||
|
to_vec_pretty,
|
||||||
to_string,
|
to_string,
|
||||||
to_pretty_writer,
|
to_string_pretty,
|
||||||
to_pretty_vec,
|
escape_str,
|
||||||
to_pretty_string,
|
|
||||||
};
|
};
|
||||||
pub use self::value::{Value, ToJson, from_json};
|
pub use self::value::{Value, to_value, from_value};
|
||||||
|
|
||||||
pub mod builder;
|
pub mod builder;
|
||||||
pub mod de;
|
pub mod de;
|
||||||
|
pub mod error;
|
||||||
pub mod ser;
|
pub mod ser;
|
||||||
pub mod value;
|
pub mod value;
|
||||||
pub mod error;
|
|
||||||
|
|||||||
+337
-516
@@ -1,498 +1,310 @@
|
|||||||
use std::f32;
|
use std::{f32, f64};
|
||||||
use std::f64;
|
|
||||||
use std::num::{Float, FpCategory};
|
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::num::{Float, FpCategory};
|
||||||
use std::string::FromUtf8Error;
|
use std::string::FromUtf8Error;
|
||||||
|
|
||||||
use ser;
|
use ser;
|
||||||
|
|
||||||
/// A structure for implementing serialization to JSON.
|
/// A structure for implementing serialization to JSON.
|
||||||
pub struct Serializer<W> {
|
pub struct Serializer<W> {
|
||||||
wr: W,
|
writer: W,
|
||||||
first: bool,
|
format: Format,
|
||||||
|
current_indent: usize,
|
||||||
|
indent: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, PartialEq)]
|
||||||
|
enum Format {
|
||||||
|
Compact,
|
||||||
|
Pretty,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W: io::Write> Serializer<W> {
|
impl<W: io::Write> Serializer<W> {
|
||||||
/// Creates a new JSON serializer whose output will be written to the writer
|
/// Creates a new JSON visitr whose output will be written to the writer
|
||||||
/// specified.
|
/// specified.
|
||||||
pub fn new(wr: W) -> Serializer<W> {
|
#[inline]
|
||||||
|
pub fn new(writer: W) -> Serializer<W> {
|
||||||
Serializer {
|
Serializer {
|
||||||
wr: wr,
|
writer: writer,
|
||||||
first: true,
|
format: Format::Compact,
|
||||||
}
|
current_indent: 0,
|
||||||
}
|
|
||||||
|
|
||||||
/// Unwrap the io::Write from the Serializer.
|
|
||||||
pub fn unwrap(self) -> W {
|
|
||||||
self.wr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<W: io::Write> ser::Serializer<io::Error> for Serializer<W> {
|
|
||||||
#[inline]
|
|
||||||
fn serialize_null(&mut self) -> io::Result<()> {
|
|
||||||
self.wr.write_all(b"null")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_bool(&mut self, value: bool) -> io::Result<()> {
|
|
||||||
if value {
|
|
||||||
self.wr.write_all(b"true")
|
|
||||||
} else {
|
|
||||||
self.wr.write_all(b"false")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_isize(&mut self, value: isize) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_i8(&mut self, value: i8) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_i16(&mut self, value: i16) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_i32(&mut self, value: i32) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_i64(&mut self, value: i64) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_usize(&mut self, value: usize) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_u8(&mut self, value: u8) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_u16(&mut self, value: u16) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_u32(&mut self, value: u32) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_u64(&mut self, value: u64) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_f32(&mut self, value: f32) -> io::Result<()> {
|
|
||||||
fmt_f32_or_null(&mut self.wr, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_f64(&mut self, value: f64) -> io::Result<()> {
|
|
||||||
fmt_f64_or_null(&mut self.wr, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_char(&mut self, value: char) -> io::Result<()> {
|
|
||||||
escape_char(&mut self.wr, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_str(&mut self, value: &str) -> io::Result<()> {
|
|
||||||
escape_str(&mut self.wr, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_tuple_start(&mut self, _len: usize) -> io::Result<()> {
|
|
||||||
self.first = true;
|
|
||||||
write!(&mut self.wr, "[")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_tuple_elt<
|
|
||||||
T: ser::Serialize<Serializer<W>, io::Error>
|
|
||||||
>(&mut self, value: &T) -> io::Result<()> {
|
|
||||||
if self.first {
|
|
||||||
self.first = false;
|
|
||||||
} else {
|
|
||||||
try!(write!(&mut self.wr, ","));
|
|
||||||
}
|
|
||||||
value.serialize(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_tuple_end(&mut self) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "]")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_struct_start(&mut self, _name: &str, _len: usize) -> io::Result<()> {
|
|
||||||
self.first = true;
|
|
||||||
write!(&mut self.wr, "{{")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_struct_elt<
|
|
||||||
T: ser::Serialize<Serializer<W>, io::Error>
|
|
||||||
>(&mut self, name: &str, value: &T) -> io::Result<()> {
|
|
||||||
use ser::Serialize;
|
|
||||||
|
|
||||||
if self.first {
|
|
||||||
self.first = false;
|
|
||||||
} else {
|
|
||||||
try!(write!(&mut self.wr, ","));
|
|
||||||
}
|
|
||||||
try!(name.serialize(self));
|
|
||||||
try!(write!(&mut self.wr, ":"));
|
|
||||||
value.serialize(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_struct_end(&mut self) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "}}")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_enum_start(&mut self, _name: &str, variant: &str, _len: usize) -> io::Result<()> {
|
|
||||||
self.first = true;
|
|
||||||
try!(write!(&mut self.wr, "{{"));
|
|
||||||
try!(self.serialize_str(variant));
|
|
||||||
write!(&mut self.wr, ":[")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_enum_elt<
|
|
||||||
T: ser::Serialize<Serializer<W>, io::Error>
|
|
||||||
>(&mut self, value: &T) -> io::Result<()> {
|
|
||||||
if self.first {
|
|
||||||
self.first = false;
|
|
||||||
} else {
|
|
||||||
try!(write!(&mut self.wr, ","));
|
|
||||||
}
|
|
||||||
value.serialize(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_enum_end(&mut self) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "]}}")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_option<
|
|
||||||
T: ser::Serialize<Serializer<W>, io::Error>
|
|
||||||
>(&mut self, v: &Option<T>) -> io::Result<()> {
|
|
||||||
match *v {
|
|
||||||
Some(ref v) => {
|
|
||||||
v.serialize(self)
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
self.serialize_null()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_seq<
|
|
||||||
T: ser::Serialize<Serializer<W>, io::Error>,
|
|
||||||
Iter: Iterator<Item=T>
|
|
||||||
>(&mut self, iter: Iter) -> io::Result<()> {
|
|
||||||
try!(write!(&mut self.wr, "["));
|
|
||||||
let mut first = true;
|
|
||||||
for elt in iter {
|
|
||||||
if first {
|
|
||||||
first = false;
|
|
||||||
} else {
|
|
||||||
try!(write!(&mut self.wr, ","));
|
|
||||||
}
|
|
||||||
try!(elt.serialize(self));
|
|
||||||
|
|
||||||
}
|
|
||||||
write!(&mut self.wr, "]")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_map<
|
|
||||||
K: ser::Serialize<Serializer<W>, io::Error>,
|
|
||||||
V: ser::Serialize<Serializer<W>, io::Error>,
|
|
||||||
Iter: Iterator<Item=(K, V)>
|
|
||||||
>(&mut self, iter: Iter) -> io::Result<()> {
|
|
||||||
try!(write!(&mut self.wr, "{{"));
|
|
||||||
let mut first = true;
|
|
||||||
for (key, value) in iter {
|
|
||||||
if first {
|
|
||||||
first = false;
|
|
||||||
} else {
|
|
||||||
try!(write!(&mut self.wr, ","));
|
|
||||||
}
|
|
||||||
try!(key.serialize(self));
|
|
||||||
try!(write!(&mut self.wr, ":"));
|
|
||||||
try!(value.serialize(self));
|
|
||||||
}
|
|
||||||
write!(&mut self.wr, "}}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Another serializer for JSON, but prints out human-readable JSON instead of
|
|
||||||
/// compact data
|
|
||||||
pub struct PrettySerializer<W> {
|
|
||||||
wr: W,
|
|
||||||
indent: usize,
|
|
||||||
first: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<W: io::Write> PrettySerializer<W> {
|
|
||||||
/// Creates a new serializer whose output will be written to the specified writer
|
|
||||||
pub fn new(wr: W) -> PrettySerializer<W> {
|
|
||||||
PrettySerializer {
|
|
||||||
wr: wr,
|
|
||||||
indent: 0,
|
indent: 0,
|
||||||
first: true,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unwrap the io::Write from the Serializer.
|
/// Creates a new JSON visitr whose output will be written to the writer
|
||||||
pub fn unwrap(self) -> W {
|
/// specified.
|
||||||
self.wr
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize_sep(&mut self) -> io::Result<()> {
|
pub fn new_pretty(writer: W) -> Serializer<W> {
|
||||||
if self.first {
|
Serializer {
|
||||||
self.first = false;
|
writer: writer,
|
||||||
self.indent += 2;
|
format: Format::Pretty,
|
||||||
try!(write!(&mut self.wr, "\n"));
|
current_indent: 0,
|
||||||
} else {
|
indent: 2,
|
||||||
try!(write!(&mut self.wr, ",\n"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spaces(&mut self.wr, self.indent)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Unwrap the `Writer` from the `Serializer`.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize_end(&mut self, s: &str) -> io::Result<()> {
|
pub fn into_inner(self) -> W {
|
||||||
if !self.first {
|
self.writer
|
||||||
try!(write!(&mut self.wr, "\n"));
|
|
||||||
self.indent -= 2;
|
|
||||||
try!(spaces(&mut self.wr, self.indent));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.first = false;
|
|
||||||
|
|
||||||
write!(&mut self.wr, "{}", s)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W: io::Write> ser::Serializer<io::Error> for PrettySerializer<W> {
|
impl<W: io::Write> ser::Serializer for Serializer<W> {
|
||||||
#[inline]
|
type Value = ();
|
||||||
fn serialize_null(&mut self) -> io::Result<()> {
|
type Error = io::Error;
|
||||||
write!(&mut self.wr, "null")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize_bool(&mut self, v: bool) -> io::Result<()> {
|
fn visit<T>(&mut self, value: &T) -> io::Result<()>
|
||||||
if v {
|
where T: ser::Serialize,
|
||||||
self.wr.write_all(b"true")
|
{
|
||||||
} else {
|
value.visit(&mut Visitor {
|
||||||
self.wr.write_all(b"false")
|
writer: &mut self.writer,
|
||||||
}
|
format: self.format,
|
||||||
|
current_indent: self.current_indent,
|
||||||
|
indent: self.indent,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
struct Visitor<'a, W: 'a> {
|
||||||
fn serialize_isize(&mut self, value: isize) -> io::Result<()> {
|
writer: &'a mut W,
|
||||||
write!(&mut self.wr, "{}", value)
|
format: Format,
|
||||||
}
|
current_indent: usize,
|
||||||
|
indent: usize,
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
impl<'a, W> Visitor<'a, W> where W: io::Write, {
|
||||||
fn serialize_i8(&mut self, value: i8) -> io::Result<()> {
|
fn serialize_sep(&mut self, first: bool) -> io::Result<()> {
|
||||||
write!(&mut self.wr, "{}", value)
|
match self.format {
|
||||||
}
|
Format::Compact => {
|
||||||
|
if first {
|
||||||
#[inline]
|
Ok(())
|
||||||
fn serialize_i16(&mut self, value: i16) -> io::Result<()> {
|
} else {
|
||||||
write!(&mut self.wr, "{}", value)
|
self.writer.write_all(b",")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_i32(&mut self, value: i32) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_i64(&mut self, value: i64) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_usize(&mut self, value: usize) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_u8(&mut self, value: u8) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_u16(&mut self, value: u16) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_u32(&mut self, value: u32) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_u64(&mut self, value: u64) -> io::Result<()> {
|
|
||||||
write!(&mut self.wr, "{}", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_f32(&mut self, value: f32) -> io::Result<()> {
|
|
||||||
fmt_f32_or_null(&mut self.wr, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_f64(&mut self, value: f64) -> io::Result<()> {
|
|
||||||
fmt_f64_or_null(&mut self.wr, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_char(&mut self, value: char) -> io::Result<()> {
|
|
||||||
escape_char(&mut self.wr, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_str(&mut self, value: &str) -> io::Result<()> {
|
|
||||||
escape_str(&mut self.wr, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_tuple_start(&mut self, _len: usize) -> io::Result<()> {
|
|
||||||
self.first = true;
|
|
||||||
self.wr.write_all(b"[")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_tuple_elt<
|
|
||||||
T: ser::Serialize<PrettySerializer<W>, io::Error>
|
|
||||||
>(&mut self, value: &T) -> io::Result<()> {
|
|
||||||
try!(self.serialize_sep());
|
|
||||||
value.serialize(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_tuple_end(&mut self) -> io::Result<()> {
|
|
||||||
self.serialize_end("]")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_struct_start(&mut self, _name: &str, _len: usize) -> io::Result<()> {
|
|
||||||
self.first = true;
|
|
||||||
self.wr.write_all(b"{")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_struct_elt<
|
|
||||||
T: ser::Serialize<PrettySerializer<W>, io::Error>
|
|
||||||
>(&mut self, name: &str, value: &T) -> io::Result<()> {
|
|
||||||
try!(self.serialize_sep());
|
|
||||||
try!(self.serialize_str(name));
|
|
||||||
try!(self.wr.write_all(b": "));
|
|
||||||
value.serialize(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_struct_end(&mut self) -> io::Result<()> {
|
|
||||||
self.serialize_end("}")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_enum_start(&mut self, _name: &str, variant: &str, _len: usize) -> io::Result<()> {
|
|
||||||
self.first = true;
|
|
||||||
try!(self.wr.write_all(b"{"));
|
|
||||||
try!(self.serialize_sep());
|
|
||||||
try!(self.serialize_str(variant));
|
|
||||||
self.first = true;
|
|
||||||
self.wr.write_all(b": [")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_enum_elt<
|
|
||||||
T: ser::Serialize<PrettySerializer<W>, io::Error>
|
|
||||||
>(&mut self, value: &T) -> io::Result<()> {
|
|
||||||
try!(self.serialize_sep());
|
|
||||||
value.serialize(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_enum_end(&mut self) -> io::Result<()> {
|
|
||||||
try!(self.serialize_tuple_end());
|
|
||||||
self.serialize_struct_end()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_option<
|
|
||||||
T: ser::Serialize<PrettySerializer<W>, io::Error>
|
|
||||||
>(&mut self, v: &Option<T>) -> io::Result<()> {
|
|
||||||
match *v {
|
|
||||||
Some(ref v) => {
|
|
||||||
v.serialize(self)
|
|
||||||
}
|
}
|
||||||
None => {
|
Format::Pretty => {
|
||||||
self.serialize_null()
|
if first {
|
||||||
|
self.current_indent += self.indent;
|
||||||
|
try!(self.writer.write_all(b"\n"));
|
||||||
|
} else {
|
||||||
|
try!(self.writer.write_all(b",\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
spaces(&mut self.writer, self.current_indent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn serialize_colon(&mut self) -> io::Result<()> {
|
||||||
fn serialize_seq<
|
match self.format {
|
||||||
T: ser::Serialize<PrettySerializer<W>, io::Error>,
|
Format::Compact => self.writer.write_all(b":"),
|
||||||
Iter: Iterator<Item=T>
|
Format::Pretty => self.writer.write_all(b": "),
|
||||||
>(&mut self, iter: Iter) -> io::Result<()> {
|
|
||||||
try!(self.wr.write_all(b"["));
|
|
||||||
|
|
||||||
self.first = true;
|
|
||||||
for elt in iter {
|
|
||||||
try!(self.serialize_sep());
|
|
||||||
try!(elt.serialize(self));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.serialize_end("]")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn serialize_end(&mut self, current_indent: usize, s: &[u8]) -> io::Result<()> {
|
||||||
fn serialize_map<
|
if self.format == Format::Pretty && current_indent != self.current_indent {
|
||||||
K: ser::Serialize<PrettySerializer<W>, io::Error>,
|
self.current_indent -= self.indent;
|
||||||
V: ser::Serialize<PrettySerializer<W>, io::Error>,
|
try!(self.writer.write(b"\n"));
|
||||||
Iter: Iterator<Item=(K, V)>
|
try!(spaces(&mut self.writer, self.current_indent));
|
||||||
>(&mut self, iter: Iter) -> io::Result<()> {
|
|
||||||
try!(self.wr.write_all(b"{"));
|
|
||||||
|
|
||||||
self.first = true;
|
|
||||||
for (key, value) in iter {
|
|
||||||
try!(self.serialize_sep());
|
|
||||||
try!(key.serialize(self));
|
|
||||||
try!(self.wr.write_all(b": "));
|
|
||||||
try!(value.serialize(self));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.serialize_end("}")
|
self.writer.write_all(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn escape_bytes<W>(wr: &mut W, bytes: &[u8]) -> io::Result<()>
|
impl<'a, W> ser::Visitor for Visitor<'a, W> where W: io::Write, {
|
||||||
|
type Value = ();
|
||||||
|
type Error = io::Error;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_bool(&mut self, value: bool) -> io::Result<()> {
|
||||||
|
if value {
|
||||||
|
self.writer.write_all(b"true")
|
||||||
|
} else {
|
||||||
|
self.writer.write_all(b"false")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_isize(&mut self, value: isize) -> io::Result<()> {
|
||||||
|
write!(self.writer, "{}", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_i8(&mut self, value: i8) -> io::Result<()> {
|
||||||
|
write!(self.writer, "{}", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_i16(&mut self, value: i16) -> io::Result<()> {
|
||||||
|
write!(self.writer, "{}", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_i32(&mut self, value: i32) -> io::Result<()> {
|
||||||
|
write!(self.writer, "{}", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_i64(&mut self, value: i64) -> io::Result<()> {
|
||||||
|
write!(self.writer, "{}", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_usize(&mut self, value: usize) -> io::Result<()> {
|
||||||
|
write!(self.writer, "{}", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_u8(&mut self, value: u8) -> io::Result<()> {
|
||||||
|
write!(self.writer, "{}", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_u16(&mut self, value: u16) -> io::Result<()> {
|
||||||
|
write!(self.writer, "{}", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_u32(&mut self, value: u32) -> io::Result<()> {
|
||||||
|
write!(self.writer, "{}", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_u64(&mut self, value: u64) -> io::Result<()> {
|
||||||
|
write!(self.writer, "{}", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_f32(&mut self, value: f32) -> io::Result<()> {
|
||||||
|
fmt_f32_or_null(self.writer, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_f64(&mut self, value: f64) -> io::Result<()> {
|
||||||
|
fmt_f64_or_null(self.writer, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_char(&mut self, value: char) -> io::Result<()> {
|
||||||
|
escape_char(self.writer, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_str(&mut self, value: &str) -> io::Result<()> {
|
||||||
|
escape_str(self.writer, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_none(&mut self) -> io::Result<()> {
|
||||||
|
self.visit_unit()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_some<V>(&mut self, value: V) -> io::Result<()>
|
||||||
|
where V: ser::Serialize
|
||||||
|
{
|
||||||
|
value.visit(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_unit(&mut self) -> io::Result<()> {
|
||||||
|
self.writer.write_all(b"null")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_enum_unit(&mut self, _name: &str, variant: &str) -> io::Result<()> {
|
||||||
|
let current_indent = self.current_indent;
|
||||||
|
|
||||||
|
try!(self.writer.write_all(b"{"));
|
||||||
|
try!(self.serialize_sep(true));
|
||||||
|
try!(self.visit_str(variant));
|
||||||
|
try!(self.serialize_colon());
|
||||||
|
try!(self.writer.write_all(b"[]"));
|
||||||
|
self.serialize_end(current_indent, b"}")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_seq<V>(&mut self, mut visitor: V) -> io::Result<()>
|
||||||
|
where V: ser::SeqVisitor,
|
||||||
|
{
|
||||||
|
let current_indent = self.current_indent;
|
||||||
|
|
||||||
|
try!(self.writer.write_all(b"["));
|
||||||
|
|
||||||
|
while let Some(()) = try!(visitor.visit(self)) { }
|
||||||
|
|
||||||
|
self.serialize_end(current_indent, b"]")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_enum_seq<V>(&mut self, _name: &str, variant: &str, visitor: V) -> io::Result<()>
|
||||||
|
where V: ser::SeqVisitor,
|
||||||
|
{
|
||||||
|
let current_indent = self.current_indent;
|
||||||
|
|
||||||
|
try!(self.writer.write_all(b"{"));
|
||||||
|
try!(self.serialize_sep(true));
|
||||||
|
try!(self.visit_str(variant));
|
||||||
|
try!(self.serialize_colon());
|
||||||
|
try!(self.visit_seq(visitor));
|
||||||
|
self.serialize_end(current_indent, b"}")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_seq_elt<T>(&mut self, first: bool, value: T) -> io::Result<()>
|
||||||
|
where T: ser::Serialize,
|
||||||
|
{
|
||||||
|
try!(self.serialize_sep(first));
|
||||||
|
|
||||||
|
value.visit(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_map<V>(&mut self, mut visitor: V) -> io::Result<()>
|
||||||
|
where V: ser::MapVisitor,
|
||||||
|
{
|
||||||
|
let current_indent = self.current_indent;
|
||||||
|
|
||||||
|
try!(self.writer.write_all(b"{"));
|
||||||
|
|
||||||
|
while let Some(()) = try!(visitor.visit(self)) { }
|
||||||
|
|
||||||
|
self.serialize_end(current_indent, b"}")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_enum_map<V>(&mut self, _name: &str, variant: &str, visitor: V) -> io::Result<()>
|
||||||
|
where V: ser::MapVisitor,
|
||||||
|
{
|
||||||
|
let current_indent = self.current_indent;
|
||||||
|
|
||||||
|
try!(self.writer.write_all(b"{"));
|
||||||
|
try!(self.serialize_sep(true));
|
||||||
|
try!(self.visit_str(variant));
|
||||||
|
try!(self.serialize_colon());
|
||||||
|
try!(self.visit_map(visitor));
|
||||||
|
self.serialize_end(current_indent, b"}")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_map_elt<K, V>(&mut self, first: bool, key: K, value: V) -> io::Result<()>
|
||||||
|
where K: ser::Serialize,
|
||||||
|
V: ser::Serialize,
|
||||||
|
{
|
||||||
|
try!(self.serialize_sep(first));
|
||||||
|
try!(key.visit(self));
|
||||||
|
try!(self.serialize_colon());
|
||||||
|
value.visit(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn escape_bytes<W>(wr: &mut W, bytes: &[u8]) -> io::Result<()>
|
||||||
where W: io::Write
|
where W: io::Write
|
||||||
{
|
{
|
||||||
try!(wr.write_all(b"\""));
|
try!(wr.write_all(b"\""));
|
||||||
@@ -524,15 +336,18 @@ fn escape_bytes<W>(wr: &mut W, bytes: &[u8]) -> io::Result<()>
|
|||||||
try!(wr.write_all(&bytes[start..]));
|
try!(wr.write_all(&bytes[start..]));
|
||||||
}
|
}
|
||||||
|
|
||||||
wr.write_all(b"\"")
|
try!(wr.write_all(b"\""));
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn escape_str<W>(wr: &mut W, value: &str) -> io::Result<()>
|
pub fn escape_str<W>(wr: &mut W, value: &str) -> io::Result<()>
|
||||||
where W: io::Write
|
where W: io::Write
|
||||||
{
|
{
|
||||||
escape_bytes(wr, value.as_bytes())
|
escape_bytes(wr, value.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn escape_char<W>(wr: &mut W, value: char) -> io::Result<()>
|
fn escape_char<W>(wr: &mut W, value: char) -> io::Result<()>
|
||||||
where W: io::Write
|
where W: io::Write
|
||||||
{
|
{
|
||||||
@@ -559,9 +374,75 @@ fn fmt_f64_or_null<W>(wr: &mut W, value: f64) -> io::Result<()>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spaces<W: io::Write>(wr: &mut W, mut n: usize) -> io::Result<()> {
|
/// Encode the specified struct into a json `[u8]` writer.
|
||||||
|
#[inline]
|
||||||
|
pub fn to_writer<W, T>(writer: &mut W, value: &T) -> io::Result<()>
|
||||||
|
where W: io::Write,
|
||||||
|
T: ser::Serialize,
|
||||||
|
{
|
||||||
|
let mut ser = Serializer::new(writer);
|
||||||
|
try!(ser::Serializer::visit(&mut ser, value));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Encode the specified struct into a json `[u8]` writer.
|
||||||
|
#[inline]
|
||||||
|
pub fn to_writer_pretty<W, T>(writer: &mut W, value: &T) -> io::Result<()>
|
||||||
|
where W: io::Write,
|
||||||
|
T: ser::Serialize,
|
||||||
|
{
|
||||||
|
let mut ser = Serializer::new_pretty(writer);
|
||||||
|
try!(ser::Serializer::visit(&mut ser, value));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Encode the specified struct into a json `[u8]` buffer.
|
||||||
|
#[inline]
|
||||||
|
pub fn to_vec<T>(value: &T) -> Vec<u8>
|
||||||
|
where T: ser::Serialize,
|
||||||
|
{
|
||||||
|
// We are writing to a Vec, which doesn't fail. So we can ignore
|
||||||
|
// the error.
|
||||||
|
let mut writer = Vec::with_capacity(128);
|
||||||
|
to_writer(&mut writer, value).unwrap();
|
||||||
|
writer
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Encode the specified struct into a json `[u8]` buffer.
|
||||||
|
#[inline]
|
||||||
|
pub fn to_vec_pretty<T>(value: &T) -> Vec<u8>
|
||||||
|
where T: ser::Serialize,
|
||||||
|
{
|
||||||
|
// We are writing to a Vec, which doesn't fail. So we can ignore
|
||||||
|
// the error.
|
||||||
|
let mut writer = Vec::with_capacity(128);
|
||||||
|
to_writer_pretty(&mut writer, value).unwrap();
|
||||||
|
writer
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Encode the specified struct into a json `String` buffer.
|
||||||
|
#[inline]
|
||||||
|
pub fn to_string<T>(value: &T) -> Result<String, FromUtf8Error>
|
||||||
|
where T: ser::Serialize
|
||||||
|
{
|
||||||
|
let vec = to_vec(value);
|
||||||
|
String::from_utf8(vec)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Encode the specified struct into a json `String` buffer.
|
||||||
|
#[inline]
|
||||||
|
pub fn to_string_pretty<T>(value: &T) -> Result<String, FromUtf8Error>
|
||||||
|
where T: ser::Serialize
|
||||||
|
{
|
||||||
|
let vec = to_vec_pretty(value);
|
||||||
|
String::from_utf8(vec)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spaces<W>(wr: &mut W, mut n: usize) -> io::Result<()>
|
||||||
|
where W: io::Write,
|
||||||
|
{
|
||||||
const LEN: usize = 16;
|
const LEN: usize = 16;
|
||||||
const BUF: &'static [u8; LEN] = &[b' '; LEN];
|
const BUF: &'static [u8; LEN] = &[b' '; 16];
|
||||||
|
|
||||||
while n >= LEN {
|
while n >= LEN {
|
||||||
try!(wr.write_all(BUF));
|
try!(wr.write_all(BUF));
|
||||||
@@ -574,63 +455,3 @@ fn spaces<W: io::Write>(wr: &mut W, mut n: usize) -> io::Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encode the specified struct into a json `[u8]` writer.
|
|
||||||
#[inline]
|
|
||||||
pub fn to_writer<W, T>(writer: W, value: &T) -> io::Result<W>
|
|
||||||
where W: io::Write,
|
|
||||||
T: ser::Serialize<Serializer<W>, io::Error>
|
|
||||||
{
|
|
||||||
let mut serializer = Serializer::new(writer);
|
|
||||||
try!(value.serialize(&mut serializer));
|
|
||||||
Ok(serializer.unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Encode the specified struct into a json `[u8]` buffer.
|
|
||||||
#[inline]
|
|
||||||
pub fn to_vec<T>(value: &T) -> Vec<u8>
|
|
||||||
where T: ser::Serialize<Serializer<Vec<u8>>, io::Error>
|
|
||||||
{
|
|
||||||
// We are writing to a Vec, which doesn't fail. So we can ignore
|
|
||||||
// the error.
|
|
||||||
let writer = Vec::with_capacity(128);
|
|
||||||
to_writer(writer, value).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Encode the specified struct into a json `String` buffer.
|
|
||||||
#[inline]
|
|
||||||
pub fn to_string<T>(value: &T) -> Result<String, FromUtf8Error>
|
|
||||||
where T: ser::Serialize<Serializer<Vec<u8>>, io::Error>
|
|
||||||
{
|
|
||||||
let vec = to_vec(value);
|
|
||||||
String::from_utf8(vec)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Encode the specified struct into a json `[u8]` writer.
|
|
||||||
#[inline]
|
|
||||||
pub fn to_pretty_writer<
|
|
||||||
W: io::Write,
|
|
||||||
T: ser::Serialize<PrettySerializer<W>, io::Error>
|
|
||||||
>(writer: W, value: &T) -> io::Result<W> {
|
|
||||||
let mut serializer = PrettySerializer::new(writer);
|
|
||||||
try!(value.serialize(&mut serializer));
|
|
||||||
Ok(serializer.unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Encode the specified struct into a json `[u8]` buffer.
|
|
||||||
pub fn to_pretty_vec<
|
|
||||||
T: ser::Serialize<PrettySerializer<Vec<u8>>, io::Error>
|
|
||||||
>(value: &T) -> Vec<u8> {
|
|
||||||
// We are writing to a Vec, which doesn't fail. So we can ignore
|
|
||||||
// the error.
|
|
||||||
let writer = Vec::with_capacity(128);
|
|
||||||
to_pretty_writer(writer, value).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Encode the specified struct into a json `String` buffer.
|
|
||||||
pub fn to_pretty_string<
|
|
||||||
T: ser::Serialize<PrettySerializer<Vec<u8>>, io::Error>
|
|
||||||
>(value: &T) -> Result<String, FromUtf8Error> {
|
|
||||||
let buf = to_pretty_vec(value);
|
|
||||||
String::from_utf8(buf)
|
|
||||||
}
|
|
||||||
|
|||||||
+526
-604
File diff suppressed because it is too large
Load Diff
+4
-11
@@ -1,17 +1,10 @@
|
|||||||
#![feature(collections, core, hash, io, std_misc, plugin, unicode)]
|
#![feature(core, io, path, std_misc, unicode)]
|
||||||
#![plugin(serde_macros)]
|
|
||||||
|
|
||||||
extern crate unicode;
|
extern crate unicode;
|
||||||
|
|
||||||
pub use de::{Deserializer, Deserialize};
|
pub use ser::{Serialize, Serializer};
|
||||||
pub use ser::{Serializer, Serialize};
|
pub use de::{Deserialize, Deserializer, Error};
|
||||||
|
|
||||||
pub mod de;
|
|
||||||
pub mod ser;
|
pub mod ser;
|
||||||
|
pub mod de;
|
||||||
pub mod json;
|
pub mod json;
|
||||||
|
|
||||||
// an inner module so we can use serde_macros.
|
|
||||||
mod serde {
|
|
||||||
pub use de;
|
|
||||||
pub use ser;
|
|
||||||
}
|
|
||||||
|
|||||||
+621
-276
@@ -1,315 +1,660 @@
|
|||||||
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
use std::collections::hash_state::HashState;
|
||||||
// file at the top-level directory of this distribution and at
|
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
use std::collections::{HashMap, HashSet, BTreeMap, BTreeSet};
|
|
||||||
use std::collections::hash_map::Hasher;
|
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
use std::path;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::str;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
pub trait Serializer<E> {
|
pub trait Serialize {
|
||||||
fn serialize_null(&mut self) -> Result<(), E>;
|
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
||||||
|
where V: Visitor;
|
||||||
fn serialize_bool(&mut self, v: bool) -> Result<(), E>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_isize(&mut self, v: isize) -> Result<(), E> {
|
|
||||||
self.serialize_i64(v as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_i8(&mut self, v: i8) -> Result<(), E> {
|
|
||||||
self.serialize_i64(v as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_i16(&mut self, v: i16) -> Result<(), E> {
|
|
||||||
self.serialize_i64(v as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_i32(&mut self, v: i32) -> Result<(), E> {
|
|
||||||
self.serialize_i64(v as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_i64(&mut self, v: i64) -> Result<(), E>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_usize(&mut self, v: usize) -> Result<(), E> {
|
|
||||||
self.serialize_u64(v as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_u8(&mut self, v: u8) -> Result<(), E> {
|
|
||||||
self.serialize_u64(v as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_u16(&mut self, v: u16) -> Result<(), E> {
|
|
||||||
self.serialize_u64(v as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_u32(&mut self, v: u32) -> Result<(), E> {
|
|
||||||
self.serialize_u64(v as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_u64(&mut self, v: u64) -> Result<(), E>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize_f32(&mut self, v: f32) -> Result<(), E> {
|
|
||||||
self.serialize_f64(v as f64)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_f64(&mut self, v: f64) -> Result<(), E>;
|
|
||||||
|
|
||||||
fn serialize_char(&mut self, v: char) -> Result<(), E>;
|
|
||||||
|
|
||||||
fn serialize_str(&mut self, v: &str) -> Result<(), E>;
|
|
||||||
|
|
||||||
fn serialize_tuple_start(&mut self, len: usize) -> Result<(), E>;
|
|
||||||
fn serialize_tuple_elt<
|
|
||||||
T: Serialize<Self, E>
|
|
||||||
>(&mut self, v: &T) -> Result<(), E>;
|
|
||||||
fn serialize_tuple_end(&mut self) -> Result<(), E>;
|
|
||||||
|
|
||||||
fn serialize_struct_start(&mut self, name: &str, len: usize) -> Result<(), E>;
|
|
||||||
fn serialize_struct_elt<
|
|
||||||
T: Serialize<Self, E>
|
|
||||||
>(&mut self, name: &str, v: &T) -> Result<(), E>;
|
|
||||||
fn serialize_struct_end(&mut self) -> Result<(), E>;
|
|
||||||
|
|
||||||
fn serialize_enum_start(&mut self, name: &str, variant: &str, len: usize) -> Result<(), E>;
|
|
||||||
fn serialize_enum_elt<
|
|
||||||
T: Serialize<Self, E>
|
|
||||||
>(&mut self, v: &T) -> Result<(), E>;
|
|
||||||
fn serialize_enum_end(&mut self) -> Result<(), E>;
|
|
||||||
|
|
||||||
fn serialize_option<
|
|
||||||
T: Serialize<Self, E>
|
|
||||||
>(&mut self, v: &Option<T>) -> Result<(), E>;
|
|
||||||
|
|
||||||
fn serialize_seq<
|
|
||||||
T: Serialize<Self, E>,
|
|
||||||
Iter: Iterator<Item=T>
|
|
||||||
>(&mut self, iter: Iter) -> Result<(), E>;
|
|
||||||
|
|
||||||
fn serialize_map<
|
|
||||||
K: Serialize<Self, E>,
|
|
||||||
V: Serialize<Self, E>,
|
|
||||||
Iter: Iterator<Item=(K, V)>
|
|
||||||
>(&mut self, iter: Iter) -> Result<(), E>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
pub trait Serialize<S: Serializer<E>, E> {
|
pub trait Serializer {
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E>;
|
type Value;
|
||||||
|
type Error;
|
||||||
|
|
||||||
|
fn visit<T>(&mut self, value: &T) -> Result<Self::Value, Self::Error>
|
||||||
|
where T: Serialize;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
macro_rules! impl_serialize {
|
pub trait Visitor {
|
||||||
|
type Value;
|
||||||
|
type Error;
|
||||||
|
|
||||||
|
fn visit_bool(&mut self, v: bool) -> Result<Self::Value, Self::Error>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_isize(&mut self, v: isize) -> Result<Self::Value, Self::Error> {
|
||||||
|
self.visit_i64(v as i64)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_i8(&mut self, v: i8) -> Result<Self::Value, Self::Error> {
|
||||||
|
self.visit_i64(v as i64)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_i16(&mut self, v: i16) -> Result<Self::Value, Self::Error> {
|
||||||
|
self.visit_i64(v as i64)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_i32(&mut self, v: i32) -> Result<Self::Value, Self::Error> {
|
||||||
|
self.visit_i64(v as i64)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_i64(&mut self, v: i64) -> Result<Self::Value, Self::Error>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_usize(&mut self, v: usize) -> Result<Self::Value, Self::Error> {
|
||||||
|
self.visit_u64(v as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_u8(&mut self, v: u8) -> Result<Self::Value, Self::Error> {
|
||||||
|
self.visit_u64(v as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_u16(&mut self, v: u16) -> Result<Self::Value, Self::Error> {
|
||||||
|
self.visit_u64(v as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_u32(&mut self, v: u32) -> Result<Self::Value, Self::Error> {
|
||||||
|
self.visit_u64(v as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_u64(&mut self, v: u64) -> Result<Self::Value, Self::Error>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_f32(&mut self, v: f32) -> Result<Self::Value, Self::Error> {
|
||||||
|
self.visit_f64(v as f64)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_f64(&mut self, v: f64) -> Result<Self::Value, Self::Error>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_char(&mut self, v: char) -> Result<Self::Value, Self::Error> {
|
||||||
|
// The unwraps in here should be safe.
|
||||||
|
let mut s = &mut [0; 4];
|
||||||
|
let len = v.encode_utf8(s).unwrap();
|
||||||
|
self.visit_str(str::from_utf8(&s[..len]).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_str(&mut self, value: &str) -> Result<Self::Value, Self::Error>;
|
||||||
|
|
||||||
|
fn visit_unit(&mut self) -> Result<Self::Value, Self::Error>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_named_unit(&mut self, _name: &str) -> Result<Self::Value, Self::Error> {
|
||||||
|
self.visit_unit()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_enum_unit(&mut self,
|
||||||
|
_name: &str,
|
||||||
|
_variant: &str) -> Result<Self::Value, Self::Error> {
|
||||||
|
self.visit_unit()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_none(&mut self) -> Result<Self::Value, Self::Error>;
|
||||||
|
|
||||||
|
fn visit_some<V>(&mut self, value: V) -> Result<Self::Value, Self::Error>
|
||||||
|
where V: Serialize;
|
||||||
|
|
||||||
|
fn visit_seq<V>(&mut self, visitor: V) -> Result<Self::Value, Self::Error>
|
||||||
|
where V: SeqVisitor;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_named_seq<V>(&mut self,
|
||||||
|
_name: &'static str,
|
||||||
|
visitor: V) -> Result<Self::Value, Self::Error>
|
||||||
|
where V: SeqVisitor,
|
||||||
|
{
|
||||||
|
self.visit_seq(visitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_enum_seq<V>(&mut self,
|
||||||
|
_name: &'static str,
|
||||||
|
_variant: &'static str,
|
||||||
|
visitor: V) -> Result<Self::Value, Self::Error>
|
||||||
|
where V: SeqVisitor,
|
||||||
|
{
|
||||||
|
self.visit_seq(visitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_seq_elt<T>(&mut self,
|
||||||
|
first: bool,
|
||||||
|
value: T) -> Result<Self::Value, Self::Error>
|
||||||
|
where T: Serialize;
|
||||||
|
|
||||||
|
fn visit_map<V>(&mut self, visitor: V) -> Result<Self::Value, Self::Error>
|
||||||
|
where V: MapVisitor;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_named_map<V>(&mut self,
|
||||||
|
_name: &'static str,
|
||||||
|
visitor: V) -> Result<Self::Value, Self::Error>
|
||||||
|
where V: MapVisitor,
|
||||||
|
{
|
||||||
|
self.visit_map(visitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_enum_map<V>(&mut self,
|
||||||
|
_name: &'static str,
|
||||||
|
_variant: &'static str,
|
||||||
|
visitor: V) -> Result<Self::Value, Self::Error>
|
||||||
|
where V: MapVisitor,
|
||||||
|
{
|
||||||
|
self.visit_map(visitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_map_elt<K, V>(&mut self,
|
||||||
|
first: bool,
|
||||||
|
key: K,
|
||||||
|
value: V) -> Result<Self::Value, Self::Error>
|
||||||
|
where K: Serialize,
|
||||||
|
V: Serialize;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait SeqVisitor {
|
||||||
|
fn visit<V>(&mut self, visitor: &mut V) -> Result<Option<V::Value>, V::Error>
|
||||||
|
where V: Visitor;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
(0, None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait MapVisitor {
|
||||||
|
fn visit<V>(&mut self, visitor: &mut V) -> Result<Option<V::Value>, V::Error>
|
||||||
|
where V: Visitor;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
(0, None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
macro_rules! impl_visit {
|
||||||
($ty:ty, $method:ident) => {
|
($ty:ty, $method:ident) => {
|
||||||
impl<S: Serializer<E>, E> Serialize<S, E> for $ty {
|
impl Serialize for $ty {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E> {
|
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
||||||
s.$method(*self)
|
where V: Visitor,
|
||||||
|
{
|
||||||
|
visitor.$method(*self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_serialize!(bool, serialize_bool);
|
impl_visit!(bool, visit_bool);
|
||||||
impl_serialize!(isize, serialize_isize);
|
impl_visit!(isize, visit_isize);
|
||||||
impl_serialize!(i8, serialize_i8);
|
impl_visit!(i8, visit_i8);
|
||||||
impl_serialize!(i16, serialize_i16);
|
impl_visit!(i16, visit_i16);
|
||||||
impl_serialize!(i32, serialize_i32);
|
impl_visit!(i32, visit_i32);
|
||||||
impl_serialize!(i64, serialize_i64);
|
impl_visit!(i64, visit_i64);
|
||||||
impl_serialize!(usize, serialize_usize);
|
impl_visit!(usize, visit_usize);
|
||||||
impl_serialize!(u8, serialize_u8);
|
impl_visit!(u8, visit_u8);
|
||||||
impl_serialize!(u16, serialize_u16);
|
impl_visit!(u16, visit_u16);
|
||||||
impl_serialize!(u32, serialize_u32);
|
impl_visit!(u32, visit_u32);
|
||||||
impl_serialize!(u64, serialize_u64);
|
impl_visit!(u64, visit_u64);
|
||||||
impl_serialize!(f32, serialize_f32);
|
impl_visit!(f32, visit_f32);
|
||||||
impl_serialize!(f64, serialize_f64);
|
impl_visit!(f64, visit_f64);
|
||||||
impl_serialize!(char, serialize_char);
|
impl_visit!(char, visit_char);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
impl<'a, S: Serializer<E>, E> Serialize<S, E> for &'a str {
|
impl<'a> Serialize for &'a str {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E> {
|
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
||||||
s.serialize_str(*self)
|
where V: Visitor,
|
||||||
|
{
|
||||||
|
visitor.visit_str(*self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Serializer<E>, E> Serialize<S, E> for String {
|
impl Serialize for String {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E> {
|
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
||||||
(&self[]).serialize(s)
|
where V: Visitor,
|
||||||
|
{
|
||||||
|
(&self[..]).visit(visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
macro_rules! impl_serialize_box {
|
impl<T> Serialize for Option<T> where T: Serialize {
|
||||||
($ty:ty) => {
|
#[inline]
|
||||||
impl<
|
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
||||||
'a,
|
where V: Visitor,
|
||||||
S: Serializer<E>,
|
{
|
||||||
E,
|
match *self {
|
||||||
T: Serialize<S, E>
|
Some(ref value) => visitor.visit_some(value),
|
||||||
> Serialize<S, E> for $ty {
|
None => visitor.visit_none(),
|
||||||
#[inline]
|
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E> {
|
|
||||||
(**self).serialize(s)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_serialize_box!(&'a T);
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
impl_serialize_box!(Box<T>);
|
|
||||||
impl_serialize_box!(Rc<T>);
|
|
||||||
|
|
||||||
impl<
|
pub struct SeqIteratorVisitor<Iter> {
|
||||||
S: Serializer<E>,
|
iter: Iter,
|
||||||
E,
|
first: bool,
|
||||||
T: Serialize<S, E> + Send + Sync
|
}
|
||||||
> Serialize<S, E> for Arc<T> {
|
|
||||||
|
impl<T, Iter> SeqIteratorVisitor<Iter>
|
||||||
|
where Iter: Iterator<Item=T>
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E> {
|
pub fn new(iter: Iter) -> SeqIteratorVisitor<Iter> {
|
||||||
(**self).serialize(s)
|
SeqIteratorVisitor {
|
||||||
}
|
iter: iter,
|
||||||
}
|
first: true,
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
impl<
|
|
||||||
S: Serializer<E>,
|
|
||||||
E,
|
|
||||||
T: Serialize<S, E>
|
|
||||||
> Serialize<S, E> for Option<T> {
|
|
||||||
#[inline]
|
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E> {
|
|
||||||
s.serialize_option(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
impl<
|
|
||||||
S: Serializer<E>,
|
|
||||||
E,
|
|
||||||
T: Serialize<S, E>
|
|
||||||
> Serialize<S, E> for Vec<T> {
|
|
||||||
#[inline]
|
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E> {
|
|
||||||
s.serialize_seq(self.iter())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
impl<
|
|
||||||
S: Serializer<E>,
|
|
||||||
E,
|
|
||||||
K: Serialize<S, E> + Eq + Hash<Hasher>,
|
|
||||||
V: Serialize<S, E>
|
|
||||||
> Serialize<S, E> for HashMap<K, V> {
|
|
||||||
#[inline]
|
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E> {
|
|
||||||
s.serialize_map(self.iter())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<
|
|
||||||
S: Serializer<E>,
|
|
||||||
E,
|
|
||||||
K: Serialize<S, E> + Ord,
|
|
||||||
V: Serialize<S, E>
|
|
||||||
> Serialize<S, E> for BTreeMap<K, V> {
|
|
||||||
#[inline]
|
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E> {
|
|
||||||
s.serialize_map(self.iter())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
impl<
|
|
||||||
S: Serializer<E>,
|
|
||||||
E,
|
|
||||||
T: Serialize<S, E> + Eq + Hash<Hasher>
|
|
||||||
> Serialize<S, E> for HashSet<T> {
|
|
||||||
#[inline]
|
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E> {
|
|
||||||
s.serialize_seq(self.iter())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<
|
|
||||||
S: Serializer<E>,
|
|
||||||
E,
|
|
||||||
T: Serialize<S, E> + Ord
|
|
||||||
> Serialize<S, E> for BTreeSet<T> {
|
|
||||||
#[inline]
|
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E> {
|
|
||||||
s.serialize_seq(self.iter())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
macro_rules! peel {
|
|
||||||
($name:ident, $($other:ident,)*) => ( impl_serialize_tuple!($($other,)*); )
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! impl_serialize_tuple {
|
|
||||||
() => {
|
|
||||||
impl<S: Serializer<E>, E> Serialize<S, E> for () {
|
|
||||||
#[inline]
|
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E> {
|
|
||||||
s.serialize_null()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
( $($name:ident,)+ ) => {
|
|
||||||
impl<
|
|
||||||
S: Serializer<E>,
|
|
||||||
E,
|
|
||||||
$($name:Serialize<S, E>),+
|
|
||||||
> Serialize<S, E> for ($($name,)+) {
|
|
||||||
#[inline]
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
fn serialize(&self, s: &mut S) -> Result<(), E> {
|
|
||||||
// FIXME: how can we count macro args?
|
|
||||||
let mut len = 0;
|
|
||||||
$({ let $name = 1; len += $name; })*;
|
|
||||||
|
|
||||||
let ($(ref $name,)*) = *self;
|
|
||||||
|
|
||||||
try!(s.serialize_tuple_start(len));
|
|
||||||
$(
|
|
||||||
try!(s.serialize_tuple_elt($name));
|
|
||||||
)*
|
|
||||||
s.serialize_tuple_end()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
peel!($($name,)*);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_serialize_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
|
impl<T, Iter> SeqVisitor for SeqIteratorVisitor<Iter>
|
||||||
|
where T: Serialize,
|
||||||
|
Iter: Iterator<Item=T>,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn visit<V>(&mut self, visitor: &mut V) -> Result<Option<V::Value>, V::Error>
|
||||||
|
where V: Visitor,
|
||||||
|
{
|
||||||
|
let first = self.first;
|
||||||
|
self.first = false;
|
||||||
|
|
||||||
|
match self.iter.next() {
|
||||||
|
Some(value) => {
|
||||||
|
let value = try!(visitor.visit_seq_elt(first, value));
|
||||||
|
Ok(Some(value))
|
||||||
|
}
|
||||||
|
None => Ok(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
self.iter.size_hint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
impl<'a, T> Serialize for &'a [T]
|
||||||
|
where T: Serialize,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
||||||
|
where V: Visitor,
|
||||||
|
{
|
||||||
|
visitor.visit_seq(SeqIteratorVisitor::new(self.iter()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Serialize for Vec<T> where T: Serialize {
|
||||||
|
#[inline]
|
||||||
|
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
||||||
|
where V: Visitor,
|
||||||
|
{
|
||||||
|
(&self[..]).visit(visitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Serialize for BTreeSet<T> where T: Serialize {
|
||||||
|
#[inline]
|
||||||
|
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
||||||
|
where V: Visitor,
|
||||||
|
{
|
||||||
|
visitor.visit_seq(SeqIteratorVisitor::new(self.iter()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, S> Serialize for HashSet<T, S>
|
||||||
|
where T: Serialize + Eq + Hash,
|
||||||
|
S: HashState,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn visit<V: Visitor>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
|
||||||
|
visitor.visit_seq(SeqIteratorVisitor::new(self.iter()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
impl Serialize for () {
|
||||||
|
#[inline]
|
||||||
|
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
||||||
|
where V: Visitor,
|
||||||
|
{
|
||||||
|
visitor.visit_unit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// FIXME(rust #19630) Remove this work-around
|
||||||
|
macro_rules! e {
|
||||||
|
($e:expr) => { $e }
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! tuple_impls {
|
||||||
|
($(
|
||||||
|
$TupleVisitor:ident ($len:expr, $($T:ident),+) {
|
||||||
|
$($state:pat => $idx:tt,)+
|
||||||
|
}
|
||||||
|
)+) => {
|
||||||
|
$(
|
||||||
|
pub struct $TupleVisitor<'a, $($T: 'a),+> {
|
||||||
|
tuple: &'a ($($T,)+),
|
||||||
|
state: u8,
|
||||||
|
first: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, $($T: 'a),+> $TupleVisitor<'a, $($T),+> {
|
||||||
|
pub fn new(tuple: &'a ($($T,)+)) -> $TupleVisitor<'a, $($T),+> {
|
||||||
|
$TupleVisitor {
|
||||||
|
tuple: tuple,
|
||||||
|
state: 0,
|
||||||
|
first: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, $($T),+> SeqVisitor for $TupleVisitor<'a, $($T),+>
|
||||||
|
where $($T: Serialize),+
|
||||||
|
{
|
||||||
|
fn visit<V>(&mut self, visitor: &mut V) -> Result<Option<V::Value>, V::Error>
|
||||||
|
where V: Visitor,
|
||||||
|
{
|
||||||
|
let first = self.first;
|
||||||
|
self.first = false;
|
||||||
|
|
||||||
|
match self.state {
|
||||||
|
$(
|
||||||
|
$state => {
|
||||||
|
self.state += 1;
|
||||||
|
Ok(Some(try!(visitor.visit_seq_elt(first, &e!(self.tuple.$idx)))))
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
_ => {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
($len, Some($len))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<$($T),+> Serialize for ($($T,)+)
|
||||||
|
where $($T: Serialize),+
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn visit<V: Visitor>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
|
||||||
|
visitor.visit_seq($TupleVisitor::new(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tuple_impls! {
|
||||||
|
TupleVisitor1 (1, T0) {
|
||||||
|
0 => 0,
|
||||||
|
}
|
||||||
|
TupleVisitor2 (2, T0, T1) {
|
||||||
|
0 => 0,
|
||||||
|
1 => 1,
|
||||||
|
}
|
||||||
|
TupleVisitor3 (3, T0, T1, T2) {
|
||||||
|
0 => 0,
|
||||||
|
1 => 1,
|
||||||
|
2 => 2,
|
||||||
|
}
|
||||||
|
TupleVisitor4 (4, T0, T1, T2, T3) {
|
||||||
|
0 => 0,
|
||||||
|
1 => 1,
|
||||||
|
2 => 2,
|
||||||
|
3 => 3,
|
||||||
|
}
|
||||||
|
TupleVisitor5 (5, T0, T1, T2, T3, T4) {
|
||||||
|
0 => 0,
|
||||||
|
1 => 1,
|
||||||
|
2 => 2,
|
||||||
|
3 => 3,
|
||||||
|
4 => 4,
|
||||||
|
}
|
||||||
|
TupleVisitor6 (6, T0, T1, T2, T3, T4, T5) {
|
||||||
|
0 => 0,
|
||||||
|
1 => 1,
|
||||||
|
2 => 2,
|
||||||
|
3 => 3,
|
||||||
|
4 => 4,
|
||||||
|
5 => 5,
|
||||||
|
}
|
||||||
|
TupleVisitor7 (7, T0, T1, T2, T3, T4, T5, T6) {
|
||||||
|
0 => 0,
|
||||||
|
1 => 1,
|
||||||
|
2 => 2,
|
||||||
|
3 => 3,
|
||||||
|
4 => 4,
|
||||||
|
5 => 5,
|
||||||
|
6 => 6,
|
||||||
|
}
|
||||||
|
TupleVisitor8 (8, T0, T1, T2, T3, T4, T5, T6, T7) {
|
||||||
|
0 => 0,
|
||||||
|
1 => 1,
|
||||||
|
2 => 2,
|
||||||
|
3 => 3,
|
||||||
|
4 => 4,
|
||||||
|
5 => 5,
|
||||||
|
6 => 6,
|
||||||
|
7 => 7,
|
||||||
|
}
|
||||||
|
TupleVisitor9 (9, T0, T1, T2, T3, T4, T5, T6, T7, T8) {
|
||||||
|
0 => 0,
|
||||||
|
1 => 1,
|
||||||
|
2 => 2,
|
||||||
|
3 => 3,
|
||||||
|
4 => 4,
|
||||||
|
5 => 5,
|
||||||
|
6 => 6,
|
||||||
|
7 => 7,
|
||||||
|
8 => 8,
|
||||||
|
}
|
||||||
|
TupleVisitor10 (10, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) {
|
||||||
|
0 => 0,
|
||||||
|
1 => 1,
|
||||||
|
2 => 2,
|
||||||
|
3 => 3,
|
||||||
|
4 => 4,
|
||||||
|
5 => 5,
|
||||||
|
6 => 6,
|
||||||
|
7 => 7,
|
||||||
|
8 => 8,
|
||||||
|
9 => 9,
|
||||||
|
}
|
||||||
|
TupleVisitor11 (11, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) {
|
||||||
|
0 => 0,
|
||||||
|
1 => 1,
|
||||||
|
2 => 2,
|
||||||
|
3 => 3,
|
||||||
|
4 => 4,
|
||||||
|
5 => 5,
|
||||||
|
6 => 6,
|
||||||
|
7 => 7,
|
||||||
|
8 => 8,
|
||||||
|
9 => 9,
|
||||||
|
10 => 10,
|
||||||
|
}
|
||||||
|
TupleVisitor12 (12, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) {
|
||||||
|
0 => 0,
|
||||||
|
1 => 1,
|
||||||
|
2 => 2,
|
||||||
|
3 => 3,
|
||||||
|
4 => 4,
|
||||||
|
5 => 5,
|
||||||
|
6 => 6,
|
||||||
|
7 => 7,
|
||||||
|
8 => 8,
|
||||||
|
9 => 9,
|
||||||
|
10 => 10,
|
||||||
|
11 => 11,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
pub struct MapIteratorVisitor<Iter> {
|
||||||
|
iter: Iter,
|
||||||
|
first: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K, V, Iter> MapIteratorVisitor<Iter>
|
||||||
|
where Iter: Iterator<Item=(K, V)>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
pub fn new(iter: Iter) -> MapIteratorVisitor<Iter> {
|
||||||
|
MapIteratorVisitor {
|
||||||
|
iter: iter,
|
||||||
|
first: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K, V, I> MapVisitor for MapIteratorVisitor<I>
|
||||||
|
where K: Serialize,
|
||||||
|
V: Serialize,
|
||||||
|
I: Iterator<Item=(K, V)>,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn visit<V_>(&mut self, visitor: &mut V_) -> Result<Option<V_::Value>, V_::Error>
|
||||||
|
where V_: Visitor,
|
||||||
|
{
|
||||||
|
let first = self.first;
|
||||||
|
self.first = false;
|
||||||
|
|
||||||
|
match self.iter.next() {
|
||||||
|
Some((key, value)) => {
|
||||||
|
let value = try!(visitor.visit_map_elt(first, key, value));
|
||||||
|
Ok(Some(value))
|
||||||
|
}
|
||||||
|
None => Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
self.iter.size_hint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
impl<K, V> Serialize for BTreeMap<K, V>
|
||||||
|
where K: Serialize + Ord,
|
||||||
|
V: Serialize,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn visit<V_: Visitor>(&self, visitor: &mut V_) -> Result<V_::Value, V_::Error> {
|
||||||
|
visitor.visit_map(MapIteratorVisitor::new(self.iter()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K, V, S> Serialize for HashMap<K, V, S>
|
||||||
|
where K: Serialize + Eq + Hash,
|
||||||
|
V: Serialize,
|
||||||
|
S: HashState,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn visit<V_: Visitor>(&self, visitor: &mut V_) -> Result<V_::Value, V_::Error> {
|
||||||
|
visitor.visit_map(MapIteratorVisitor::new(self.iter()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
impl<'a, T> Serialize for &'a T where T: Serialize {
|
||||||
|
#[inline]
|
||||||
|
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
||||||
|
where V: Visitor,
|
||||||
|
{
|
||||||
|
(**self).visit(visitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Serialize for &'a mut T where T: Serialize {
|
||||||
|
#[inline]
|
||||||
|
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
||||||
|
where V: Visitor,
|
||||||
|
{
|
||||||
|
(**self).visit(visitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Serialize for Box<T> where T: Serialize {
|
||||||
|
#[inline]
|
||||||
|
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
||||||
|
where V: Visitor,
|
||||||
|
{
|
||||||
|
(**self).visit(visitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Serialize for Rc<T> where T: Serialize, {
|
||||||
|
#[inline]
|
||||||
|
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
||||||
|
where V: Visitor,
|
||||||
|
{
|
||||||
|
(**self).visit(visitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Serialize for Arc<T> where T: Serialize, {
|
||||||
|
#[inline]
|
||||||
|
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
||||||
|
where V: Visitor,
|
||||||
|
{
|
||||||
|
(**self).visit(visitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
impl Serialize for path::Path {
|
||||||
|
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
||||||
|
where V: Visitor,
|
||||||
|
{
|
||||||
|
self.to_str().unwrap().visit(visitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for path::PathBuf {
|
||||||
|
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
||||||
|
where V: Visitor,
|
||||||
|
{
|
||||||
|
self.to_str().unwrap().visit(visitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
-368
@@ -1,368 +0,0 @@
|
|||||||
#![feature(plugin)]
|
|
||||||
#![plugin(serde_macros)]
|
|
||||||
|
|
||||||
extern crate serde;
|
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
|
||||||
use std::{option, string};
|
|
||||||
|
|
||||||
use serde::de::{Deserializer, Deserialize, Token, TokenKind, IgnoreTokens};
|
|
||||||
|
|
||||||
macro_rules! treemap {
|
|
||||||
($($k:expr => $v:expr),*) => ({
|
|
||||||
let mut _m = ::std::collections::BTreeMap::new();
|
|
||||||
$(_m.insert($k, $v);)*
|
|
||||||
_m
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
|
||||||
struct Inner {
|
|
||||||
a: (),
|
|
||||||
b: usize,
|
|
||||||
c: BTreeMap<string::String, option::Option<char>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<
|
|
||||||
D: Deserializer<E>,
|
|
||||||
E
|
|
||||||
> Deserialize<D, E> for Inner {
|
|
||||||
#[inline]
|
|
||||||
fn deserialize_token(d: &mut D, token: Token) -> Result<Inner, E> {
|
|
||||||
try!(d.expect_struct_start(token, "Inner"));
|
|
||||||
|
|
||||||
let mut a = None;
|
|
||||||
let mut b = None;
|
|
||||||
let mut c = None;
|
|
||||||
|
|
||||||
static FIELDS: &'static [&'static str] = &["a", "b", "c"];
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let idx = match try!(d.expect_struct_field_or_end(FIELDS)) {
|
|
||||||
Some(idx) => idx,
|
|
||||||
None => { break; }
|
|
||||||
};
|
|
||||||
|
|
||||||
match idx {
|
|
||||||
Some(0) => { a = Some(try!(d.expect_struct_value())); }
|
|
||||||
Some(1) => { b = Some(try!(d.expect_struct_value())); }
|
|
||||||
Some(2) => { c = Some(try!(d.expect_struct_value())); }
|
|
||||||
Some(_) => unreachable!(),
|
|
||||||
None => { let _: IgnoreTokens = try!(Deserialize::deserialize(d)); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Inner { a: a.unwrap(), b: b.unwrap(), c: c.unwrap() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
|
||||||
struct Outer {
|
|
||||||
inner: Vec<Inner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D: Deserializer<E>, E> Deserialize<D, E> for Outer {
|
|
||||||
#[inline]
|
|
||||||
fn deserialize_token(d: &mut D, token: Token) -> Result<Outer, E> {
|
|
||||||
try!(d.expect_struct_start(token, "Outer"));
|
|
||||||
|
|
||||||
static FIELDS: &'static [&'static str] = &["inner"];
|
|
||||||
|
|
||||||
let mut inner = None;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let idx = match try!(d.expect_struct_field_or_end(FIELDS)) {
|
|
||||||
Some(idx) => idx,
|
|
||||||
None => { break; }
|
|
||||||
};
|
|
||||||
|
|
||||||
match idx {
|
|
||||||
Some(0) => { inner = Some(try!(d.expect_struct_value())); }
|
|
||||||
Some(_) => unreachable!(),
|
|
||||||
None => { let _: IgnoreTokens = try!(Deserialize::deserialize(d)); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Outer { inner: inner.unwrap() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
|
||||||
enum Animal {
|
|
||||||
Dog,
|
|
||||||
Frog(string::String, isize)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D: Deserializer<E>, E> Deserialize<D, E> for Animal {
|
|
||||||
#[inline]
|
|
||||||
fn deserialize_token(d: &mut D, token: Token) -> Result<Animal, E> {
|
|
||||||
match try!(d.expect_enum_start(token, "Animal", &["Dog", "Frog"])) {
|
|
||||||
0 => {
|
|
||||||
try!(d.expect_enum_end());
|
|
||||||
Ok(Animal::Dog)
|
|
||||||
}
|
|
||||||
1 => {
|
|
||||||
let x0 = try!(Deserialize::deserialize(d));
|
|
||||||
let x1 = try!(Deserialize::deserialize(d));
|
|
||||||
try!(d.expect_enum_end());
|
|
||||||
Ok(Animal::Frog(x0, x1))
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
enum Error {
|
|
||||||
EndOfStream,
|
|
||||||
SyntaxError(Vec<TokenKind>),
|
|
||||||
UnexpectedName,
|
|
||||||
ConversionError,
|
|
||||||
MissingField(&'static str),
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
struct TokenDeserializer<Iter> {
|
|
||||||
tokens: Iter,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Iter: Iterator<Item=Token>> TokenDeserializer<Iter> {
|
|
||||||
#[inline]
|
|
||||||
fn new(tokens: Iter) -> TokenDeserializer<Iter> {
|
|
||||||
TokenDeserializer {
|
|
||||||
tokens: tokens,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Iter: Iterator<Item=Token>> Iterator for TokenDeserializer<Iter> {
|
|
||||||
type Item = Result<Token, Error>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next(&mut self) -> option::Option<Result<Token, Error>> {
|
|
||||||
self.tokens.next().map(|token| Ok(token))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Iter: Iterator<Item=Token>> Deserializer<Error> for TokenDeserializer<Iter> {
|
|
||||||
fn end_of_stream_error(&mut self) -> Error {
|
|
||||||
Error::EndOfStream
|
|
||||||
}
|
|
||||||
|
|
||||||
fn syntax_error(&mut self, _token: Token, expected: &[TokenKind]) -> Error {
|
|
||||||
Error::SyntaxError(expected.to_vec())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unexpected_name_error(&mut self, _token: Token) -> Error {
|
|
||||||
Error::UnexpectedName
|
|
||||||
}
|
|
||||||
|
|
||||||
fn conversion_error(&mut self, _token: Token) -> Error {
|
|
||||||
Error::ConversionError
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn missing_field<
|
|
||||||
T: Deserialize<TokenDeserializer<Iter>, Error>
|
|
||||||
>(&mut self, field: &'static str) -> Result<T, Error> {
|
|
||||||
Err(Error::MissingField(field))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
macro_rules! test_value {
|
|
||||||
($name:ident, [$($tokens:expr => $value:expr, $ty:ty),*]) => {
|
|
||||||
#[test]
|
|
||||||
fn $name() {
|
|
||||||
$(
|
|
||||||
let mut deserializer = TokenDeserializer::new($tokens.into_iter());
|
|
||||||
let value: $ty = Deserialize::deserialize(&mut deserializer).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(value, $value);
|
|
||||||
)+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
test_value!(test_primitives, [
|
|
||||||
vec!(Token::Null) => (), (),
|
|
||||||
vec!(Token::Bool(true)) => true, bool,
|
|
||||||
vec!(Token::Bool(false)) => false, bool,
|
|
||||||
vec!(Token::Isize(5)) => 5, isize,
|
|
||||||
vec!(Token::I8(5)) => 5, i8,
|
|
||||||
vec!(Token::I16(5)) => 5, i16,
|
|
||||||
vec!(Token::I32(5)) => 5, i32,
|
|
||||||
vec!(Token::I64(5)) => 5, i64,
|
|
||||||
vec!(Token::Usize(5)) => 5, usize,
|
|
||||||
vec!(Token::U8(5)) => 5, u8,
|
|
||||||
vec!(Token::U16(5)) => 5, u16,
|
|
||||||
vec!(Token::U32(5)) => 5, u32,
|
|
||||||
vec!(Token::U64(5)) => 5, u64,
|
|
||||||
vec!(Token::F32(5.0)) => 5.0, f32,
|
|
||||||
vec!(Token::F64(5.0)) => 5.0, f64,
|
|
||||||
vec!(Token::Char('c')) => 'c', char,
|
|
||||||
vec!(Token::Str("abc")) => "abc", &str,
|
|
||||||
vec!(Token::String("abc".to_string())) => "abc".to_string(), string::String
|
|
||||||
]);
|
|
||||||
|
|
||||||
test_value!(test_tuples, [
|
|
||||||
vec!(
|
|
||||||
Token::TupleStart(0),
|
|
||||||
Token::End,
|
|
||||||
) => (), (),
|
|
||||||
|
|
||||||
vec!(
|
|
||||||
Token::TupleStart(2),
|
|
||||||
Token::Isize(5),
|
|
||||||
|
|
||||||
Token::Str("a"),
|
|
||||||
Token::End,
|
|
||||||
) => (5, "a"), (isize, &'static str),
|
|
||||||
|
|
||||||
vec!(
|
|
||||||
Token::TupleStart(3),
|
|
||||||
Token::Null,
|
|
||||||
|
|
||||||
Token::TupleStart(0),
|
|
||||||
Token::End,
|
|
||||||
|
|
||||||
Token::TupleStart(2),
|
|
||||||
Token::Isize(5),
|
|
||||||
|
|
||||||
Token::Str("a"),
|
|
||||||
Token::End,
|
|
||||||
Token::End,
|
|
||||||
) => ((), (), (5, "a")), ((), (), (isize, &'static str))
|
|
||||||
]);
|
|
||||||
|
|
||||||
test_value!(test_options, [
|
|
||||||
vec!(Token::Option(false)) => None, option::Option<isize>,
|
|
||||||
|
|
||||||
vec!(
|
|
||||||
Token::Option(true),
|
|
||||||
Token::Isize(5),
|
|
||||||
) => Some(5), option::Option<isize>
|
|
||||||
]);
|
|
||||||
|
|
||||||
test_value!(test_structs, [
|
|
||||||
vec!(
|
|
||||||
Token::StructStart("Outer", 1),
|
|
||||||
Token::Str("inner"),
|
|
||||||
Token::SeqStart(0),
|
|
||||||
Token::End,
|
|
||||||
Token::End,
|
|
||||||
) => Outer { inner: vec!() }, Outer,
|
|
||||||
|
|
||||||
vec!(
|
|
||||||
Token::StructStart("Outer", 1),
|
|
||||||
Token::Str("inner"),
|
|
||||||
Token::SeqStart(1),
|
|
||||||
Token::StructStart("Inner", 3),
|
|
||||||
Token::Str("a"),
|
|
||||||
Token::Null,
|
|
||||||
|
|
||||||
Token::Str("b"),
|
|
||||||
Token::Usize(5),
|
|
||||||
|
|
||||||
Token::Str("c"),
|
|
||||||
Token::MapStart(1),
|
|
||||||
Token::String("abc".to_string()),
|
|
||||||
|
|
||||||
Token::Option(true),
|
|
||||||
Token::Char('c'),
|
|
||||||
Token::End,
|
|
||||||
Token::End,
|
|
||||||
Token::End,
|
|
||||||
Token::End,
|
|
||||||
) => Outer {
|
|
||||||
inner: vec!(
|
|
||||||
Inner {
|
|
||||||
a: (),
|
|
||||||
b: 5,
|
|
||||||
c: treemap!("abc".to_string() => Some('c')),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
}, Outer
|
|
||||||
]);
|
|
||||||
|
|
||||||
test_value!(test_enums, [
|
|
||||||
vec!(
|
|
||||||
Token::EnumStart("Animal", "Dog", 0),
|
|
||||||
Token::End,
|
|
||||||
) => Animal::Dog, Animal,
|
|
||||||
|
|
||||||
vec!(
|
|
||||||
Token::EnumStart("Animal", "Frog", 2),
|
|
||||||
Token::String("Henry".to_string()),
|
|
||||||
Token::Isize(349),
|
|
||||||
Token::End,
|
|
||||||
) => Animal::Frog("Henry".to_string(), 349), Animal
|
|
||||||
]);
|
|
||||||
|
|
||||||
test_value!(test_vecs, [
|
|
||||||
vec!(
|
|
||||||
Token::SeqStart(0),
|
|
||||||
Token::End,
|
|
||||||
) => vec!(), Vec<isize>,
|
|
||||||
|
|
||||||
vec!(
|
|
||||||
Token::SeqStart(3),
|
|
||||||
Token::Isize(5),
|
|
||||||
|
|
||||||
Token::Isize(6),
|
|
||||||
|
|
||||||
Token::Isize(7),
|
|
||||||
Token::End,
|
|
||||||
) => vec!(5, 6, 7), Vec<isize>,
|
|
||||||
|
|
||||||
|
|
||||||
vec!(
|
|
||||||
Token::SeqStart(3),
|
|
||||||
Token::SeqStart(1),
|
|
||||||
Token::Isize(1),
|
|
||||||
Token::End,
|
|
||||||
|
|
||||||
Token::SeqStart(2),
|
|
||||||
Token::Isize(2),
|
|
||||||
|
|
||||||
Token::Isize(3),
|
|
||||||
Token::End,
|
|
||||||
|
|
||||||
Token::SeqStart(3),
|
|
||||||
Token::Isize(4),
|
|
||||||
|
|
||||||
Token::Isize(5),
|
|
||||||
|
|
||||||
Token::Isize(6),
|
|
||||||
Token::End,
|
|
||||||
Token::End,
|
|
||||||
) => vec!(vec!(1), vec!(2, 3), vec!(4, 5, 6)), Vec<Vec<isize>>
|
|
||||||
]);
|
|
||||||
|
|
||||||
test_value!(test_treemaps, [
|
|
||||||
vec!(
|
|
||||||
Token::MapStart(0),
|
|
||||||
Token::End,
|
|
||||||
) => treemap!(), BTreeMap<isize, string::String>,
|
|
||||||
|
|
||||||
vec!(
|
|
||||||
Token::MapStart(2),
|
|
||||||
Token::Isize(5),
|
|
||||||
Token::String("a".to_string()),
|
|
||||||
|
|
||||||
Token::Isize(6),
|
|
||||||
Token::String("b".to_string()),
|
|
||||||
Token::End,
|
|
||||||
) => treemap!(5is => "a".to_string(), 6is => "b".to_string()), BTreeMap<isize, string::
|
|
||||||
String>
|
|
||||||
]);
|
|
||||||
-1384
File diff suppressed because it is too large
Load Diff
@@ -1,30 +0,0 @@
|
|||||||
#![feature(plugin)]
|
|
||||||
#![plugin(serde_macros)]
|
|
||||||
|
|
||||||
extern crate serde;
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
|
||||||
#[derive_serialize]
|
|
||||||
#[derive_deserialize]
|
|
||||||
struct Test {
|
|
||||||
#[serial_name = "$schema"]
|
|
||||||
schema: String,
|
|
||||||
title: String,
|
|
||||||
#[serial_name = "type"]
|
|
||||||
ty: isize
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_json_struct() {
|
|
||||||
let input = Test {
|
|
||||||
schema: "a".to_string(),
|
|
||||||
title: "b".to_string(),
|
|
||||||
ty: 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
let s = serde::json::to_string(&input).unwrap();
|
|
||||||
assert_eq!(&s[], r#"{"$schema":"a","title":"b","type":3}"#);
|
|
||||||
|
|
||||||
let output: Test = serde::json::from_str(&s).unwrap();
|
|
||||||
assert_eq!(input, output);
|
|
||||||
}
|
|
||||||
-517
@@ -1,517 +0,0 @@
|
|||||||
#![feature(plugin)]
|
|
||||||
#![plugin(serde_macros)]
|
|
||||||
|
|
||||||
extern crate serde;
|
|
||||||
|
|
||||||
use std::collections::{HashMap, BTreeMap};
|
|
||||||
use std::{option, string};
|
|
||||||
|
|
||||||
use serde::ser::{Serializer, Serialize};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
|
||||||
#[derive_serialize]
|
|
||||||
struct Inner {
|
|
||||||
a: (),
|
|
||||||
b: usize,
|
|
||||||
c: HashMap<string::String, option::Option<char>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
|
||||||
#[derive_serialize]
|
|
||||||
struct Outer {
|
|
||||||
inner: Vec<Inner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
|
||||||
#[derive_serialize]
|
|
||||||
enum Animal {
|
|
||||||
Dog,
|
|
||||||
Frog(String, isize)
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
|
||||||
pub enum Token<'a> {
|
|
||||||
Null,
|
|
||||||
Bool(bool),
|
|
||||||
Isize(isize),
|
|
||||||
I8(i8),
|
|
||||||
I16(i16),
|
|
||||||
I32(i32),
|
|
||||||
I64(i64),
|
|
||||||
Usize(usize),
|
|
||||||
U8(u8),
|
|
||||||
U16(u16),
|
|
||||||
U32(u32),
|
|
||||||
U64(u64),
|
|
||||||
F32(f32),
|
|
||||||
F64(f64),
|
|
||||||
Char(char),
|
|
||||||
Str(&'a str),
|
|
||||||
|
|
||||||
TupleStart(usize),
|
|
||||||
TupleSep,
|
|
||||||
TupleEnd,
|
|
||||||
|
|
||||||
StructStart(&'a str, usize),
|
|
||||||
StructSep(&'a str),
|
|
||||||
StructEnd,
|
|
||||||
|
|
||||||
EnumStart(&'a str, &'a str, usize),
|
|
||||||
EnumSep,
|
|
||||||
EnumEnd,
|
|
||||||
|
|
||||||
Option(bool),
|
|
||||||
|
|
||||||
SeqStart(usize),
|
|
||||||
SeqEnd,
|
|
||||||
|
|
||||||
MapStart(usize),
|
|
||||||
MapEnd,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
#[allow(dead_code)]
|
|
||||||
enum Error {
|
|
||||||
EndOfStream,
|
|
||||||
SyntaxError,
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
struct AssertSerializer<Iter> {
|
|
||||||
iter: Iter,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, Iter: Iterator<Item=Token<'a>>> AssertSerializer<Iter> {
|
|
||||||
fn new(iter: Iter) -> AssertSerializer<Iter> {
|
|
||||||
AssertSerializer {
|
|
||||||
iter: iter,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize<'b>(&mut self, token: Token<'b>) -> Result<(), Error> {
|
|
||||||
let t = match self.iter.next() {
|
|
||||||
Some(t) => t,
|
|
||||||
None => { panic!(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
assert_eq!(t, token);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, Iter: Iterator<Item=Token<'a>>> Serializer<Error> for AssertSerializer<Iter> {
|
|
||||||
fn serialize_null(&mut self) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::Null)
|
|
||||||
}
|
|
||||||
fn serialize_bool(&mut self, v: bool) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::Bool(v))
|
|
||||||
}
|
|
||||||
fn serialize_isize(&mut self, v: isize) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::Isize(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_i8(&mut self, v: i8) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::I8(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_i16(&mut self, v: i16) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::I16(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_i32(&mut self, v: i32) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::I32(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_i64(&mut self, v: i64) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::I64(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_usize(&mut self, v: usize) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::Usize(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_u8(&mut self, v: u8) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::U8(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_u16(&mut self, v: u16) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::U16(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_u32(&mut self, v: u32) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::U32(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_u64(&mut self, v: u64) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::U64(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_f32(&mut self, v: f32) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::F32(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_f64(&mut self, v: f64) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::F64(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_char(&mut self, v: char) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::Char(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_str(&mut self, v: &str) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::Str(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_tuple_start(&mut self, len: usize) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::TupleStart(len))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_tuple_elt<
|
|
||||||
T: Serialize<AssertSerializer<Iter>, Error>
|
|
||||||
>(&mut self, value: &T) -> Result<(), Error> {
|
|
||||||
try!(self.serialize(Token::TupleSep));
|
|
||||||
value.serialize(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_tuple_end(&mut self) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::TupleEnd)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_struct_start(&mut self, name: &str, len: usize) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::StructStart(name, len))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_struct_elt<
|
|
||||||
T: Serialize<AssertSerializer<Iter>, Error>
|
|
||||||
>(&mut self, name: &str, value: &T) -> Result<(), Error> {
|
|
||||||
try!(self.serialize(Token::StructSep(name)));
|
|
||||||
value.serialize(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_struct_end(&mut self) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::StructEnd)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_enum_start(&mut self, name: &str, variant: &str, len: usize) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::EnumStart(name, variant, len))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_enum_elt<
|
|
||||||
T: Serialize<AssertSerializer<Iter>, Error>
|
|
||||||
>(&mut self, value: &T) -> Result<(), Error> {
|
|
||||||
try!(self.serialize(Token::EnumSep));
|
|
||||||
value.serialize(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_enum_end(&mut self) -> Result<(), Error> {
|
|
||||||
self.serialize(Token::EnumEnd)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_option<
|
|
||||||
T: Serialize<AssertSerializer<Iter>, Error>
|
|
||||||
>(&mut self, v: &option::Option<T>) -> Result<(), Error> {
|
|
||||||
match *v {
|
|
||||||
Some(ref v) => {
|
|
||||||
try!(self.serialize(Token::Option(true)));
|
|
||||||
v.serialize(self)
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
self.serialize(Token::Option(false))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_seq<
|
|
||||||
T: Serialize<AssertSerializer<Iter>, Error>,
|
|
||||||
SeqIter: Iterator<Item=T>
|
|
||||||
>(&mut self, iter: SeqIter) -> Result<(), Error> {
|
|
||||||
let (len, _) = iter.size_hint();
|
|
||||||
try!(self.serialize(Token::SeqStart(len)));
|
|
||||||
for elt in iter {
|
|
||||||
try!(elt.serialize(self));
|
|
||||||
}
|
|
||||||
self.serialize(Token::SeqEnd)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_map<
|
|
||||||
K: Serialize<AssertSerializer<Iter>, Error>,
|
|
||||||
V: Serialize<AssertSerializer<Iter>, Error>,
|
|
||||||
MapIter: Iterator<Item=(K, V)>
|
|
||||||
>(&mut self, iter: MapIter) -> Result<(), Error> {
|
|
||||||
let (len, _) = iter.size_hint();
|
|
||||||
try!(self.serialize(Token::MapStart(len)));
|
|
||||||
for (key, value) in iter {
|
|
||||||
try!(key.serialize(self));
|
|
||||||
try!(value.serialize(self));
|
|
||||||
}
|
|
||||||
self.serialize(Token::MapEnd)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_tokens_int() {
|
|
||||||
let tokens = vec!(
|
|
||||||
Token::Isize(5)
|
|
||||||
);
|
|
||||||
let mut serializer = AssertSerializer::new(tokens.into_iter());
|
|
||||||
5is.serialize(&mut serializer).unwrap();
|
|
||||||
assert_eq!(serializer.iter.next(), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_tokens_str() {
|
|
||||||
let tokens = vec!(
|
|
||||||
Token::Str("a"),
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut serializer = AssertSerializer::new(tokens.into_iter());
|
|
||||||
"a".serialize(&mut serializer).unwrap();
|
|
||||||
assert_eq!(serializer.iter.next(), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_tokens_null() {
|
|
||||||
let tokens = vec!(
|
|
||||||
Token::Null,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut serializer = AssertSerializer::new(tokens.into_iter());
|
|
||||||
().serialize(&mut serializer).unwrap();
|
|
||||||
assert_eq!(serializer.iter.next(), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_tokens_option_none() {
|
|
||||||
let tokens = vec!(
|
|
||||||
Token::Option(false),
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut serializer = AssertSerializer::new(tokens.into_iter());
|
|
||||||
None::<isize>.serialize(&mut serializer).unwrap();
|
|
||||||
assert_eq!(serializer.iter.next(), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_tokens_option_some() {
|
|
||||||
let tokens = vec!(
|
|
||||||
Token::Option(true),
|
|
||||||
Token::Isize(5),
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut serializer = AssertSerializer::new(tokens.into_iter());
|
|
||||||
Some(5is).serialize(&mut serializer).unwrap();
|
|
||||||
assert_eq!(serializer.iter.next(), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_tokens_tuple() {
|
|
||||||
let tokens = vec!(
|
|
||||||
Token::TupleStart(2),
|
|
||||||
Token::TupleSep,
|
|
||||||
Token::Isize(5),
|
|
||||||
|
|
||||||
Token::TupleSep,
|
|
||||||
Token::Str("a"),
|
|
||||||
Token::TupleEnd,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut serializer = AssertSerializer::new(tokens.into_iter());
|
|
||||||
(5is, "a").serialize(&mut serializer).unwrap();
|
|
||||||
assert_eq!(serializer.iter.next(), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_tokens_tuple_compound() {
|
|
||||||
let tokens = vec!(
|
|
||||||
Token::TupleStart(3),
|
|
||||||
Token::TupleSep,
|
|
||||||
Token::Null,
|
|
||||||
|
|
||||||
Token::TupleSep,
|
|
||||||
Token::Null,
|
|
||||||
|
|
||||||
Token::TupleSep,
|
|
||||||
Token::TupleStart(2),
|
|
||||||
Token::TupleSep,
|
|
||||||
Token::Isize(5),
|
|
||||||
|
|
||||||
Token::TupleSep,
|
|
||||||
Token::Str("a"),
|
|
||||||
Token::TupleEnd,
|
|
||||||
Token::TupleEnd,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut serializer = AssertSerializer::new(tokens.into_iter());
|
|
||||||
((), (), (5is, "a")).serialize(&mut serializer).unwrap();
|
|
||||||
assert_eq!(serializer.iter.next(), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_tokens_struct_empty() {
|
|
||||||
let tokens = vec!(
|
|
||||||
Token::StructStart("Outer", 1),
|
|
||||||
Token::StructSep("inner"),
|
|
||||||
Token::SeqStart(0),
|
|
||||||
Token::SeqEnd,
|
|
||||||
Token::StructEnd,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut serializer = AssertSerializer::new(tokens.into_iter());
|
|
||||||
Outer { inner: vec!() }.serialize(&mut serializer).unwrap();
|
|
||||||
assert_eq!(serializer.iter.next(), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_tokens_struct() {
|
|
||||||
let tokens = vec!(
|
|
||||||
Token::StructStart("Outer", 1),
|
|
||||||
Token::StructSep("inner"),
|
|
||||||
Token::SeqStart(1),
|
|
||||||
Token::StructStart("Inner", 3),
|
|
||||||
Token::StructSep("a"),
|
|
||||||
Token::Null,
|
|
||||||
|
|
||||||
Token::StructSep("b"),
|
|
||||||
Token::Usize(5),
|
|
||||||
|
|
||||||
Token::StructSep("c"),
|
|
||||||
Token::MapStart(1),
|
|
||||||
Token::Str("abc"),
|
|
||||||
Token::Option(true),
|
|
||||||
Token::Char('c'),
|
|
||||||
Token::MapEnd,
|
|
||||||
Token::StructEnd,
|
|
||||||
Token::SeqEnd,
|
|
||||||
Token::StructEnd,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut serializer = AssertSerializer::new(tokens.into_iter());
|
|
||||||
|
|
||||||
let mut map = HashMap::new();
|
|
||||||
map.insert("abc".to_string(), Some('c'));
|
|
||||||
|
|
||||||
Outer {
|
|
||||||
inner: vec!(
|
|
||||||
Inner {
|
|
||||||
a: (),
|
|
||||||
b: 5,
|
|
||||||
c: map,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}.serialize(&mut serializer).unwrap();
|
|
||||||
assert_eq!(serializer.iter.next(), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_tokens_enum() {
|
|
||||||
let tokens = vec!(
|
|
||||||
Token::EnumStart("Animal", "Dog", 0),
|
|
||||||
Token::EnumEnd,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut serializer = AssertSerializer::new(tokens.into_iter());
|
|
||||||
Animal::Dog.serialize(&mut serializer).unwrap();
|
|
||||||
assert_eq!(serializer.iter.next(), None);
|
|
||||||
|
|
||||||
let tokens = vec!(
|
|
||||||
Token::EnumStart("Animal", "Frog", 2),
|
|
||||||
Token::EnumSep,
|
|
||||||
Token::Str("Henry"),
|
|
||||||
|
|
||||||
Token::EnumSep,
|
|
||||||
Token::Isize(349),
|
|
||||||
Token::EnumEnd,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut serializer = AssertSerializer::new(tokens.into_iter());
|
|
||||||
Animal::Frog("Henry".to_string(), 349).serialize(&mut serializer).unwrap();
|
|
||||||
assert_eq!(serializer.iter.next(), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_tokens_vec_empty() {
|
|
||||||
let tokens = vec!(
|
|
||||||
Token::SeqStart(0),
|
|
||||||
Token::SeqEnd,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut serializer = AssertSerializer::new(tokens.into_iter());
|
|
||||||
let v: Vec<isize> = vec!();
|
|
||||||
v.serialize(&mut serializer).unwrap();
|
|
||||||
assert_eq!(serializer.iter.next(), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_tokens_vec() {
|
|
||||||
let tokens = vec!(
|
|
||||||
Token::SeqStart(3),
|
|
||||||
Token::Isize(5),
|
|
||||||
Token::Isize(6),
|
|
||||||
Token::Isize(7),
|
|
||||||
Token::SeqEnd,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut serializer = AssertSerializer::new(tokens.into_iter());
|
|
||||||
(vec!(5is, 6, 7)).serialize(&mut serializer).unwrap();
|
|
||||||
assert_eq!(serializer.iter.next(), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_tokens_vec_compound() {
|
|
||||||
let tokens = vec!(
|
|
||||||
Token::SeqStart(3),
|
|
||||||
Token::SeqStart(1),
|
|
||||||
Token::Isize(1),
|
|
||||||
Token::SeqEnd,
|
|
||||||
|
|
||||||
Token::SeqStart(2),
|
|
||||||
Token::Isize(2),
|
|
||||||
Token::Isize(3),
|
|
||||||
Token::SeqEnd,
|
|
||||||
|
|
||||||
Token::SeqStart(3),
|
|
||||||
Token::Isize(4),
|
|
||||||
Token::Isize(5),
|
|
||||||
Token::Isize(6),
|
|
||||||
Token::SeqEnd,
|
|
||||||
Token::SeqEnd,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut serializer = AssertSerializer::new(tokens.into_iter());
|
|
||||||
(vec!(vec!(1is), vec!(2, 3), vec!(4, 5, 6))).serialize(&mut serializer).unwrap();
|
|
||||||
assert_eq!(serializer.iter.next(), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_tokens_treemap() {
|
|
||||||
let tokens = vec!(
|
|
||||||
Token::MapStart(2),
|
|
||||||
Token::Isize(5),
|
|
||||||
Token::Str("a"),
|
|
||||||
|
|
||||||
Token::Isize(6),
|
|
||||||
Token::Str("b"),
|
|
||||||
Token::MapEnd,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut serializer = AssertSerializer::new(tokens.into_iter());
|
|
||||||
|
|
||||||
let mut map = BTreeMap::new();
|
|
||||||
map.insert(5is, "a".to_string());
|
|
||||||
map.insert(6is, "b".to_string());
|
|
||||||
|
|
||||||
map.serialize(&mut serializer).unwrap();
|
|
||||||
assert_eq!(serializer.iter.next(), None);
|
|
||||||
}
|
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
#![feature(custom_derive, plugin, test)]
|
#![feature(custom_derive, plugin, test)]
|
||||||
#![plugin(serde2_macros)]
|
#![plugin(serde_macros)]
|
||||||
|
|
||||||
extern crate test;
|
extern crate test;
|
||||||
extern crate serde2;
|
extern crate serde;
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
use serde2::de::{self, Deserialize, Deserializer, Visitor};
|
use serde::de::{self, Deserialize, Deserializer, Visitor};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum Token<'a> {
|
enum Token<'a> {
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
#![feature(custom_derive, plugin, test)]
|
#![feature(custom_derive, plugin, test)]
|
||||||
#![plugin(serde2_macros)]
|
#![plugin(serde_macros)]
|
||||||
|
|
||||||
extern crate test;
|
extern crate test;
|
||||||
extern crate serde2;
|
extern crate serde;
|
||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use serde2::de;
|
use serde::de;
|
||||||
use serde2::ser;
|
use serde::ser;
|
||||||
|
|
||||||
use serde2::json::{
|
use serde::json::{
|
||||||
self,
|
self,
|
||||||
Value,
|
Value,
|
||||||
from_str,
|
from_str,
|
||||||
@@ -18,7 +18,7 @@ use serde2::json::{
|
|||||||
to_value,
|
to_value,
|
||||||
};
|
};
|
||||||
|
|
||||||
use serde2::json::error::{Error, ErrorCode};
|
use serde::json::error::{Error, ErrorCode};
|
||||||
|
|
||||||
macro_rules! treemap {
|
macro_rules! treemap {
|
||||||
($($k:expr => $v:expr),*) => ({
|
($($k:expr => $v:expr),*) => ({
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
extern crate serde2;
|
extern crate serde;
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use serde2::json::value::Value;
|
use serde::json::value::Value;
|
||||||
use serde2::json::builder::{ArrayBuilder, ObjectBuilder};
|
use serde::json::builder::{ArrayBuilder, ObjectBuilder};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_array_builder() {
|
fn test_array_builder() {
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
#![feature(custom_derive, plugin)]
|
#![feature(custom_derive, plugin)]
|
||||||
#![plugin(serde2_macros)]
|
#![plugin(serde_macros)]
|
||||||
|
|
||||||
extern crate serde2;
|
extern crate serde;
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use serde2::json::{self, Value};
|
use serde::json::{self, Value};
|
||||||
|
|
||||||
macro_rules! btreemap {
|
macro_rules! btreemap {
|
||||||
() => {
|
() => {
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
#![feature(custom_derive, plugin, test)]
|
#![feature(custom_derive, plugin, test)]
|
||||||
#![plugin(serde2_macros)]
|
#![plugin(serde_macros)]
|
||||||
|
|
||||||
extern crate test;
|
extern crate test;
|
||||||
extern crate serde2;
|
extern crate serde;
|
||||||
|
|
||||||
use std::vec;
|
use std::vec;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use serde2::ser::{Serialize, Serializer, Visitor, SeqVisitor, MapVisitor};
|
use serde::ser::{Serialize, Serializer, Visitor, SeqVisitor, MapVisitor};
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub enum Token<'a> {
|
pub enum Token<'a> {
|
||||||
Reference in New Issue
Block a user