mirror of
https://github.com/serde-rs/serde.git
synced 2025-10-02 15:25:38 +00:00
add a JsonDeserializer, clean up tests
This commit is contained in:
parent
88631b57cb
commit
86560857a7
@ -223,13 +223,13 @@ mod deserializer {
|
|||||||
match self.stack.pop() {
|
match self.stack.pop() {
|
||||||
Some(AnimalState(Dog)) => {
|
Some(AnimalState(Dog)) => {
|
||||||
self.stack.push(EndState);
|
self.stack.push(EndState);
|
||||||
Some(Ok(EnumStart("Animal", "Dog")))
|
Some(Ok(EnumStart("Animal", "Dog", 0)))
|
||||||
}
|
}
|
||||||
Some(AnimalState(Frog(x0, x1))) => {
|
Some(AnimalState(Frog(x0, x1))) => {
|
||||||
self.stack.push(EndState);
|
self.stack.push(EndState);
|
||||||
self.stack.push(IntState(x1));
|
self.stack.push(IntState(x1));
|
||||||
self.stack.push(StringState(x0));
|
self.stack.push(StringState(x0));
|
||||||
Some(Ok(EnumStart("Animal", "Frog")))
|
Some(Ok(EnumStart("Animal", "Frog", 2)))
|
||||||
}
|
}
|
||||||
Some(IntState(x)) => {
|
Some(IntState(x)) => {
|
||||||
Some(Ok(Int(x)))
|
Some(Ok(Int(x)))
|
||||||
|
@ -19,7 +19,7 @@ impl<E, D: Deserializer<E>> Deserializable<E, D> for Inner {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize_token(d: &mut D, token: Token) -> Result<Inner, E> {
|
fn deserialize_token(d: &mut D, token: Token) -> Result<Inner, E> {
|
||||||
match token {
|
match token {
|
||||||
de::StructStart("Inner") |
|
de::StructStart("Inner", _) |
|
||||||
de::MapStart(_) => {
|
de::MapStart(_) => {
|
||||||
let mut a = None;
|
let mut a = None;
|
||||||
let mut b = None;
|
let mut b = None;
|
||||||
@ -83,7 +83,7 @@ impl<E, D: Deserializer<E>> Deserializable<E, D> for Outer {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize_token(d: &mut D, token: Token) -> Result<Outer, E> {
|
fn deserialize_token(d: &mut D, token: Token) -> Result<Outer, E> {
|
||||||
match token {
|
match token {
|
||||||
de::StructStart("Outer") |
|
de::StructStart("Outer", _) |
|
||||||
de::MapStart(_) => {
|
de::MapStart(_) => {
|
||||||
let mut inner = None;
|
let mut inner = None;
|
||||||
|
|
||||||
@ -390,7 +390,7 @@ mod deserializer {
|
|||||||
self.stack.push(EndState);
|
self.stack.push(EndState);
|
||||||
self.stack.push(VecState(inner));
|
self.stack.push(VecState(inner));
|
||||||
self.stack.push(FieldState("inner"));
|
self.stack.push(FieldState("inner"));
|
||||||
Some(Ok(StructStart("Outer")))
|
Some(Ok(StructStart("Outer", 1)))
|
||||||
}
|
}
|
||||||
Some(InnerState(Inner { a: (), b, c })) => {
|
Some(InnerState(Inner { a: (), b, c })) => {
|
||||||
self.stack.push(EndState);
|
self.stack.push(EndState);
|
||||||
@ -402,7 +402,7 @@ mod deserializer {
|
|||||||
|
|
||||||
self.stack.push(NullState);
|
self.stack.push(NullState);
|
||||||
self.stack.push(FieldState("a"));
|
self.stack.push(FieldState("a"));
|
||||||
Some(Ok(StructStart("Inner")))
|
Some(Ok(StructStart("Inner", 3)))
|
||||||
}
|
}
|
||||||
Some(FieldState(name)) => Some(Ok(Str(name))),
|
Some(FieldState(name)) => Some(Ok(Str(name))),
|
||||||
Some(VecState(value)) => {
|
Some(VecState(value)) => {
|
||||||
|
24
de.rs
24
de.rs
@ -26,8 +26,8 @@ pub enum Token {
|
|||||||
Option(bool),
|
Option(bool),
|
||||||
|
|
||||||
TupleStart(uint),
|
TupleStart(uint),
|
||||||
StructStart(&'static str),
|
StructStart(&'static str, uint),
|
||||||
EnumStart(&'static str, &'static str),
|
EnumStart(&'static str, &'static str, uint),
|
||||||
SeqStart(uint),
|
SeqStart(uint),
|
||||||
MapStart(uint),
|
MapStart(uint),
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ pub trait Deserializer<E>: Iterator<Result<Token, E>> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn expect_struct_start(&mut self, token: Token, name: &str) -> Result<(), E> {
|
fn expect_struct_start(&mut self, token: Token, name: &str) -> Result<(), E> {
|
||||||
match token {
|
match token {
|
||||||
StructStart(n) => {
|
StructStart(n, _) => {
|
||||||
if name == n {
|
if name == n {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@ -187,9 +187,9 @@ pub trait Deserializer<E>: Iterator<Result<Token, E>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn expect_enum_start<'a>(&mut self, token: Token, name: &str, variants: &[&str]) -> Result<uint, E> {
|
fn expect_enum_start(&mut self, token: Token, name: &str, variants: &[&str]) -> Result<uint, E> {
|
||||||
match token {
|
match token {
|
||||||
EnumStart(n, v) => {
|
EnumStart(n, v, _) => {
|
||||||
if name == n {
|
if name == n {
|
||||||
match variants.iter().position(|variant| *variant == v) {
|
match variants.iter().position(|variant| *variant == v) {
|
||||||
Some(position) => Ok(position),
|
Some(position) => Ok(position),
|
||||||
@ -511,7 +511,7 @@ pub fn ignore_token<E, D: Deserializer<E>>(d: &mut D, token: Token) -> Result<()
|
|||||||
Option(true) => { ignore(d) }
|
Option(true) => { ignore(d) }
|
||||||
Option(false) => { Ok(()) }
|
Option(false) => { Ok(()) }
|
||||||
|
|
||||||
EnumStart(_, _) => {
|
EnumStart(_, _, _) => {
|
||||||
loop {
|
loop {
|
||||||
match try!(d.expect_token()) {
|
match try!(d.expect_token()) {
|
||||||
End => { return Ok(()); }
|
End => { return Ok(()); }
|
||||||
@ -520,7 +520,7 @@ pub fn ignore_token<E, D: Deserializer<E>>(d: &mut D, token: Token) -> Result<()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StructStart(_) => {
|
StructStart(_, _) => {
|
||||||
loop {
|
loop {
|
||||||
match try!(d.expect_token()) {
|
match try!(d.expect_token()) {
|
||||||
End => { return Ok(()); }
|
End => { return Ok(()); }
|
||||||
@ -817,7 +817,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_tokens_struct_empty() {
|
fn test_tokens_struct_empty() {
|
||||||
let tokens = vec!(
|
let tokens = vec!(
|
||||||
StructStart("Outer"),
|
StructStart("Outer", 1),
|
||||||
Str("inner"),
|
Str("inner"),
|
||||||
SeqStart(0),
|
SeqStart(0),
|
||||||
End,
|
End,
|
||||||
@ -833,10 +833,10 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_tokens_struct() {
|
fn test_tokens_struct() {
|
||||||
let tokens = vec!(
|
let tokens = vec!(
|
||||||
StructStart("Outer"),
|
StructStart("Outer", 1),
|
||||||
Str("inner"),
|
Str("inner"),
|
||||||
SeqStart(1),
|
SeqStart(1),
|
||||||
StructStart("Inner"),
|
StructStart("Inner", 3),
|
||||||
Str("a"),
|
Str("a"),
|
||||||
Null,
|
Null,
|
||||||
|
|
||||||
@ -877,7 +877,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_tokens_enum() {
|
fn test_tokens_enum() {
|
||||||
let tokens = vec!(
|
let tokens = vec!(
|
||||||
EnumStart("Animal", "Dog"),
|
EnumStart("Animal", "Dog", 0),
|
||||||
End,
|
End,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -887,7 +887,7 @@ mod tests {
|
|||||||
assert_eq!(value, Dog);
|
assert_eq!(value, Dog);
|
||||||
|
|
||||||
let tokens = vec!(
|
let tokens = vec!(
|
||||||
EnumStart("Animal", "Frog"),
|
EnumStart("Animal", "Frog", 2),
|
||||||
String("Henry".to_strbuf()),
|
String("Henry".to_strbuf()),
|
||||||
Int(349),
|
Int(349),
|
||||||
End,
|
End,
|
||||||
|
312
json.rs
312
json.rs
@ -244,24 +244,158 @@ use std::str::ScalarValue;
|
|||||||
use std::str;
|
use std::str;
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
use std::vec;
|
||||||
|
|
||||||
use de;
|
use de;
|
||||||
use collections::{HashMap, TreeMap};
|
use collections::{HashMap, TreeMap};
|
||||||
|
use collections::treemap;
|
||||||
|
|
||||||
/// Represents a json value
|
/// Represents a json value
|
||||||
#[deriving(Clone, Eq)]
|
#[deriving(Clone, Eq, Show)]
|
||||||
pub enum Json {
|
pub enum Json {
|
||||||
|
Null,
|
||||||
|
Boolean(bool),
|
||||||
Number(f64),
|
Number(f64),
|
||||||
String(String),
|
String(String),
|
||||||
Boolean(bool),
|
|
||||||
List(List),
|
List(List),
|
||||||
Object(Box<Object>),
|
Object(Object),
|
||||||
Null,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type List = Vec<Json>;
|
pub type List = Vec<Json>;
|
||||||
pub type Object = TreeMap<String, Json>;
|
pub type Object = TreeMap<String, Json>;
|
||||||
|
|
||||||
|
impl<E, D: de::Deserializer<E>> de::Deserializable<E, D> for Json {
|
||||||
|
#[inline]
|
||||||
|
fn deserialize_token(d: &mut D, token: de::Token) -> Result<Json, E> {
|
||||||
|
match token {
|
||||||
|
de::Null => Ok(Null),
|
||||||
|
de::Bool(x) => Ok(Boolean(x)),
|
||||||
|
de::Int(x) => Ok(Number(x as f64)),
|
||||||
|
de::I8(x) => Ok(Number(x as f64)),
|
||||||
|
de::I16(x) => Ok(Number(x as f64)),
|
||||||
|
de::I32(x) => Ok(Number(x as f64)),
|
||||||
|
de::I64(x) => Ok(Number(x as f64)),
|
||||||
|
de::Uint(x) => Ok(Number(x as f64)),
|
||||||
|
de::U8(x) => Ok(Number(x as f64)),
|
||||||
|
de::U16(x) => Ok(Number(x as f64)),
|
||||||
|
de::U32(x) => Ok(Number(x as f64)),
|
||||||
|
de::U64(x) => Ok(Number(x as f64)),
|
||||||
|
de::F32(x) => Ok(Number(x as f64)),
|
||||||
|
de::F64(x) => Ok(Number(x)),
|
||||||
|
de::Char(x) => Ok(String(x.to_str())),
|
||||||
|
de::Str(x) => Ok(String(x.to_str())),
|
||||||
|
de::String(x) => Ok(String(x)),
|
||||||
|
de::Option(false) => Ok(Null),
|
||||||
|
de::Option(true) => de::Deserializable::deserialize(d),
|
||||||
|
de::TupleStart(_) | de::SeqStart(_) => {
|
||||||
|
let list = try!(de::Deserializable::deserialize_token(d, token));
|
||||||
|
Ok(List(list))
|
||||||
|
}
|
||||||
|
de::StructStart(_, _) | de::MapStart(_) => {
|
||||||
|
let object = try!(de::Deserializable::deserialize_token(d, token));
|
||||||
|
Ok(Object(object))
|
||||||
|
}
|
||||||
|
de::EnumStart(_, name, len) => {
|
||||||
|
let token = de::SeqStart(len);
|
||||||
|
let fields: Vec<Json> = try!(de::Deserializable::deserialize_token(d, token));
|
||||||
|
if fields.is_empty() {
|
||||||
|
Ok(String(name.to_strbuf()))
|
||||||
|
} else {
|
||||||
|
let mut object = TreeMap::new();
|
||||||
|
object.insert("variant".to_strbuf(), String(name.to_strbuf()));
|
||||||
|
object.insert("fields".to_strbuf(), List(fields));
|
||||||
|
Ok(Object(object))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
de::End => Err(d.syntax_error()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum JsonDeserializerState {
|
||||||
|
JsonDeserializerValueState(Json),
|
||||||
|
JsonDeserializerListState(vec::MoveItems<Json>),
|
||||||
|
JsonDeserializerObjectState(treemap::MoveEntries<String, Json>),
|
||||||
|
}
|
||||||
|
|
||||||
|
struct JsonDeserializer {
|
||||||
|
stack: Vec<JsonDeserializerState>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl JsonDeserializer {
|
||||||
|
/// Creates a new decoder instance for decoding the specified JSON value.
|
||||||
|
pub fn new(json: Json) -> JsonDeserializer {
|
||||||
|
JsonDeserializer {
|
||||||
|
stack: vec!(JsonDeserializerValueState(json)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator<Result<de::Token, ParserError>> for JsonDeserializer {
|
||||||
|
#[inline]
|
||||||
|
fn next(&mut self) -> Option<Result<de::Token, ParserError>> {
|
||||||
|
loop {
|
||||||
|
match self.stack.pop() {
|
||||||
|
Some(JsonDeserializerValueState(value)) => {
|
||||||
|
let token = match value {
|
||||||
|
Null => de::Null,
|
||||||
|
Boolean(x) => de::Bool(x),
|
||||||
|
Number(x) => de::F64(x),
|
||||||
|
String(x) => de::String(x),
|
||||||
|
List(x) => {
|
||||||
|
let len = x.len();
|
||||||
|
self.stack.push(JsonDeserializerListState(x.move_iter()));
|
||||||
|
de::SeqStart(len)
|
||||||
|
}
|
||||||
|
Object(x) => {
|
||||||
|
let len = x.len();
|
||||||
|
self.stack.push(JsonDeserializerObjectState(x.move_iter()));
|
||||||
|
de::MapStart(len)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return Some(Ok(token));
|
||||||
|
}
|
||||||
|
Some(JsonDeserializerListState(mut iter)) => {
|
||||||
|
match iter.next() {
|
||||||
|
Some(value) => {
|
||||||
|
self.stack.push(JsonDeserializerListState(iter));
|
||||||
|
self.stack.push(JsonDeserializerValueState(value));
|
||||||
|
// loop around.
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
return Some(Ok(de::End));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(JsonDeserializerObjectState(mut iter)) => {
|
||||||
|
match iter.next() {
|
||||||
|
Some((key, value)) => {
|
||||||
|
self.stack.push(JsonDeserializerObjectState(iter));
|
||||||
|
self.stack.push(JsonDeserializerValueState(value));
|
||||||
|
return Some(Ok(de::String(key)));
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
return Some(Ok(de::End));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => { return None; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl de::Deserializer<ParserError> for JsonDeserializer {
|
||||||
|
fn end_of_stream_error(&self) -> ParserError {
|
||||||
|
SyntaxError(EOFWhileParsingValue, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn syntax_error(&self) -> ParserError {
|
||||||
|
SyntaxError(InvalidSyntax, 0, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The errors that can arise while parsing a JSON stream.
|
/// The errors that can arise while parsing a JSON stream.
|
||||||
#[deriving(Clone, Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub enum ErrorCode {
|
pub enum ErrorCode {
|
||||||
@ -1615,6 +1749,60 @@ impl<T: Iterator<char>> de::Deserializer<ParserError> for Parser<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
#[inline]
|
||||||
|
fn expect_enum_start(&mut self, token: de::Token, _name: &str, variants: &[&str]) -> Result<uint, ParserError> {
|
||||||
|
match token {
|
||||||
|
Str(name) =>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
let name = match self.pop() {
|
||||||
|
String(s) => s,
|
||||||
|
Object(mut o) => {
|
||||||
|
let n = match o.pop(&"variant".to_strbuf()) {
|
||||||
|
Some(String(s)) => s,
|
||||||
|
Some(val) => {
|
||||||
|
return Err(ExpectedError("String".to_strbuf(),
|
||||||
|
format_strbuf!("{}", val)))
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
return Err(MissingFieldError("variant".to_strbuf()))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match o.pop(&"fields".to_strbuf()) {
|
||||||
|
Some(List(l)) => {
|
||||||
|
for field in l.move_iter().rev() {
|
||||||
|
self.stack.push(field.clone());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Some(val) => {
|
||||||
|
return Err(ExpectedError("List".to_strbuf(),
|
||||||
|
format_strbuf!("{}", val)))
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
return Err(MissingFieldError("fields".to_strbuf()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n
|
||||||
|
}
|
||||||
|
json => {
|
||||||
|
return Err(ExpectedError("String or Object".to_strbuf(),
|
||||||
|
format_strbuf!("{}", json)))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let idx = match names.iter()
|
||||||
|
.position(|n| {
|
||||||
|
str::eq_slice(*n, name.as_slice())
|
||||||
|
}) {
|
||||||
|
Some(idx) => idx,
|
||||||
|
None => return Err(UnknownVariantError(name))
|
||||||
|
};
|
||||||
|
f(self, idx)
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1733,6 +1921,15 @@ pub fn from_iter<
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Decodes a json value from a `Json`.
|
||||||
|
pub fn from_json<
|
||||||
|
T: de::Deserializable<ParserError, JsonDeserializer>
|
||||||
|
>(json: Json) -> Result<T, ParserError> {
|
||||||
|
let mut d = JsonDeserializer::new(json);
|
||||||
|
de::Deserializable::deserialize(&mut d)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1757,7 +1954,6 @@ pub fn from_str(s: &str) -> Result<Json, BuilderError> {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
/// A structure to decode JSON to values in rust.
|
/// A structure to decode JSON to values in rust.
|
||||||
pub struct Decoder {
|
pub struct Decoder {
|
||||||
stack: Vec<Json>,
|
stack: Vec<Json>,
|
||||||
@ -1797,7 +1993,9 @@ macro_rules! expect(
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
impl ::Decoder<DecoderError> for Decoder {
|
impl ::Decoder<DecoderError> for Decoder {
|
||||||
|
|
||||||
fn read_nil(&mut self) -> DecodeResult<()> {
|
fn read_nil(&mut self) -> DecodeResult<()> {
|
||||||
debug!("read_nil");
|
debug!("read_nil");
|
||||||
try!(expect!(self.pop(), Null));
|
try!(expect!(self.pop(), Null));
|
||||||
@ -2206,7 +2404,7 @@ impl<A:ToJson> ToJson for TreeMap<String, A> {
|
|||||||
for (key, value) in self.iter() {
|
for (key, value) in self.iter() {
|
||||||
d.insert((*key).clone(), value.to_json());
|
d.insert((*key).clone(), value.to_json());
|
||||||
}
|
}
|
||||||
Object(box d)
|
Object(d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2216,7 +2414,7 @@ impl<A:ToJson> ToJson for HashMap<String, A> {
|
|||||||
for (key, value) in self.iter() {
|
for (key, value) in self.iter() {
|
||||||
d.insert((*key).clone(), value.to_json());
|
d.insert((*key).clone(), value.to_json());
|
||||||
}
|
}
|
||||||
Object(box d)
|
Object(d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2255,7 +2453,17 @@ mod tests {
|
|||||||
TrailingCharacters};
|
TrailingCharacters};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
Json,
|
||||||
|
Null,
|
||||||
|
Boolean,
|
||||||
|
Number,
|
||||||
|
String,
|
||||||
|
List,
|
||||||
|
Object,
|
||||||
|
};
|
||||||
use super::{Parser, ParserError, from_iter};
|
use super::{Parser, ParserError, from_iter};
|
||||||
|
use super::{JsonDeserializer, from_json};
|
||||||
use super::{
|
use super::{
|
||||||
EOFWhileParsingList,
|
EOFWhileParsingList,
|
||||||
EOFWhileParsingObject,
|
EOFWhileParsingObject,
|
||||||
@ -2270,7 +2478,9 @@ mod tests {
|
|||||||
};
|
};
|
||||||
use de;
|
use de;
|
||||||
|
|
||||||
|
use std::fmt::Show;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::str;
|
||||||
use collections::TreeMap;
|
use collections::TreeMap;
|
||||||
|
|
||||||
#[deriving(Eq, Show)]
|
#[deriving(Eq, Show)]
|
||||||
@ -2311,7 +2521,7 @@ mod tests {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize_token(d: &mut D, token: de::Token) -> Result<Inner, E> {
|
fn deserialize_token(d: &mut D, token: de::Token) -> Result<Inner, E> {
|
||||||
match token {
|
match token {
|
||||||
de::StructStart("Inner") |
|
de::StructStart("Inner", _) |
|
||||||
de::MapStart(_) => {
|
de::MapStart(_) => {
|
||||||
let mut a = None;
|
let mut a = None;
|
||||||
let mut b = None;
|
let mut b = None;
|
||||||
@ -2373,7 +2583,7 @@ mod tests {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize_token(d: &mut D, token: de::Token) -> Result<Outer, E> {
|
fn deserialize_token(d: &mut D, token: de::Token) -> Result<Outer, E> {
|
||||||
match token {
|
match token {
|
||||||
de::StructStart("Outer") |
|
de::StructStart("Outer", _) |
|
||||||
de::MapStart(_) => {
|
de::MapStart(_) => {
|
||||||
let mut inner = None;
|
let mut inner = None;
|
||||||
|
|
||||||
@ -2664,44 +2874,82 @@ mod tests {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
fn test_parser_err<
|
||||||
|
'a,
|
||||||
|
T: Eq + Show + de::Deserializable<ParserError, Parser<str::Chars<'a>>>
|
||||||
|
>(errors: &[(&'a str, ParserError)]) {
|
||||||
|
for &(s, err) in errors.iter() {
|
||||||
|
let v: Result<T, ParserError> = from_iter(s.chars());
|
||||||
|
assert_eq!(v, Err(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_parser_ok<
|
||||||
|
'a,
|
||||||
|
T: Eq + Show + de::Deserializable<ParserError, Parser<str::Chars<'a>>>
|
||||||
|
>(errors: &[(&'a str, T)]) {
|
||||||
|
for &(s, ref value) in errors.iter() {
|
||||||
|
let v: T = from_iter(s.chars()).unwrap();
|
||||||
|
assert_eq!(v, *value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_json_deserializer_ok<
|
||||||
|
T: Eq + Show + de::Deserializable<ParserError, JsonDeserializer>
|
||||||
|
>(errors: &[(Json, T)]) {
|
||||||
|
for &(ref json, ref value) in errors.iter() {
|
||||||
|
let v: T = from_json(json.clone()).unwrap();
|
||||||
|
assert_eq!(v, *value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decode_null() {
|
fn test_decode_null() {
|
||||||
let errors = [
|
test_parser_err::<()>([
|
||||||
("n", SyntaxError(InvalidSyntax, 1, 2)),
|
("n", SyntaxError(InvalidSyntax, 1, 2)),
|
||||||
("nul", SyntaxError(InvalidSyntax, 1, 4)),
|
("nul", SyntaxError(InvalidSyntax, 1, 4)),
|
||||||
("nulla", SyntaxError(TrailingCharacters, 1, 5)),
|
("nulla", SyntaxError(TrailingCharacters, 1, 5)),
|
||||||
];
|
]);
|
||||||
|
|
||||||
for &(s, err) in errors.iter() {
|
test_parser_ok([
|
||||||
let v: Result<(), ParserError> = from_iter(s.chars());
|
("null", ()),
|
||||||
assert_eq!(v, Err(err));
|
]);
|
||||||
}
|
|
||||||
|
|
||||||
let v: () = from_iter("null".chars()).unwrap();
|
test_parser_ok([
|
||||||
assert_eq!(v, ());
|
("null", Null),
|
||||||
|
]);
|
||||||
|
|
||||||
|
test_json_deserializer_ok([
|
||||||
|
(Null, ()),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decode_bool() {
|
fn test_decode_bool() {
|
||||||
let errors = [
|
test_parser_err::<bool>([
|
||||||
("t", SyntaxError(InvalidSyntax, 1, 2)),
|
("t", SyntaxError(InvalidSyntax, 1, 2)),
|
||||||
("truz", SyntaxError(InvalidSyntax, 1, 4)),
|
("truz", SyntaxError(InvalidSyntax, 1, 4)),
|
||||||
("f", SyntaxError(InvalidSyntax, 1, 2)),
|
("f", SyntaxError(InvalidSyntax, 1, 2)),
|
||||||
("faz", SyntaxError(InvalidSyntax, 1, 3)),
|
("faz", SyntaxError(InvalidSyntax, 1, 3)),
|
||||||
("truea", SyntaxError(TrailingCharacters, 1, 5)),
|
("truea", SyntaxError(TrailingCharacters, 1, 5)),
|
||||||
("falsea", SyntaxError(TrailingCharacters, 1, 6)),
|
("falsea", SyntaxError(TrailingCharacters, 1, 6)),
|
||||||
];
|
]);
|
||||||
|
|
||||||
for &(s, err) in errors.iter() {
|
test_parser_ok([
|
||||||
let v: Result<bool, ParserError> = from_iter(s.chars());
|
("true", true),
|
||||||
assert_eq!(v, Err(err));
|
("false", false),
|
||||||
}
|
]);
|
||||||
|
|
||||||
let v: bool = from_iter("true".chars()).unwrap();
|
test_parser_ok([
|
||||||
assert_eq!(v, true);
|
("true", Boolean(true)),
|
||||||
|
("false", Boolean(false)),
|
||||||
|
]);
|
||||||
|
|
||||||
let v: bool = from_iter("false".chars()).unwrap();
|
|
||||||
assert_eq!(v, false);
|
test_json_deserializer_ok([
|
||||||
|
(Boolean(true), true),
|
||||||
|
(Boolean(false), false),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3026,6 +3274,13 @@ mod tests {
|
|||||||
/*
|
/*
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decode_enum() {
|
fn test_decode_enum() {
|
||||||
|
let value: Result<Animal, ParserError> = from_iter("\"Dog\"".chars());
|
||||||
|
assert_eq!(value, Ok(Dog));
|
||||||
|
|
||||||
|
let s = "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}";
|
||||||
|
let value: Result<Animal, ParserError> = from_iter(s.chars());
|
||||||
|
assert_eq!(value, Ok(Frog("Henry".to_strbuf(), 349)));
|
||||||
|
|
||||||
let mut decoder = Decoder::new(from_str("\"Dog\"").unwrap());
|
let mut decoder = Decoder::new(from_str("\"Dog\"").unwrap());
|
||||||
let value: Animal = Decodable::decode(&mut decoder).unwrap();
|
let value: Animal = Decodable::decode(&mut decoder).unwrap();
|
||||||
assert_eq!(value, Dog);
|
assert_eq!(value, Dog);
|
||||||
@ -3034,8 +3289,11 @@ mod tests {
|
|||||||
let mut decoder = Decoder::new(from_str(s).unwrap());
|
let mut decoder = Decoder::new(from_str(s).unwrap());
|
||||||
let value: Animal = Decodable::decode(&mut decoder).unwrap();
|
let value: Animal = Decodable::decode(&mut decoder).unwrap();
|
||||||
assert_eq!(value, Frog("Henry".to_strbuf(), 349));
|
assert_eq!(value, Frog("Henry".to_strbuf(), 349));
|
||||||
|
assert_eq!(value, Dog);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decode_map() {
|
fn test_decode_map() {
|
||||||
let s = "{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\
|
let s = "{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\
|
||||||
|
Loading…
x
Reference in New Issue
Block a user