structs should deserialize from a map

This commit is contained in:
Erick Tryzelaar 2014-05-27 21:46:31 -07:00
parent bf58f7999f
commit c70e9f0eae
2 changed files with 91 additions and 30 deletions

View File

@ -3,6 +3,7 @@ use test::Bencher;
use serialize::{Decoder, Decodable};
use de;
use de::{Token, Deserializer, Deserializable};
//////////////////////////////////////////////////////////////////////////////
@ -17,12 +18,57 @@ struct Inner {
impl<E, D: Deserializer<E>> Deserializable<E, D> for Inner {
#[inline]
fn deserialize_token(d: &mut D, token: Token) -> Result<Inner, E> {
try!(d.expect_struct_start(token, "Inner"));
let a = try!(d.expect_struct_field("a"));
let b = try!(d.expect_struct_field("b"));
let c = try!(d.expect_struct_field("c"));
try!(d.expect_end());
Ok(Inner { a: a, b: b, c: c })
match token {
de::StructStart("Inner") |
de::MapStart(_) => {
let mut a = None;
let mut b = None;
let mut c = None;
loop {
match try!(d.expect_token()) {
de::End => { break; }
de::Str(name) => {
match name {
"a" => {
a = Some(try!(de::Deserializable::deserialize(d)));
}
"b" => {
b = Some(try!(de::Deserializable::deserialize(d)));
}
"c" => {
c = Some(try!(de::Deserializable::deserialize(d)));
}
_ => { }
}
}
de::String(ref name) => {
match name.as_slice() {
"a" => {
a = Some(try!(de::Deserializable::deserialize(d)));
}
"b" => {
b = Some(try!(de::Deserializable::deserialize(d)));
}
"c" => {
c = Some(try!(de::Deserializable::deserialize(d)));
}
_ => { }
}
}
_ => { return Err(d.syntax_error()); }
}
}
match (a, b, c) {
(Some(a), Some(b), Some(c)) => {
Ok(Inner { a: a, b: b, c: c })
}
_ => Err(d.syntax_error()),
}
}
_ => Err(d.syntax_error()),
}
}
}
@ -36,10 +82,43 @@ struct Outer {
impl<E, D: Deserializer<E>> Deserializable<E, D> for Outer {
#[inline]
fn deserialize_token(d: &mut D, token: Token) -> Result<Outer, E> {
try!(d.expect_struct_start(token, "Outer"));
let inner = try!(d.expect_struct_field("inner"));
try!(d.expect_end());
Ok(Outer { inner: inner })
match token {
de::StructStart("Outer") |
de::MapStart(_) => {
let mut inner = None;
loop {
match try!(d.expect_token()) {
de::End => { break; }
de::Str(name) => {
match name {
"inner" => {
inner = Some(try!(de::Deserializable::deserialize(d)));
}
_ => { }
}
}
de::String(ref name) => {
match name.as_slice() {
"inner" => {
inner = Some(try!(de::Deserializable::deserialize(d)));
}
_ => { }
}
}
_ => { return Err(d.syntax_error()); }
}
}
match inner {
Some(inner) => {
Ok(Outer { inner: inner })
}
_ => Err(d.syntax_error()),
}
}
_ => Err(d.syntax_error()),
}
}
}

22
json.rs
View File

@ -2288,17 +2288,7 @@ mod tests {
#[inline]
fn deserialize_token(d: &mut D, token: de::Token) -> Result<Inner, E> {
match token {
de::StructStart(name) => {
if name != "Inner" {
return Err(d.syntax_error());
}
let a = try!(d.expect_struct_field("a"));
let b = try!(d.expect_struct_field("b"));
let c = try!(d.expect_struct_field("c"));
try!(d.expect_end());
Ok(Inner { a: a, b: b, c: c })
}
de::StructStart("Inner") |
de::MapStart(_) => {
let mut a = None;
let mut b = None;
@ -2360,15 +2350,7 @@ mod tests {
#[inline]
fn deserialize_token(d: &mut D, token: de::Token) -> Result<Outer, E> {
match token {
de::StructStart(name) => {
if name != "Outer" {
return Err(d.syntax_error());
}
let inner = try!(d.expect_struct_field("inner"));
try!(d.expect_end());
Ok(Outer { inner: inner })
}
de::StructStart("Outer") |
de::MapStart(_) => {
let mut inner = None;