2014-06-08 14:52:40 -07:00
|
|
|
// 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.
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-08-04 16:53:21 -07:00
|
|
|
use std::collections::{HashMap, HashSet, TreeMap, TreeSet};
|
2014-05-16 07:15:02 -07:00
|
|
|
use std::hash::Hash;
|
2014-05-19 09:48:58 -07:00
|
|
|
use std::num;
|
2014-08-04 16:38:43 -07:00
|
|
|
use std::rc::Rc;
|
2014-09-29 21:50:24 -04:00
|
|
|
use std::option;
|
|
|
|
use std::string;
|
2014-08-04 16:38:43 -07:00
|
|
|
use std::sync::Arc;
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-05-31 12:28:30 -07:00
|
|
|
#[deriving(Clone, PartialEq, Show)]
|
2014-05-16 07:15:02 -07:00
|
|
|
pub enum Token {
|
2014-05-16 21:21:05 -07:00
|
|
|
Null,
|
|
|
|
Bool(bool),
|
2014-05-16 07:15:02 -07:00
|
|
|
Int(int),
|
2014-05-19 07:18:35 -07:00
|
|
|
I8(i8),
|
|
|
|
I16(i16),
|
|
|
|
I32(i32),
|
|
|
|
I64(i64),
|
|
|
|
Uint(uint),
|
|
|
|
U8(u8),
|
|
|
|
U16(u16),
|
|
|
|
U32(u32),
|
|
|
|
U64(u64),
|
|
|
|
F32(f32),
|
2014-05-16 21:21:05 -07:00
|
|
|
F64(f64),
|
2014-05-19 07:18:35 -07:00
|
|
|
Char(char),
|
|
|
|
Str(&'static str),
|
2014-09-29 21:50:24 -04:00
|
|
|
String(string::String),
|
2014-05-19 19:41:38 -07:00
|
|
|
Option(bool),
|
2014-05-20 19:22:23 -07:00
|
|
|
|
|
|
|
TupleStart(uint),
|
2014-05-28 10:46:29 -07:00
|
|
|
StructStart(&'static str, uint),
|
|
|
|
EnumStart(&'static str, &'static str, uint),
|
2014-05-20 19:22:23 -07:00
|
|
|
SeqStart(uint),
|
|
|
|
MapStart(uint),
|
|
|
|
|
|
|
|
End,
|
2014-05-16 07:15:02 -07:00
|
|
|
}
|
|
|
|
|
2014-08-06 22:24:06 -04:00
|
|
|
impl Token {
|
|
|
|
pub fn to_kind(&self) -> TokenKind {
|
|
|
|
match *self {
|
|
|
|
Null => NullKind,
|
|
|
|
Bool(_) => BoolKind,
|
|
|
|
Int(_) => IntKind,
|
|
|
|
I8(_) => I8Kind,
|
|
|
|
I16(_) => I16Kind,
|
|
|
|
I32(_) => I32Kind,
|
|
|
|
I64(_) => I64Kind,
|
|
|
|
Uint(_) => UintKind,
|
|
|
|
U8(_) => U8Kind,
|
|
|
|
U16(_) => U16Kind,
|
|
|
|
U32(_) => U32Kind,
|
|
|
|
U64(_) => U64Kind,
|
|
|
|
F32(_) => F32Kind,
|
|
|
|
F64(_) => F64Kind,
|
|
|
|
Char(_) => CharKind,
|
|
|
|
Str(_) => StrKind,
|
|
|
|
String(_) => StringKind,
|
|
|
|
Option(_) => OptionKind,
|
|
|
|
TupleStart(_) => TupleStartKind,
|
|
|
|
StructStart(_, _) => StructStartKind,
|
|
|
|
EnumStart(_, _, _) => EnumStartKind,
|
|
|
|
SeqStart(_) => SeqStartKind,
|
|
|
|
MapStart(_) => MapStartKind,
|
|
|
|
End => EndKind,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[deriving(Clone, PartialEq, Eq)]
|
|
|
|
pub enum TokenKind {
|
|
|
|
NullKind,
|
|
|
|
BoolKind,
|
|
|
|
IntKind,
|
|
|
|
I8Kind,
|
|
|
|
I16Kind,
|
|
|
|
I32Kind,
|
|
|
|
I64Kind,
|
|
|
|
UintKind,
|
|
|
|
U8Kind,
|
|
|
|
U16Kind,
|
|
|
|
U32Kind,
|
|
|
|
U64Kind,
|
|
|
|
F32Kind,
|
|
|
|
F64Kind,
|
|
|
|
CharKind,
|
|
|
|
StrKind,
|
|
|
|
StringKind,
|
|
|
|
OptionKind,
|
|
|
|
|
|
|
|
TupleStartKind,
|
|
|
|
StructStartKind,
|
|
|
|
EnumStartKind,
|
|
|
|
SeqStartKind,
|
|
|
|
MapStartKind,
|
|
|
|
|
|
|
|
EndKind,
|
|
|
|
}
|
|
|
|
|
2014-10-06 21:50:22 -07:00
|
|
|
static PRIMITIVE_TOKEN_KINDS: [TokenKind, .. 12] = [
|
2014-08-06 22:24:06 -04:00
|
|
|
IntKind,
|
|
|
|
I8Kind,
|
|
|
|
I16Kind,
|
|
|
|
I32Kind,
|
|
|
|
I64Kind,
|
|
|
|
UintKind,
|
|
|
|
U8Kind,
|
|
|
|
U16Kind,
|
|
|
|
U32Kind,
|
|
|
|
U64Kind,
|
|
|
|
F32Kind,
|
|
|
|
F64Kind,
|
|
|
|
];
|
|
|
|
|
2014-10-06 21:50:22 -07:00
|
|
|
static STR_TOKEN_KINDS: [TokenKind, .. 2] = [
|
2014-08-06 22:24:06 -04:00
|
|
|
StrKind,
|
|
|
|
StringKind,
|
|
|
|
];
|
|
|
|
|
2014-10-06 21:50:22 -07:00
|
|
|
static COMPOUND_TOKEN_KINDS: [TokenKind, .. 6] = [
|
2014-08-06 22:24:06 -04:00
|
|
|
OptionKind,
|
|
|
|
EnumStartKind,
|
|
|
|
StructStartKind,
|
|
|
|
TupleStartKind,
|
|
|
|
SeqStartKind,
|
|
|
|
MapStartKind,
|
|
|
|
];
|
|
|
|
|
|
|
|
impl ::std::fmt::Show for TokenKind {
|
|
|
|
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
|
|
|
match *self {
|
|
|
|
NullKind => "Null".fmt(f),
|
|
|
|
BoolKind => "Bool".fmt(f),
|
|
|
|
IntKind => "Int".fmt(f),
|
|
|
|
I8Kind => "I8".fmt(f),
|
|
|
|
I16Kind => "I16".fmt(f),
|
|
|
|
I32Kind => "I32".fmt(f),
|
|
|
|
I64Kind => "I64".fmt(f),
|
|
|
|
UintKind => "Uint".fmt(f),
|
|
|
|
U8Kind => "U8".fmt(f),
|
|
|
|
U16Kind => "U16".fmt(f),
|
|
|
|
U32Kind => "U32".fmt(f),
|
|
|
|
U64Kind => "U64".fmt(f),
|
|
|
|
F32Kind => "F32".fmt(f),
|
|
|
|
F64Kind => "F64".fmt(f),
|
|
|
|
CharKind => "Char".fmt(f),
|
|
|
|
StrKind => "Str".fmt(f),
|
|
|
|
StringKind => "String".fmt(f),
|
|
|
|
OptionKind => "Option".fmt(f),
|
|
|
|
TupleStartKind => "TupleStart".fmt(f),
|
|
|
|
StructStartKind => "StructStart".fmt(f),
|
|
|
|
EnumStartKind => "EnumStart".fmt(f),
|
|
|
|
SeqStartKind => "SeqStart".fmt(f),
|
|
|
|
MapStartKind => "MapStart".fmt(f),
|
|
|
|
EndKind => "End".fmt(f),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-19 07:18:35 -07:00
|
|
|
macro_rules! to_result {
|
|
|
|
($expr:expr, $err:expr) => {
|
|
|
|
match $expr {
|
|
|
|
Some(value) => Ok(value),
|
2014-08-06 22:24:06 -04:00
|
|
|
None => Err($err),
|
2014-05-19 07:18:35 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-16 07:15:02 -07:00
|
|
|
pub trait Deserializer<E>: Iterator<Result<Token, E>> {
|
2014-08-18 07:39:34 -07:00
|
|
|
/// Called when a `Deserializable` expected more tokens, but the
|
|
|
|
/// `Deserializer` was empty.
|
|
|
|
fn end_of_stream_error(&mut self) -> E;
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-08-18 07:39:34 -07:00
|
|
|
/// Called when a `Deserializer` was unable to properly parse the stream.
|
|
|
|
fn syntax_error(&mut self, token: Token, expected: &[TokenKind]) -> E;
|
2014-08-06 22:24:06 -04:00
|
|
|
|
2014-08-18 07:39:34 -07:00
|
|
|
/// Called when a named structure or enum got a name that it didn't expect.
|
|
|
|
fn unexpected_name_error(&mut self, token: Token) -> E;
|
2014-08-06 22:24:06 -04:00
|
|
|
|
2014-08-18 07:39:34 -07:00
|
|
|
/// Called when a value was unable to be coerced into another value.
|
|
|
|
fn conversion_error(&mut self, token: Token) -> E;
|
2014-08-03 12:35:15 -07:00
|
|
|
|
2014-08-18 07:39:34 -07:00
|
|
|
/// Called when a `Deserializable` structure did not deserialize a field
|
|
|
|
/// named `field`.
|
2014-08-18 07:37:44 -07:00
|
|
|
fn missing_field<
|
2014-08-19 15:18:47 -07:00
|
|
|
T: Deserializable<Self, E>
|
2014-08-18 07:37:44 -07:00
|
|
|
>(&mut self, field: &'static str) -> Result<T, E>;
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-08-18 07:40:15 -07:00
|
|
|
/// Called when a deserializable has decided to not consume this token.
|
|
|
|
fn ignore_field(&mut self, _token: Token) -> Result<(), E> {
|
|
|
|
let _: IgnoreTokens = try!(Deserializable::deserialize(self));
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2014-05-27 07:21:37 -07:00
|
|
|
#[inline]
|
|
|
|
fn expect_token(&mut self) -> Result<Token, E> {
|
|
|
|
match self.next() {
|
|
|
|
Some(Ok(token)) => Ok(token),
|
|
|
|
Some(Err(err)) => Err(err),
|
2014-08-05 23:02:15 -04:00
|
|
|
None => Err(self.end_of_stream_error()),
|
2014-05-27 07:21:37 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-19 07:55:05 -07:00
|
|
|
#[inline]
|
2014-05-23 22:30:53 -07:00
|
|
|
fn expect_null(&mut self, token: Token) -> Result<(), E> {
|
|
|
|
match token {
|
2014-05-19 07:18:35 -07:00
|
|
|
Null => Ok(()),
|
2014-08-14 19:08:41 -07:00
|
|
|
TupleStart(_) | SeqStart(_) => {
|
2014-05-27 07:21:37 -07:00
|
|
|
match try!(self.expect_token()) {
|
|
|
|
End => Ok(()),
|
2014-08-06 22:24:06 -04:00
|
|
|
token => Err(self.syntax_error(token, [EndKind])),
|
2014-05-20 19:22:23 -07:00
|
|
|
}
|
|
|
|
}
|
2014-08-14 19:08:41 -07:00
|
|
|
token => Err(self.syntax_error(token, [NullKind, TupleStartKind, SeqStartKind])),
|
2014-05-19 19:41:38 -07:00
|
|
|
}
|
2014-05-16 21:21:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-05-25 21:59:58 -07:00
|
|
|
fn expect_bool(&mut self, token: Token) -> Result<bool, E> {
|
|
|
|
match token {
|
|
|
|
Bool(value) => Ok(value),
|
2014-08-06 22:24:06 -04:00
|
|
|
token => Err(self.syntax_error(token, [BoolKind])),
|
2014-05-19 19:41:38 -07:00
|
|
|
}
|
2014-05-16 21:21:05 -07:00
|
|
|
}
|
|
|
|
|
2014-05-16 07:15:02 -07:00
|
|
|
#[inline]
|
2014-05-23 22:30:53 -07:00
|
|
|
fn expect_num<T: NumCast>(&mut self, token: Token) -> Result<T, E> {
|
|
|
|
match token {
|
2014-10-06 21:50:22 -07:00
|
|
|
Int(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)),
|
|
|
|
I8(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)),
|
|
|
|
I16(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)),
|
|
|
|
I32(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)),
|
|
|
|
I64(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)),
|
|
|
|
Uint(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)),
|
|
|
|
U8(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)),
|
|
|
|
U16(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)),
|
|
|
|
U32(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)),
|
|
|
|
U64(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)),
|
|
|
|
F32(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)),
|
|
|
|
F64(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)),
|
|
|
|
token => Err(self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)),
|
2014-08-03 12:35:15 -07:00
|
|
|
}
|
|
|
|
}
|
2014-08-03 12:34:57 -07:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn expect_from_primitive<T: FromPrimitive>(&mut self, token: Token) -> Result<T, E> {
|
|
|
|
match token {
|
2014-08-06 22:24:06 -04:00
|
|
|
Int(x) => to_result!(num::from_int(x), self.conversion_error(token)),
|
|
|
|
I8(x) => to_result!(num::from_i8(x), self.conversion_error(token)),
|
|
|
|
I16(x) => to_result!(num::from_i16(x), self.conversion_error(token)),
|
|
|
|
I32(x) => to_result!(num::from_i32(x), self.conversion_error(token)),
|
|
|
|
I64(x) => to_result!(num::from_i64(x), self.conversion_error(token)),
|
|
|
|
Uint(x) => to_result!(num::from_uint(x), self.conversion_error(token)),
|
|
|
|
U8(x) => to_result!(num::from_u8(x), self.conversion_error(token)),
|
|
|
|
U16(x) => to_result!(num::from_u16(x), self.conversion_error(token)),
|
|
|
|
U32(x) => to_result!(num::from_u32(x), self.conversion_error(token)),
|
|
|
|
U64(x) => to_result!(num::from_u64(x), self.conversion_error(token)),
|
|
|
|
F32(x) => to_result!(num::from_f32(x), self.conversion_error(token)),
|
|
|
|
F64(x) => to_result!(num::from_f64(x), self.conversion_error(token)),
|
2014-10-06 21:50:22 -07:00
|
|
|
token => Err(self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)),
|
2014-05-19 09:48:58 -07:00
|
|
|
}
|
2014-05-16 21:21:05 -07:00
|
|
|
}
|
|
|
|
|
2014-05-16 07:15:02 -07:00
|
|
|
#[inline]
|
2014-05-25 21:59:58 -07:00
|
|
|
fn expect_char(&mut self, token: Token) -> Result<char, E> {
|
|
|
|
match token {
|
|
|
|
Char(value) => Ok(value),
|
2014-08-06 22:24:06 -04:00
|
|
|
Str(value) if value.char_len() == 1 => {
|
|
|
|
Ok(value.char_at(0))
|
|
|
|
}
|
|
|
|
String(ref value) if value.as_slice().char_len() == 1 => {
|
|
|
|
Ok(value.as_slice().char_at(0))
|
|
|
|
}
|
|
|
|
token => Err(self.syntax_error(token, [CharKind])),
|
2014-05-19 19:41:38 -07:00
|
|
|
}
|
2014-05-19 07:18:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-05-25 21:59:58 -07:00
|
|
|
fn expect_str(&mut self, token: Token) -> Result<&'static str, E> {
|
|
|
|
match token {
|
|
|
|
Str(value) => Ok(value),
|
2014-10-06 21:50:22 -07:00
|
|
|
token => Err(self.syntax_error(token, STR_TOKEN_KINDS)),
|
2014-05-19 19:41:38 -07:00
|
|
|
}
|
2014-05-19 07:18:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-09-29 21:50:24 -04:00
|
|
|
fn expect_string(&mut self, token: Token) -> Result<string::String, E> {
|
2014-05-24 14:08:35 -07:00
|
|
|
match token {
|
2014-08-06 22:24:06 -04:00
|
|
|
Char(value) => Ok(value.to_string()),
|
2014-05-29 06:44:38 -07:00
|
|
|
Str(value) => Ok(value.to_string()),
|
2014-05-26 07:18:18 -07:00
|
|
|
String(value) => Ok(value),
|
2014-10-06 21:50:22 -07:00
|
|
|
token => Err(self.syntax_error(token, STR_TOKEN_KINDS)),
|
2014-05-19 19:41:38 -07:00
|
|
|
}
|
2014-05-16 07:15:02 -07:00
|
|
|
}
|
|
|
|
|
2014-05-19 07:55:05 -07:00
|
|
|
#[inline]
|
|
|
|
fn expect_option<
|
2014-08-19 15:18:47 -07:00
|
|
|
T: Deserializable<Self, E>
|
2014-09-29 21:50:24 -04:00
|
|
|
>(&mut self, token: Token) -> Result<option::Option<T>, E> {
|
2014-05-25 21:59:58 -07:00
|
|
|
match token {
|
2014-05-19 19:41:38 -07:00
|
|
|
Option(false) => Ok(None),
|
|
|
|
Option(true) => {
|
|
|
|
let value: T = try!(Deserializable::deserialize(self));
|
2014-05-19 09:47:16 -07:00
|
|
|
Ok(Some(value))
|
|
|
|
}
|
2014-08-06 22:24:06 -04:00
|
|
|
token => Err(self.syntax_error(token, [OptionKind])),
|
2014-05-19 07:55:05 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-16 07:15:02 -07:00
|
|
|
#[inline]
|
2014-06-22 16:51:50 -04:00
|
|
|
fn expect_tuple_start(&mut self, token: Token) -> Result<uint, E> {
|
2014-05-23 22:30:53 -07:00
|
|
|
match token {
|
2014-06-22 16:51:50 -04:00
|
|
|
TupleStart(len) => Ok(len),
|
2014-08-14 19:03:23 -07:00
|
|
|
SeqStart(len) => Ok(len),
|
|
|
|
token => Err(self.syntax_error(token, [TupleStartKind, SeqStartKind])),
|
2014-05-20 19:22:23 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-28 08:39:02 -07:00
|
|
|
#[inline]
|
2014-08-03 12:35:15 -07:00
|
|
|
fn expect_tuple_elt<
|
2014-08-19 15:18:47 -07:00
|
|
|
T: Deserializable<Self, E>
|
2014-06-28 08:39:02 -07:00
|
|
|
>(&mut self) -> Result<T, E> {
|
|
|
|
Deserializable::deserialize(self)
|
|
|
|
}
|
|
|
|
|
2014-06-09 07:51:53 -07:00
|
|
|
#[inline]
|
|
|
|
fn expect_tuple_end(&mut self) -> Result<(), E> {
|
|
|
|
match try!(self.expect_token()) {
|
|
|
|
End => Ok(()),
|
2014-08-06 22:24:06 -04:00
|
|
|
token => Err(self.syntax_error(token, [EndKind])),
|
2014-06-09 07:51:53 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-21 08:25:28 -07:00
|
|
|
#[inline]
|
2014-05-25 21:59:58 -07:00
|
|
|
fn expect_struct_start(&mut self, token: Token, name: &str) -> Result<(), E> {
|
|
|
|
match token {
|
2014-05-28 10:46:29 -07:00
|
|
|
StructStart(n, _) => {
|
2014-05-21 08:25:28 -07:00
|
|
|
if name == n {
|
|
|
|
Ok(())
|
|
|
|
} else {
|
2014-08-06 22:24:06 -04:00
|
|
|
Err(self.unexpected_name_error(token))
|
2014-05-21 08:25:28 -07:00
|
|
|
}
|
|
|
|
}
|
2014-08-06 22:24:06 -04:00
|
|
|
_ => Err(self.syntax_error(token, [StructStartKind])),
|
2014-05-21 08:25:28 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-10-22 18:22:42 -07:00
|
|
|
fn expect_struct_field_or_end(&mut self,
|
|
|
|
fields: &'static [&'static str]
|
|
|
|
) -> Result<option::Option<option::Option<uint>>, E> {
|
2014-05-27 07:21:37 -07:00
|
|
|
match try!(self.expect_token()) {
|
2014-10-22 18:22:42 -07:00
|
|
|
End => {
|
|
|
|
Ok(None)
|
|
|
|
}
|
2014-05-26 08:26:34 -07:00
|
|
|
Str(n) => {
|
2014-11-07 18:23:44 -02:00
|
|
|
Ok(Some(fields.iter().position(|field| *field == n)))
|
2014-05-21 08:25:28 -07:00
|
|
|
}
|
2014-05-26 08:26:34 -07:00
|
|
|
String(n) => {
|
2014-11-07 18:23:44 -02:00
|
|
|
Ok(Some(fields.iter().position(|field| *field == n.as_slice())))
|
2014-05-26 08:26:34 -07:00
|
|
|
}
|
2014-08-05 23:02:15 -04:00
|
|
|
token => {
|
2014-10-22 18:22:42 -07:00
|
|
|
Err(self.syntax_error(token, STR_TOKEN_KINDS))
|
2014-08-05 23:02:15 -04:00
|
|
|
}
|
2014-05-21 08:25:28 -07:00
|
|
|
}
|
2014-10-22 18:22:42 -07:00
|
|
|
}
|
2014-05-26 08:26:34 -07:00
|
|
|
|
2014-10-22 18:22:42 -07:00
|
|
|
#[inline]
|
|
|
|
fn expect_struct_value<
|
|
|
|
T: Deserializable<Self, E>
|
|
|
|
>(&mut self) -> Result<T, E> {
|
2014-05-26 08:26:34 -07:00
|
|
|
Deserializable::deserialize(self)
|
2014-05-21 08:25:28 -07:00
|
|
|
}
|
|
|
|
|
2014-06-09 07:51:53 -07:00
|
|
|
#[inline]
|
|
|
|
fn expect_struct_end(&mut self) -> Result<(), E> {
|
|
|
|
match try!(self.expect_token()) {
|
|
|
|
End => Ok(()),
|
2014-08-06 22:24:06 -04:00
|
|
|
token => Err(self.syntax_error(token, [EndKind])),
|
2014-06-09 07:51:53 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-21 08:44:48 -07:00
|
|
|
#[inline]
|
2014-05-28 10:46:29 -07:00
|
|
|
fn expect_enum_start(&mut self, token: Token, name: &str, variants: &[&str]) -> Result<uint, E> {
|
2014-05-24 14:08:35 -07:00
|
|
|
match token {
|
2014-05-28 10:46:29 -07:00
|
|
|
EnumStart(n, v, _) => {
|
2014-05-21 08:44:48 -07:00
|
|
|
if name == n {
|
2014-05-24 14:11:25 -07:00
|
|
|
match variants.iter().position(|variant| *variant == v) {
|
|
|
|
Some(position) => Ok(position),
|
2014-08-06 22:24:06 -04:00
|
|
|
None => Err(self.unexpected_name_error(token)),
|
2014-05-21 08:44:48 -07:00
|
|
|
}
|
|
|
|
} else {
|
2014-08-06 22:24:06 -04:00
|
|
|
Err(self.unexpected_name_error(token))
|
2014-05-21 08:44:48 -07:00
|
|
|
}
|
|
|
|
}
|
2014-08-06 22:24:06 -04:00
|
|
|
token => Err(self.syntax_error(token, [EnumStartKind])),
|
2014-05-21 08:44:48 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-28 08:39:02 -07:00
|
|
|
#[inline]
|
2014-07-27 20:16:18 -07:00
|
|
|
fn expect_enum_elt<
|
2014-08-19 15:18:47 -07:00
|
|
|
T: Deserializable<Self, E>
|
2014-06-28 08:39:02 -07:00
|
|
|
>(&mut self) -> Result<T, E> {
|
|
|
|
Deserializable::deserialize(self)
|
|
|
|
}
|
|
|
|
|
2014-06-09 07:51:53 -07:00
|
|
|
#[inline]
|
|
|
|
fn expect_enum_end(&mut self) -> Result<(), E> {
|
|
|
|
match try!(self.expect_token()) {
|
|
|
|
End => Ok(()),
|
2014-08-06 22:24:06 -04:00
|
|
|
token => Err(self.syntax_error(token, [EndKind])),
|
2014-06-09 07:51:53 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-28 11:34:46 -07:00
|
|
|
#[inline]
|
|
|
|
fn expect_seq_start(&mut self, token: Token) -> Result<uint, E> {
|
|
|
|
match token {
|
|
|
|
TupleStart(len) => Ok(len),
|
|
|
|
SeqStart(len) => Ok(len),
|
2014-08-06 22:24:06 -04:00
|
|
|
token => Err(self.syntax_error(token, [TupleStartKind, SeqStartKind])),
|
2014-06-28 11:34:46 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn expect_seq_elt_or_end<
|
2014-08-19 15:18:47 -07:00
|
|
|
T: Deserializable<Self, E>
|
2014-09-29 21:50:24 -04:00
|
|
|
>(&mut self) -> Result<option::Option<T>, E> {
|
2014-06-28 11:34:46 -07:00
|
|
|
match try!(self.expect_token()) {
|
|
|
|
End => Ok(None),
|
|
|
|
token => {
|
|
|
|
let value = try!(Deserializable::deserialize_token(self, token));
|
|
|
|
Ok(Some(value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-20 19:22:23 -07:00
|
|
|
#[inline]
|
2014-06-23 20:44:24 -04:00
|
|
|
fn expect_seq<
|
|
|
|
'a,
|
2014-08-19 15:18:47 -07:00
|
|
|
T: Deserializable<Self, E>,
|
2014-05-16 07:15:02 -07:00
|
|
|
C: FromIterator<T>
|
2014-06-23 20:44:24 -04:00
|
|
|
>(&'a mut self, token: Token) -> Result<C, E> {
|
2014-06-28 11:34:46 -07:00
|
|
|
let len = try!(self.expect_seq_start(token));
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-06-23 20:44:24 -04:00
|
|
|
let mut d: SeqDeserializer<'a, Self, E> = SeqDeserializer {
|
|
|
|
d: self,
|
|
|
|
len: len,
|
|
|
|
err: None,
|
|
|
|
};
|
|
|
|
|
|
|
|
let collection: C = d.collect();
|
|
|
|
|
|
|
|
match d.err {
|
|
|
|
Some(err) => Err(err),
|
|
|
|
None => Ok(collection),
|
|
|
|
}
|
2014-05-21 06:47:58 -07:00
|
|
|
}
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-06-28 11:34:46 -07:00
|
|
|
#[inline]
|
|
|
|
fn expect_map_start(&mut self, token: Token) -> Result<uint, E> {
|
|
|
|
match token {
|
|
|
|
MapStart(len) => Ok(len),
|
2014-08-06 22:24:06 -04:00
|
|
|
_ => Err(self.syntax_error(token, [MapStartKind])),
|
2014-06-28 11:34:46 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn expect_map_elt_or_end<
|
2014-08-19 15:18:47 -07:00
|
|
|
K: Deserializable<Self, E>,
|
|
|
|
V: Deserializable<Self, E>
|
2014-09-29 21:50:24 -04:00
|
|
|
>(&mut self) -> Result<option::Option<(K, V)>, E> {
|
2014-06-28 11:34:46 -07:00
|
|
|
match try!(self.expect_token()) {
|
|
|
|
End => Ok(None),
|
|
|
|
token => {
|
|
|
|
let key = try!(Deserializable::deserialize_token(self, token));
|
|
|
|
let value = try!(Deserializable::deserialize(self));
|
|
|
|
Ok(Some((key, value)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-21 06:47:58 -07:00
|
|
|
#[inline]
|
2014-06-23 20:44:24 -04:00
|
|
|
fn expect_map<
|
|
|
|
'a,
|
2014-08-19 15:18:47 -07:00
|
|
|
K: Deserializable<Self, E>,
|
|
|
|
V: Deserializable<Self, E>,
|
2014-06-23 20:44:24 -04:00
|
|
|
C: FromIterator<(K, V)>
|
|
|
|
>(&'a mut self, token: Token) -> Result<C, E> {
|
2014-06-28 11:34:46 -07:00
|
|
|
let len = try!(self.expect_map_start(token));
|
2014-06-23 20:44:24 -04:00
|
|
|
|
|
|
|
let mut d: MapDeserializer<'a, Self, E> = MapDeserializer {
|
|
|
|
d: self,
|
|
|
|
len: len,
|
|
|
|
err: None,
|
|
|
|
};
|
|
|
|
|
|
|
|
let collection: C = d.collect();
|
|
|
|
|
|
|
|
match d.err {
|
|
|
|
Some(err) => Err(err),
|
|
|
|
None => Ok(collection),
|
2014-05-25 21:36:56 -07:00
|
|
|
}
|
2014-05-16 07:15:02 -07:00
|
|
|
}
|
2014-06-23 20:44:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-09-04 21:57:13 -04:00
|
|
|
struct SeqDeserializer<'a, D: 'a, E> {
|
2014-06-23 20:44:24 -04:00
|
|
|
d: &'a mut D,
|
|
|
|
len: uint,
|
2014-09-29 21:50:24 -04:00
|
|
|
err: option::Option<E>,
|
2014-06-23 20:44:24 -04:00
|
|
|
}
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-06-23 20:44:24 -04:00
|
|
|
impl<
|
|
|
|
'a,
|
|
|
|
D: Deserializer<E>,
|
2014-08-19 15:18:47 -07:00
|
|
|
E,
|
|
|
|
T: Deserializable<D, E>
|
2014-06-23 20:44:24 -04:00
|
|
|
> Iterator<T> for SeqDeserializer<'a, D, E> {
|
2014-05-16 07:15:02 -07:00
|
|
|
#[inline]
|
2014-09-29 21:50:24 -04:00
|
|
|
fn next(&mut self) -> option::Option<T> {
|
2014-06-28 11:34:46 -07:00
|
|
|
match self.d.expect_seq_elt_or_end() {
|
|
|
|
Ok(next) => next,
|
2014-06-23 20:44:24 -04:00
|
|
|
Err(err) => {
|
|
|
|
self.err = Some(err);
|
|
|
|
None
|
|
|
|
}
|
2014-05-25 22:08:37 -07:00
|
|
|
}
|
2014-05-16 07:15:02 -07:00
|
|
|
}
|
2014-06-23 20:44:24 -04:00
|
|
|
|
|
|
|
#[inline]
|
2014-09-29 21:50:24 -04:00
|
|
|
fn size_hint(&self) -> (uint, option::Option<uint>) {
|
2014-06-23 20:44:24 -04:00
|
|
|
(self.len, Some(self.len))
|
|
|
|
}
|
2014-05-16 07:15:02 -07:00
|
|
|
}
|
|
|
|
|
2014-05-16 21:21:05 -07:00
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-09-04 21:57:13 -04:00
|
|
|
struct MapDeserializer<'a, D:'a, E> {
|
2014-06-23 20:44:24 -04:00
|
|
|
d: &'a mut D,
|
|
|
|
len: uint,
|
2014-09-29 21:50:24 -04:00
|
|
|
err: option::Option<E>,
|
2014-06-23 20:44:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<
|
|
|
|
'a,
|
2014-05-21 06:47:58 -07:00
|
|
|
D: Deserializer<E>,
|
2014-08-19 15:18:47 -07:00
|
|
|
E,
|
|
|
|
K: Deserializable<D, E>,
|
|
|
|
V: Deserializable<D, E>
|
2014-06-23 20:44:24 -04:00
|
|
|
> Iterator<(K, V)> for MapDeserializer<'a, D, E> {
|
|
|
|
#[inline]
|
2014-09-29 21:50:24 -04:00
|
|
|
fn next(&mut self) -> option::Option<(K, V)> {
|
2014-06-28 11:34:46 -07:00
|
|
|
match self.d.expect_map_elt_or_end() {
|
|
|
|
Ok(next) => next,
|
2014-06-23 20:44:24 -04:00
|
|
|
Err(err) => {
|
|
|
|
self.err = Some(err);
|
|
|
|
None
|
2014-05-23 20:58:09 -07:00
|
|
|
}
|
2014-05-24 15:02:24 -07:00
|
|
|
}
|
2014-06-23 20:44:24 -04:00
|
|
|
}
|
2014-05-21 06:47:58 -07:00
|
|
|
|
2014-06-23 20:44:24 -04:00
|
|
|
#[inline]
|
2014-09-29 21:50:24 -04:00
|
|
|
fn size_hint(&self) -> (uint, option::Option<uint>) {
|
2014-06-23 20:44:24 -04:00
|
|
|
(self.len, Some(self.len))
|
|
|
|
}
|
2014-05-21 06:47:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-08-19 15:18:47 -07:00
|
|
|
pub trait Deserializable<D: Deserializer<E>, E> {
|
2014-05-23 22:30:53 -07:00
|
|
|
#[inline]
|
2014-08-19 15:18:47 -07:00
|
|
|
fn deserialize(d: &mut D) -> Result<Self, E> {
|
2014-06-22 21:55:07 -04:00
|
|
|
let token = try!(d.expect_token());
|
|
|
|
Deserializable::deserialize_token(d, token)
|
2014-05-23 22:30:53 -07:00
|
|
|
}
|
|
|
|
|
2014-08-19 15:18:47 -07:00
|
|
|
fn deserialize_token(d: &mut D, token: Token) -> Result<Self, E>;
|
2014-05-16 07:15:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-05-19 07:18:35 -07:00
|
|
|
macro_rules! impl_deserializable {
|
2014-05-19 19:41:38 -07:00
|
|
|
($ty:ty, $method:ident) => {
|
2014-08-19 15:18:47 -07:00
|
|
|
impl<D: Deserializer<E>, E> Deserializable<D, E> for $ty {
|
2014-05-19 18:44:20 -07:00
|
|
|
#[inline]
|
2014-08-19 15:18:47 -07:00
|
|
|
fn deserialize_token(d: &mut D, token: Token) -> Result<$ty, E> {
|
2014-05-23 22:30:53 -07:00
|
|
|
d.$method(token)
|
2014-05-19 18:44:20 -07:00
|
|
|
}
|
2014-05-19 07:18:35 -07:00
|
|
|
}
|
2014-05-16 21:21:05 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-25 21:59:58 -07:00
|
|
|
impl_deserializable!(bool, expect_bool)
|
2014-05-19 19:41:38 -07:00
|
|
|
impl_deserializable!(int, expect_num)
|
|
|
|
impl_deserializable!(i8, expect_num)
|
|
|
|
impl_deserializable!(i16, expect_num)
|
|
|
|
impl_deserializable!(i32, expect_num)
|
|
|
|
impl_deserializable!(i64, expect_num)
|
|
|
|
impl_deserializable!(uint, expect_num)
|
|
|
|
impl_deserializable!(u8, expect_num)
|
|
|
|
impl_deserializable!(u16, expect_num)
|
|
|
|
impl_deserializable!(u32, expect_num)
|
|
|
|
impl_deserializable!(u64, expect_num)
|
|
|
|
impl_deserializable!(f32, expect_num)
|
|
|
|
impl_deserializable!(f64, expect_num)
|
|
|
|
impl_deserializable!(char, expect_char)
|
|
|
|
impl_deserializable!(&'static str, expect_str)
|
2014-09-29 21:50:24 -04:00
|
|
|
impl_deserializable!(string::String, expect_string)
|
2014-05-16 07:15:02 -07:00
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-08-19 15:18:47 -07:00
|
|
|
impl<
|
|
|
|
D: Deserializer<E>,
|
|
|
|
E,
|
|
|
|
T: Deserializable<D, E>
|
|
|
|
> Deserializable<D, E> for Box<T> {
|
2014-08-04 16:38:43 -07:00
|
|
|
#[inline]
|
2014-08-19 15:18:47 -07:00
|
|
|
fn deserialize_token(d: &mut D, token: Token) -> Result<Box<T>, E> {
|
2014-08-04 16:38:43 -07:00
|
|
|
Ok(box try!(Deserializable::deserialize_token(d, token)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-19 15:18:47 -07:00
|
|
|
impl<
|
|
|
|
D: Deserializer<E>,
|
|
|
|
E,
|
|
|
|
T: Deserializable<D, E>
|
|
|
|
> Deserializable<D, E> for Rc<T> {
|
2014-08-04 16:38:43 -07:00
|
|
|
#[inline]
|
2014-08-19 15:18:47 -07:00
|
|
|
fn deserialize_token(d: &mut D, token: Token) -> Result<Rc<T>, E> {
|
2014-08-04 16:38:43 -07:00
|
|
|
Ok(Rc::new(try!(Deserializable::deserialize_token(d, token))))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-19 15:18:47 -07:00
|
|
|
impl<
|
|
|
|
D: Deserializer<E>,
|
|
|
|
E,
|
|
|
|
T: Deserializable<D, E> + Send + Sync
|
|
|
|
> Deserializable<D, E> for Arc<T> {
|
2014-08-04 16:38:43 -07:00
|
|
|
#[inline]
|
2014-08-19 15:18:47 -07:00
|
|
|
fn deserialize_token(d: &mut D, token: Token) -> Result<Arc<T>, E> {
|
2014-08-04 16:38:43 -07:00
|
|
|
Ok(Arc::new(try!(Deserializable::deserialize_token(d, token))))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-08-19 15:18:47 -07:00
|
|
|
impl<
|
|
|
|
D: Deserializer<E>,
|
|
|
|
E,
|
|
|
|
T: Deserializable<D ,E>
|
2014-09-29 21:50:24 -04:00
|
|
|
> Deserializable<D, E> for option::Option<T> {
|
2014-05-19 18:44:20 -07:00
|
|
|
#[inline]
|
2014-09-29 21:50:24 -04:00
|
|
|
fn deserialize_token(d: &mut D, token: Token) -> Result<option::Option<T>, E> {
|
2014-05-25 21:59:58 -07:00
|
|
|
d.expect_option(token)
|
2014-05-19 18:44:20 -07:00
|
|
|
}
|
2014-05-16 07:15:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-08-19 15:18:47 -07:00
|
|
|
impl<
|
|
|
|
D: Deserializer<E>,
|
|
|
|
E,
|
|
|
|
T: Deserializable<D ,E>
|
|
|
|
> Deserializable<D, E> for Vec<T> {
|
2014-05-19 18:44:20 -07:00
|
|
|
#[inline]
|
2014-08-19 15:18:47 -07:00
|
|
|
fn deserialize_token(d: &mut D, token: Token) -> Result<Vec<T>, E> {
|
2014-06-23 20:44:24 -04:00
|
|
|
d.expect_seq(token)
|
2014-05-25 22:08:37 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-05-16 07:15:02 -07:00
|
|
|
impl<
|
2014-08-19 15:18:47 -07:00
|
|
|
D: Deserializer<E>,
|
|
|
|
E,
|
|
|
|
K: Deserializable<D, E> + Eq + Hash,
|
|
|
|
V: Deserializable<D, E>
|
|
|
|
> Deserializable<D, E> for HashMap<K, V> {
|
2014-05-19 18:44:20 -07:00
|
|
|
#[inline]
|
2014-08-19 15:18:47 -07:00
|
|
|
fn deserialize_token(d: &mut D, token: Token) -> Result<HashMap<K, V>, E> {
|
2014-06-23 20:44:24 -04:00
|
|
|
d.expect_map(token)
|
2014-05-19 18:44:20 -07:00
|
|
|
}
|
2014-05-16 07:15:02 -07:00
|
|
|
}
|
|
|
|
|
2014-05-26 12:53:37 -07:00
|
|
|
impl<
|
2014-08-19 15:18:47 -07:00
|
|
|
D: Deserializer<E>,
|
|
|
|
E,
|
|
|
|
K: Deserializable<D, E> + Ord,
|
|
|
|
V: Deserializable<D, E>
|
|
|
|
> Deserializable<D, E> for TreeMap<K, V> {
|
2014-05-26 12:53:37 -07:00
|
|
|
#[inline]
|
2014-08-19 15:18:47 -07:00
|
|
|
fn deserialize_token(d: &mut D, token: Token) -> Result<TreeMap<K, V>, E> {
|
2014-06-23 20:44:24 -04:00
|
|
|
d.expect_map(token)
|
2014-05-26 12:53:37 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-16 07:15:02 -07:00
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-08-04 16:53:21 -07:00
|
|
|
impl<
|
2014-08-19 15:18:47 -07:00
|
|
|
D: Deserializer<E>,
|
|
|
|
E,
|
|
|
|
T: Deserializable<D, E> + Eq + Hash
|
|
|
|
> Deserializable<D, E> for HashSet<T> {
|
2014-08-04 16:53:21 -07:00
|
|
|
#[inline]
|
2014-08-19 15:18:47 -07:00
|
|
|
fn deserialize_token(d: &mut D, token: Token) -> Result<HashSet<T>, E> {
|
2014-08-04 16:53:21 -07:00
|
|
|
d.expect_seq(token)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<
|
2014-08-19 15:18:47 -07:00
|
|
|
D: Deserializer<E>,
|
|
|
|
E,
|
|
|
|
T: Deserializable<D, E> + Ord
|
|
|
|
> Deserializable<D, E> for TreeSet<T> {
|
2014-08-04 16:53:21 -07:00
|
|
|
#[inline]
|
2014-08-19 15:18:47 -07:00
|
|
|
fn deserialize_token(d: &mut D, token: Token) -> Result<TreeSet<T>, E> {
|
2014-08-04 16:53:21 -07:00
|
|
|
d.expect_seq(token)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-06-08 14:52:40 -07:00
|
|
|
macro_rules! peel {
|
|
|
|
($name:ident, $($other:ident,)*) => (impl_deserialize_tuple!($($other,)*))
|
|
|
|
}
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-06-08 14:52:40 -07:00
|
|
|
macro_rules! impl_deserialize_tuple {
|
2014-06-22 16:51:50 -04:00
|
|
|
() => {
|
2014-08-19 15:18:47 -07:00
|
|
|
impl<
|
|
|
|
D: Deserializer<E>,
|
|
|
|
E
|
|
|
|
> Deserializable<D, E> for () {
|
2014-06-22 16:51:50 -04:00
|
|
|
#[inline]
|
2014-08-19 15:18:47 -07:00
|
|
|
fn deserialize_token(d: &mut D, token: Token) -> Result<(), E> {
|
2014-06-22 16:51:50 -04:00
|
|
|
d.expect_null(token)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2014-06-08 14:52:40 -07:00
|
|
|
( $($name:ident,)+ ) => {
|
2014-05-19 17:53:24 -07:00
|
|
|
impl<
|
2014-08-19 15:18:47 -07:00
|
|
|
D: Deserializer<E>,
|
|
|
|
E,
|
|
|
|
$($name: Deserializable<D, E>),*
|
|
|
|
> Deserializable<D, E> for ($($name,)*) {
|
2014-05-19 18:44:20 -07:00
|
|
|
#[inline]
|
2014-09-04 21:57:13 -04:00
|
|
|
#[allow(non_snake_case)]
|
2014-08-19 15:18:47 -07:00
|
|
|
fn deserialize_token(d: &mut D, token: Token) -> Result<($($name,)*), E> {
|
2014-06-22 16:51:50 -04:00
|
|
|
try!(d.expect_tuple_start(token));
|
2014-05-19 18:44:20 -07:00
|
|
|
|
2014-05-21 06:47:58 -07:00
|
|
|
let result = ($({
|
2014-08-03 12:35:15 -07:00
|
|
|
let $name = try!(d.expect_tuple_elt());
|
2014-05-21 06:47:58 -07:00
|
|
|
$name
|
|
|
|
},)*);
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-06-09 07:51:53 -07:00
|
|
|
try!(d.expect_tuple_end());
|
|
|
|
|
|
|
|
Ok(result)
|
2014-05-19 17:53:24 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
peel!($($name,)*)
|
2014-06-08 14:52:40 -07:00
|
|
|
}
|
|
|
|
}
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-06-08 14:52:40 -07:00
|
|
|
impl_deserialize_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
|
2014-05-16 07:15:02 -07:00
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-05-30 19:13:50 -07:00
|
|
|
/// Helper struct that will ignore tokens while taking in consideration
|
|
|
|
/// recursive structures.
|
|
|
|
pub struct IgnoreTokens;
|
2014-05-27 07:36:57 -07:00
|
|
|
|
2014-08-19 15:18:47 -07:00
|
|
|
impl<D: Deserializer<E>, E> Deserializable<D, E> for IgnoreTokens {
|
2014-05-30 19:13:50 -07:00
|
|
|
#[inline]
|
2014-08-19 15:18:47 -07:00
|
|
|
fn deserialize_token(d: &mut D, token: Token) -> Result<IgnoreTokens, E> {
|
2014-05-30 19:13:50 -07:00
|
|
|
match token {
|
|
|
|
Option(true) => {
|
|
|
|
Deserializable::deserialize(d)
|
|
|
|
}
|
|
|
|
|
|
|
|
EnumStart(_, _, _) => {
|
|
|
|
loop {
|
|
|
|
match try!(d.expect_token()) {
|
|
|
|
End => { return Ok(IgnoreTokens); }
|
|
|
|
token => {
|
|
|
|
let _: IgnoreTokens = try!(Deserializable::deserialize_token(d, token));
|
|
|
|
}
|
|
|
|
}
|
2014-05-27 07:36:57 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-30 19:13:50 -07:00
|
|
|
StructStart(_, _) => {
|
|
|
|
loop {
|
|
|
|
match try!(d.expect_token()) {
|
|
|
|
End => { return Ok(IgnoreTokens); }
|
|
|
|
Str(_) | String(_) => {
|
|
|
|
let _: IgnoreTokens = try!(Deserializable::deserialize(d));
|
|
|
|
}
|
2014-08-06 22:24:06 -04:00
|
|
|
_token => { return Err(d.syntax_error(token, [EndKind, StrKind, StringKind])); }
|
2014-05-30 19:13:50 -07:00
|
|
|
}
|
2014-05-27 07:36:57 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-30 19:13:50 -07:00
|
|
|
TupleStart(_) => {
|
|
|
|
loop {
|
|
|
|
match try!(d.expect_token()) {
|
|
|
|
End => { return Ok(IgnoreTokens); }
|
|
|
|
token => {
|
|
|
|
let _: IgnoreTokens = try!(Deserializable::deserialize_token(d, token));
|
|
|
|
}
|
|
|
|
}
|
2014-05-27 07:36:57 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-30 19:13:50 -07:00
|
|
|
SeqStart(_) => {
|
|
|
|
loop {
|
|
|
|
match try!(d.expect_token()) {
|
|
|
|
End => { return Ok(IgnoreTokens); }
|
|
|
|
token => {
|
|
|
|
let _: IgnoreTokens = try!(Deserializable::deserialize_token(d, token));
|
|
|
|
}
|
|
|
|
}
|
2014-05-27 07:36:57 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-30 19:13:50 -07:00
|
|
|
MapStart(_) => {
|
|
|
|
loop {
|
|
|
|
match try!(d.expect_token()) {
|
|
|
|
End => { return Ok(IgnoreTokens); }
|
|
|
|
token => {
|
|
|
|
let _: IgnoreTokens = try!(Deserializable::deserialize_token(d, token));
|
|
|
|
let _: IgnoreTokens = try!(Deserializable::deserialize(d));
|
|
|
|
}
|
2014-05-27 07:36:57 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-06 22:24:06 -04:00
|
|
|
End => {
|
2014-10-06 21:50:22 -07:00
|
|
|
Err(d.syntax_error(token, COMPOUND_TOKEN_KINDS))
|
2014-08-06 22:24:06 -04:00
|
|
|
}
|
2014-05-30 19:13:50 -07:00
|
|
|
|
|
|
|
_ => Ok(IgnoreTokens),
|
2014-05-30 19:15:05 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
/// Helper struct that will gather tokens while taking in consideration
|
|
|
|
/// recursive structures.
|
|
|
|
pub struct GatherTokens {
|
|
|
|
tokens: Vec<Token>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl GatherTokens {
|
|
|
|
#[inline]
|
|
|
|
pub fn unwrap(self) -> Vec<Token> {
|
|
|
|
self.tokens
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-06-22 16:51:50 -04:00
|
|
|
fn gather<D: Deserializer<E>, E>(&mut self, d: &mut D) -> Result<(), E> {
|
2014-05-30 19:15:05 -07:00
|
|
|
let token = try!(d.expect_token());
|
|
|
|
self.gather_token(d, token)
|
|
|
|
}
|
2014-05-30 19:13:50 -07:00
|
|
|
|
2014-05-30 19:15:05 -07:00
|
|
|
#[inline]
|
2014-06-22 16:51:50 -04:00
|
|
|
fn gather_token<D: Deserializer<E>, E>(&mut self, d: &mut D, token: Token) -> Result<(), E> {
|
2014-05-30 19:15:05 -07:00
|
|
|
match token {
|
|
|
|
token @ Option(true) => {
|
|
|
|
self.tokens.push(token);
|
|
|
|
self.gather(d)
|
|
|
|
}
|
|
|
|
EnumStart(name, variant, len) => {
|
|
|
|
self.tokens.reserve_additional(len + 1);
|
|
|
|
self.tokens.push(EnumStart(name, variant, len));
|
|
|
|
self.gather_seq(d)
|
|
|
|
}
|
|
|
|
StructStart(name, len) => {
|
|
|
|
self.tokens.reserve_additional(len + 1);
|
|
|
|
self.tokens.push(StructStart(name, len));
|
2014-05-30 22:30:02 -07:00
|
|
|
self.gather_struct(d)
|
2014-05-30 19:15:05 -07:00
|
|
|
}
|
|
|
|
TupleStart(len) => {
|
|
|
|
self.tokens.reserve_additional(len + 1);
|
|
|
|
self.tokens.push(TupleStart(len));
|
|
|
|
self.gather_seq(d)
|
|
|
|
}
|
|
|
|
SeqStart(len) => {
|
|
|
|
self.tokens.reserve_additional(len + 1);
|
|
|
|
self.tokens.push(SeqStart(len));
|
|
|
|
self.gather_seq(d)
|
|
|
|
}
|
|
|
|
MapStart(len) => {
|
|
|
|
self.tokens.reserve_additional(len + 1);
|
|
|
|
self.tokens.push(MapStart(len));
|
|
|
|
self.gather_map(d)
|
|
|
|
}
|
|
|
|
End => {
|
2014-10-06 21:50:22 -07:00
|
|
|
Err(d.syntax_error(token, COMPOUND_TOKEN_KINDS))
|
2014-05-30 19:15:05 -07:00
|
|
|
}
|
|
|
|
token => {
|
|
|
|
self.tokens.push(token);
|
|
|
|
Ok(())
|
|
|
|
}
|
2014-05-30 19:13:50 -07:00
|
|
|
}
|
2014-05-27 07:36:57 -07:00
|
|
|
}
|
2014-05-30 19:15:05 -07:00
|
|
|
|
|
|
|
#[inline]
|
2014-06-22 16:51:50 -04:00
|
|
|
fn gather_seq<D: Deserializer<E>, E>(&mut self, d: &mut D) -> Result<(), E> {
|
2014-05-30 19:15:05 -07:00
|
|
|
loop {
|
|
|
|
match try!(d.expect_token()) {
|
|
|
|
token @ End => {
|
|
|
|
self.tokens.push(token);
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
token => {
|
|
|
|
try!(self.gather_token(d, token));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-06-22 16:51:50 -04:00
|
|
|
fn gather_struct<D: Deserializer<E>, E>(&mut self, d: &mut D) -> Result<(), E> {
|
2014-05-30 19:15:05 -07:00
|
|
|
loop {
|
|
|
|
match try!(d.expect_token()) {
|
|
|
|
token @ End => {
|
|
|
|
self.tokens.push(token);
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
token @ Str(_) | token @ String(_) => {
|
|
|
|
self.tokens.push(token);
|
|
|
|
try!(self.gather(d))
|
|
|
|
}
|
2014-08-06 22:24:06 -04:00
|
|
|
token => {
|
|
|
|
return Err(d.syntax_error(token, [EndKind, StrKind, StringKind]));
|
|
|
|
}
|
2014-05-30 19:15:05 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-06-22 16:51:50 -04:00
|
|
|
fn gather_map<D: Deserializer<E>, E>(&mut self, d: &mut D) -> Result<(), E> {
|
2014-05-30 19:15:05 -07:00
|
|
|
loop {
|
|
|
|
match try!(d.expect_token()) {
|
|
|
|
End => {
|
|
|
|
self.tokens.push(End);
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
token => {
|
|
|
|
try!(self.gather_token(d, token));
|
|
|
|
try!(self.gather(d))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-19 15:18:47 -07:00
|
|
|
impl<D: Deserializer<E>, E> Deserializable<D, E> for GatherTokens {
|
2014-05-30 19:15:05 -07:00
|
|
|
#[inline]
|
2014-08-19 15:18:47 -07:00
|
|
|
fn deserialize_token(d: &mut D, token: Token) -> Result<GatherTokens, E> {
|
2014-05-30 19:15:05 -07:00
|
|
|
let mut tokens = GatherTokens {
|
|
|
|
tokens: vec!(),
|
|
|
|
};
|
|
|
|
try!(tokens.gather_token(d, token));
|
|
|
|
Ok(tokens)
|
|
|
|
}
|
2014-05-27 07:36:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-05-16 07:15:02 -07:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2014-06-22 16:51:50 -04:00
|
|
|
use std::collections::TreeMap;
|
2014-09-29 21:58:22 -04:00
|
|
|
use std::{option, string};
|
2014-05-23 20:41:29 -07:00
|
|
|
use serialize::Decoder;
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-10-22 18:22:42 -07:00
|
|
|
use super::{Deserializer, Deserializable, Token, TokenKind, IgnoreTokens};
|
2014-06-22 16:51:50 -04:00
|
|
|
use super::{
|
|
|
|
Null,
|
|
|
|
Bool,
|
|
|
|
Int,
|
|
|
|
I8,
|
|
|
|
I16,
|
|
|
|
I32,
|
|
|
|
I64,
|
|
|
|
Uint,
|
|
|
|
U8,
|
|
|
|
U16,
|
|
|
|
U32,
|
|
|
|
U64,
|
|
|
|
F32,
|
|
|
|
F64,
|
|
|
|
Char,
|
|
|
|
Str,
|
|
|
|
String,
|
|
|
|
Option,
|
|
|
|
TupleStart,
|
|
|
|
StructStart,
|
|
|
|
EnumStart,
|
|
|
|
SeqStart,
|
|
|
|
MapStart,
|
|
|
|
End,
|
|
|
|
};
|
|
|
|
|
|
|
|
macro_rules! treemap {
|
|
|
|
($($k:expr => $v:expr),*) => ({
|
|
|
|
let mut _m = ::std::collections::TreeMap::new();
|
|
|
|
$(_m.insert($k, $v);)*
|
|
|
|
_m
|
|
|
|
})
|
|
|
|
}
|
2014-05-16 07:15:02 -07:00
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-05-31 12:28:30 -07:00
|
|
|
#[deriving(Clone, PartialEq, Show, Decodable)]
|
2014-05-21 08:25:28 -07:00
|
|
|
struct Inner {
|
|
|
|
a: (),
|
|
|
|
b: uint,
|
2014-09-29 21:58:22 -04:00
|
|
|
c: TreeMap<string::String, option::Option<char>>,
|
2014-05-21 08:25:28 -07:00
|
|
|
}
|
|
|
|
|
2014-08-19 15:18:47 -07:00
|
|
|
impl<
|
|
|
|
D: Deserializer<E>,
|
|
|
|
E
|
|
|
|
> Deserializable<D, E> for Inner {
|
2014-05-21 08:25:28 -07:00
|
|
|
#[inline]
|
2014-08-19 15:18:47 -07:00
|
|
|
fn deserialize_token(d: &mut D, token: Token) -> Result<Inner, E> {
|
2014-05-25 21:59:58 -07:00
|
|
|
try!(d.expect_struct_start(token, "Inner"));
|
2014-10-22 18:22:42 -07:00
|
|
|
|
|
|
|
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!(Deserializable::deserialize(d)); }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(Inner { a: a.unwrap(), b: b.unwrap(), c: c.unwrap() })
|
2014-05-21 08:25:28 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-05-31 12:28:30 -07:00
|
|
|
#[deriving(Clone, PartialEq, Show, Decodable)]
|
2014-05-21 08:25:28 -07:00
|
|
|
struct Outer {
|
|
|
|
inner: Vec<Inner>,
|
|
|
|
}
|
|
|
|
|
2014-08-19 15:18:47 -07:00
|
|
|
impl<D: Deserializer<E>, E> Deserializable<D, E> for Outer {
|
2014-05-21 08:25:28 -07:00
|
|
|
#[inline]
|
2014-08-19 15:18:47 -07:00
|
|
|
fn deserialize_token(d: &mut D, token: Token) -> Result<Outer, E> {
|
2014-05-25 21:59:58 -07:00
|
|
|
try!(d.expect_struct_start(token, "Outer"));
|
2014-10-22 18:22:42 -07:00
|
|
|
|
|
|
|
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!(Deserializable::deserialize(d)); }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(Outer { inner: inner.unwrap() })
|
2014-05-21 08:25:28 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-05-31 12:28:30 -07:00
|
|
|
#[deriving(Clone, PartialEq, Show, Decodable)]
|
2014-05-21 08:44:48 -07:00
|
|
|
enum Animal {
|
|
|
|
Dog,
|
2014-09-29 21:58:22 -04:00
|
|
|
Frog(string::String, int)
|
2014-05-21 08:44:48 -07:00
|
|
|
}
|
|
|
|
|
2014-08-19 15:18:47 -07:00
|
|
|
impl<D: Deserializer<E>, E> Deserializable<D, E> for Animal {
|
2014-05-21 08:44:48 -07:00
|
|
|
#[inline]
|
2014-08-19 15:18:47 -07:00
|
|
|
fn deserialize_token(d: &mut D, token: Token) -> Result<Animal, E> {
|
2014-05-25 21:59:58 -07:00
|
|
|
match try!(d.expect_enum_start(token, "Animal", ["Dog", "Frog"])) {
|
2014-05-21 08:44:48 -07:00
|
|
|
0 => {
|
2014-06-09 07:51:53 -07:00
|
|
|
try!(d.expect_enum_end());
|
2014-05-21 08:44:48 -07:00
|
|
|
Ok(Dog)
|
|
|
|
}
|
|
|
|
1 => {
|
|
|
|
let x0 = try!(Deserializable::deserialize(d));
|
|
|
|
let x1 = try!(Deserializable::deserialize(d));
|
2014-06-09 07:51:53 -07:00
|
|
|
try!(d.expect_enum_end());
|
2014-05-21 08:44:48 -07:00
|
|
|
Ok(Frog(x0, x1))
|
|
|
|
}
|
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-05-16 07:15:02 -07:00
|
|
|
#[deriving(Show)]
|
|
|
|
enum Error {
|
|
|
|
EndOfStream,
|
2014-09-06 23:08:51 -04:00
|
|
|
SyntaxError(Vec<TokenKind>),
|
|
|
|
UnexpectedName,
|
|
|
|
ConversionError,
|
|
|
|
MissingField(&'static str),
|
2014-05-16 07:15:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
struct TokenDeserializer<Iter> {
|
|
|
|
tokens: Iter,
|
2014-05-16 07:15:02 -07:00
|
|
|
}
|
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
impl<Iter: Iterator<Token>> TokenDeserializer<Iter> {
|
2014-05-16 07:15:02 -07:00
|
|
|
#[inline]
|
2014-06-22 16:51:50 -04:00
|
|
|
fn new(tokens: Iter) -> TokenDeserializer<Iter> {
|
2014-05-16 07:15:02 -07:00
|
|
|
TokenDeserializer {
|
|
|
|
tokens: tokens,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
impl<Iter: Iterator<Token>> Iterator<Result<Token, Error>> for TokenDeserializer<Iter> {
|
2014-05-16 07:15:02 -07:00
|
|
|
#[inline]
|
2014-09-29 21:58:22 -04:00
|
|
|
fn next(&mut self) -> option::Option<Result<Token, Error>> {
|
2014-06-22 16:51:50 -04:00
|
|
|
match self.tokens.next() {
|
2014-05-16 07:15:02 -07:00
|
|
|
None => None,
|
|
|
|
Some(token) => Some(Ok(token)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
impl<Iter: Iterator<Token>> Deserializer<Error> for TokenDeserializer<Iter> {
|
2014-08-18 07:39:34 -07:00
|
|
|
fn end_of_stream_error(&mut self) -> Error {
|
2014-08-05 23:02:15 -04:00
|
|
|
EndOfStream
|
2014-05-16 07:15:02 -07:00
|
|
|
}
|
|
|
|
|
2014-09-06 23:08:51 -04:00
|
|
|
fn syntax_error(&mut self, _token: Token, expected: &[TokenKind]) -> Error {
|
|
|
|
SyntaxError(expected.to_vec())
|
2014-08-06 22:24:06 -04:00
|
|
|
}
|
|
|
|
|
2014-08-18 07:39:34 -07:00
|
|
|
fn unexpected_name_error(&mut self, _token: Token) -> Error {
|
2014-09-06 23:08:51 -04:00
|
|
|
UnexpectedName
|
2014-08-06 22:24:06 -04:00
|
|
|
}
|
|
|
|
|
2014-08-18 07:39:34 -07:00
|
|
|
fn conversion_error(&mut self, _token: Token) -> Error {
|
2014-09-06 23:08:51 -04:00
|
|
|
ConversionError
|
2014-05-16 07:15:02 -07:00
|
|
|
}
|
2014-08-03 12:35:15 -07:00
|
|
|
|
2014-08-18 07:37:44 -07:00
|
|
|
#[inline]
|
|
|
|
fn missing_field<
|
2014-08-19 15:18:47 -07:00
|
|
|
T: Deserializable<TokenDeserializer<Iter>, Error>
|
2014-09-06 23:08:51 -04:00
|
|
|
>(&mut self, field: &'static str) -> Result<T, Error> {
|
|
|
|
Err(MissingField(field))
|
2014-08-03 12:35:15 -07:00
|
|
|
}
|
2014-05-16 07:15:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
macro_rules! test_value {
|
|
|
|
($name:ident, [$($tokens:expr => $value:expr: $ty:ty),*]) => {
|
|
|
|
#[test]
|
|
|
|
fn $name() {
|
|
|
|
$(
|
2014-09-29 21:58:22 -04:00
|
|
|
let mut deserializer = TokenDeserializer::new($tokens.into_iter());
|
2014-06-22 16:51:50 -04:00
|
|
|
let value: $ty = Deserializable::deserialize(&mut deserializer).unwrap();
|
2014-05-21 08:25:28 -07:00
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
assert_eq!(value, $value);
|
|
|
|
)+
|
|
|
|
}
|
|
|
|
}
|
2014-05-20 19:22:23 -07:00
|
|
|
}
|
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
test_value!(test_primitives, [
|
|
|
|
vec!(Null) => (): (),
|
|
|
|
vec!(Bool(true)) => true: bool,
|
|
|
|
vec!(Bool(false)) => false: bool,
|
|
|
|
vec!(Int(5)) => 5: int,
|
|
|
|
vec!(I8(5)) => 5: i8,
|
|
|
|
vec!(I16(5)) => 5: i16,
|
|
|
|
vec!(I32(5)) => 5: i32,
|
|
|
|
vec!(I64(5)) => 5: i64,
|
|
|
|
vec!(Uint(5)) => 5: uint,
|
|
|
|
vec!(U8(5)) => 5: u8,
|
|
|
|
vec!(U16(5)) => 5: u16,
|
|
|
|
vec!(U32(5)) => 5: u32,
|
|
|
|
vec!(U64(5)) => 5: u64,
|
|
|
|
vec!(F32(5.0)) => 5.0: f32,
|
|
|
|
vec!(F64(5.0)) => 5.0: f64,
|
|
|
|
vec!(Char('c')) => 'c': char,
|
|
|
|
vec!(Str("abc")) => "abc": &str,
|
2014-09-29 21:58:22 -04:00
|
|
|
vec!(String("abc".to_string())) => "abc".to_string(): string::String
|
2014-06-22 16:51:50 -04:00
|
|
|
])
|
|
|
|
|
|
|
|
test_value!(test_tuples, [
|
|
|
|
vec!(
|
2014-05-20 19:22:23 -07:00
|
|
|
TupleStart(0),
|
|
|
|
End,
|
2014-06-22 16:51:50 -04:00
|
|
|
) => (): (),
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
vec!(
|
2014-05-20 19:22:23 -07:00
|
|
|
TupleStart(2),
|
2014-05-16 07:15:02 -07:00
|
|
|
Int(5),
|
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
Str("a"),
|
2014-05-20 19:22:23 -07:00
|
|
|
End,
|
2014-06-22 16:51:50 -04:00
|
|
|
) => (5, "a"): (int, &'static str),
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
vec!(
|
2014-05-20 19:22:23 -07:00
|
|
|
TupleStart(3),
|
|
|
|
Null,
|
2014-05-20 19:38:48 -07:00
|
|
|
|
2014-05-20 19:22:23 -07:00
|
|
|
TupleStart(0),
|
|
|
|
End,
|
|
|
|
|
|
|
|
TupleStart(2),
|
2014-05-16 07:15:02 -07:00
|
|
|
Int(5),
|
2014-05-19 19:41:38 -07:00
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
Str("a"),
|
2014-05-20 19:22:23 -07:00
|
|
|
End,
|
|
|
|
End,
|
2014-06-22 16:51:50 -04:00
|
|
|
) => ((), (), (5, "a")): ((), (), (int, &'static str))
|
|
|
|
])
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
test_value!(test_options, [
|
2014-09-29 21:58:22 -04:00
|
|
|
vec!(Option(false)) => None: option::Option<int>,
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
vec!(
|
|
|
|
Option(true),
|
|
|
|
Int(5),
|
2014-09-29 21:58:22 -04:00
|
|
|
) => Some(5): option::Option<int>
|
2014-06-22 16:51:50 -04:00
|
|
|
])
|
2014-05-21 08:25:28 -07:00
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
test_value!(test_structs, [
|
|
|
|
vec!(
|
2014-05-28 10:46:29 -07:00
|
|
|
StructStart("Outer", 1),
|
2014-05-26 08:26:34 -07:00
|
|
|
Str("inner"),
|
2014-05-21 08:25:28 -07:00
|
|
|
SeqStart(0),
|
|
|
|
End,
|
|
|
|
End,
|
2014-06-22 16:51:50 -04:00
|
|
|
) => Outer { inner: vec!() }: Outer,
|
2014-05-21 08:25:28 -07:00
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
vec!(
|
2014-05-28 10:46:29 -07:00
|
|
|
StructStart("Outer", 1),
|
2014-05-26 08:26:34 -07:00
|
|
|
Str("inner"),
|
2014-05-21 08:25:28 -07:00
|
|
|
SeqStart(1),
|
2014-05-28 10:46:29 -07:00
|
|
|
StructStart("Inner", 3),
|
2014-05-26 08:26:34 -07:00
|
|
|
Str("a"),
|
2014-05-21 08:25:28 -07:00
|
|
|
Null,
|
|
|
|
|
2014-05-26 08:26:34 -07:00
|
|
|
Str("b"),
|
2014-05-21 08:25:28 -07:00
|
|
|
Uint(5),
|
|
|
|
|
2014-05-26 08:26:34 -07:00
|
|
|
Str("c"),
|
2014-05-21 08:25:28 -07:00
|
|
|
MapStart(1),
|
2014-05-29 06:44:38 -07:00
|
|
|
String("abc".to_string()),
|
2014-05-21 08:25:28 -07:00
|
|
|
|
2014-05-26 09:01:22 -07:00
|
|
|
Option(true),
|
|
|
|
Char('c'),
|
2014-05-21 08:25:28 -07:00
|
|
|
End,
|
|
|
|
End,
|
|
|
|
End,
|
|
|
|
End,
|
2014-06-22 16:51:50 -04:00
|
|
|
) => Outer {
|
|
|
|
inner: vec!(
|
|
|
|
Inner {
|
|
|
|
a: (),
|
|
|
|
b: 5,
|
|
|
|
c: treemap!("abc".to_string() => Some('c')),
|
|
|
|
},
|
|
|
|
),
|
|
|
|
}: Outer
|
|
|
|
])
|
|
|
|
|
|
|
|
test_value!(test_enums, [
|
|
|
|
vec!(
|
2014-05-28 10:46:29 -07:00
|
|
|
EnumStart("Animal", "Dog", 0),
|
2014-05-21 08:44:48 -07:00
|
|
|
End,
|
2014-06-22 16:51:50 -04:00
|
|
|
) => Dog: Animal,
|
2014-05-21 08:44:48 -07:00
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
vec!(
|
2014-05-28 10:46:29 -07:00
|
|
|
EnumStart("Animal", "Frog", 2),
|
2014-05-29 06:44:38 -07:00
|
|
|
String("Henry".to_string()),
|
2014-05-21 08:44:48 -07:00
|
|
|
Int(349),
|
|
|
|
End,
|
2014-06-22 16:51:50 -04:00
|
|
|
) => Frog("Henry".to_string(), 349): Animal
|
|
|
|
])
|
2014-05-21 08:44:48 -07:00
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
test_value!(test_vecs, [
|
|
|
|
vec!(
|
2014-05-20 19:22:23 -07:00
|
|
|
SeqStart(0),
|
|
|
|
End,
|
2014-06-22 16:51:50 -04:00
|
|
|
) => vec!(): Vec<int>,
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
vec!(
|
2014-05-20 19:22:23 -07:00
|
|
|
SeqStart(3),
|
2014-05-16 07:15:02 -07:00
|
|
|
Int(5),
|
|
|
|
|
|
|
|
Int(6),
|
|
|
|
|
|
|
|
Int(7),
|
2014-05-20 19:22:23 -07:00
|
|
|
End,
|
2014-06-22 16:51:50 -04:00
|
|
|
) => vec!(5, 6, 7): Vec<int>,
|
2014-05-16 07:15:02 -07:00
|
|
|
|
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
vec!(
|
|
|
|
SeqStart(3),
|
2014-05-20 19:22:23 -07:00
|
|
|
SeqStart(1),
|
2014-05-16 07:15:02 -07:00
|
|
|
Int(1),
|
2014-05-20 19:22:23 -07:00
|
|
|
End,
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-05-20 19:22:23 -07:00
|
|
|
SeqStart(2),
|
2014-05-16 07:15:02 -07:00
|
|
|
Int(2),
|
|
|
|
|
|
|
|
Int(3),
|
2014-05-20 19:22:23 -07:00
|
|
|
End,
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-05-20 19:22:23 -07:00
|
|
|
SeqStart(3),
|
2014-05-16 07:15:02 -07:00
|
|
|
Int(4),
|
|
|
|
|
|
|
|
Int(5),
|
|
|
|
|
|
|
|
Int(6),
|
2014-05-20 19:22:23 -07:00
|
|
|
End,
|
|
|
|
End,
|
2014-06-22 16:51:50 -04:00
|
|
|
) => vec!(vec!(1), vec!(2, 3), vec!(4, 5, 6)): Vec<Vec<int>>
|
|
|
|
])
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
test_value!(test_treemaps, [
|
|
|
|
vec!(
|
|
|
|
MapStart(0),
|
|
|
|
End,
|
2014-09-29 21:58:22 -04:00
|
|
|
) => treemap!(): TreeMap<int, string::String>,
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-06-22 16:51:50 -04:00
|
|
|
vec!(
|
2014-05-20 19:22:23 -07:00
|
|
|
MapStart(2),
|
2014-05-26 09:01:22 -07:00
|
|
|
Int(5),
|
2014-05-29 06:44:38 -07:00
|
|
|
String("a".to_string()),
|
2014-05-16 07:15:02 -07:00
|
|
|
|
2014-05-26 09:01:22 -07:00
|
|
|
Int(6),
|
2014-05-29 06:44:38 -07:00
|
|
|
String("b".to_string()),
|
2014-05-20 19:22:23 -07:00
|
|
|
End,
|
2014-09-29 21:58:22 -04:00
|
|
|
) => treemap!(5i => "a".to_string(), 6i => "b".to_string()): TreeMap<int, string::
|
|
|
|
String>
|
2014-06-22 16:51:50 -04:00
|
|
|
])
|
2014-05-16 07:15:02 -07:00
|
|
|
}
|