mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-13 17:11:02 +00:00
structs should deserialize from a map
This commit is contained in:
+89
-10
@@ -3,6 +3,7 @@ use test::Bencher;
|
|||||||
|
|
||||||
use serialize::{Decoder, Decodable};
|
use serialize::{Decoder, Decodable};
|
||||||
|
|
||||||
|
use de;
|
||||||
use de::{Token, Deserializer, Deserializable};
|
use de::{Token, Deserializer, Deserializable};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -17,12 +18,57 @@ struct Inner {
|
|||||||
impl<E, D: Deserializer<E>> Deserializable<E, D> for Inner {
|
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> {
|
||||||
try!(d.expect_struct_start(token, "Inner"));
|
match token {
|
||||||
let a = try!(d.expect_struct_field("a"));
|
de::StructStart("Inner") |
|
||||||
let b = try!(d.expect_struct_field("b"));
|
de::MapStart(_) => {
|
||||||
let c = try!(d.expect_struct_field("c"));
|
let mut a = None;
|
||||||
try!(d.expect_end());
|
let mut b = None;
|
||||||
Ok(Inner { a: a, b: b, c: c })
|
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 {
|
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> {
|
||||||
try!(d.expect_struct_start(token, "Outer"));
|
match token {
|
||||||
let inner = try!(d.expect_struct_field("inner"));
|
de::StructStart("Outer") |
|
||||||
try!(d.expect_end());
|
de::MapStart(_) => {
|
||||||
Ok(Outer { inner: inner })
|
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()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2288,17 +2288,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(name) => {
|
de::StructStart("Inner") |
|
||||||
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::MapStart(_) => {
|
de::MapStart(_) => {
|
||||||
let mut a = None;
|
let mut a = None;
|
||||||
let mut b = None;
|
let mut b = None;
|
||||||
@@ -2360,15 +2350,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(name) => {
|
de::StructStart("Outer") |
|
||||||
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::MapStart(_) => {
|
de::MapStart(_) => {
|
||||||
let mut inner = None;
|
let mut inner = None;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user