mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-12 23:41:03 +00:00
feat(codegen): Add support for #![serde(skip_serialize_if="$expr")]
This allows end users to use an arbitrary expression to decide whether
or not to serialize some field. This expression has access to all the
fields in the struct, but none of the internal state of the Serialize
implementation. For structs, serde implements this by creating a
temporary trait and implementing the struct for it. For struct variants,
the fields are copied by reference into a temporary struct first
before implementing the temporary trait.
This also fixes a bug where the serde_codegen wasn't making calls to
Serializer::serialize_{tuple,struct}_variant{,_elt}.
This commit is contained in:
@@ -9,10 +9,14 @@ use token::{
|
||||
|
||||
trait Trait {
|
||||
fn my_default() -> Self;
|
||||
|
||||
fn should_skip(&self) -> bool;
|
||||
}
|
||||
|
||||
impl Trait for i32 {
|
||||
fn my_default() -> Self { 123 }
|
||||
|
||||
fn should_skip(&self) -> bool { *self == 123 }
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
@@ -31,19 +35,19 @@ fn test_default_struct() {
|
||||
vec![
|
||||
Token::StructStart("DefaultStruct", Some(3)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a1"),
|
||||
Token::I32(1),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a2"),
|
||||
Token::I32(2),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a3"),
|
||||
Token::I32(3),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::StructEnd,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -52,11 +56,11 @@ fn test_default_struct() {
|
||||
vec![
|
||||
Token::StructStart("DefaultStruct", Some(1)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a1"),
|
||||
Token::I32(1),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::StructEnd,
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -79,19 +83,19 @@ fn test_default_enum() {
|
||||
vec![
|
||||
Token::EnumMapStart("DefaultEnum", "Struct", Some(3)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("a1"),
|
||||
Token::I32(1),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("a2"),
|
||||
Token::I32(2),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("a3"),
|
||||
Token::I32(3),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::EnumMapEnd,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -100,11 +104,11 @@ fn test_default_enum() {
|
||||
vec![
|
||||
Token::EnumMapStart("DefaultEnum", "Struct", Some(3)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("a1"),
|
||||
Token::I32(1),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::EnumMapEnd,
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -123,34 +127,34 @@ fn test_ignore_unknown() {
|
||||
vec![
|
||||
Token::StructStart("DefaultStruct", Some(5)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("whoops1"),
|
||||
Token::I32(2),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a1"),
|
||||
Token::I32(1),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("whoops2"),
|
||||
Token::SeqStart(Some(1)),
|
||||
Token::SeqSep,
|
||||
Token::I32(2),
|
||||
Token::SeqEnd,
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a2"),
|
||||
Token::I32(2),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("whoops3"),
|
||||
Token::I32(2),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a3"),
|
||||
Token::I32(3),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::StructEnd,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -158,15 +162,15 @@ fn test_ignore_unknown() {
|
||||
vec![
|
||||
Token::StructStart("DenyUnknown", Some(2)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a1"),
|
||||
Token::I32(1),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("whoops"),
|
||||
Token::I32(2),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::StructEnd,
|
||||
],
|
||||
Error::UnknownFieldError("whoops".to_owned())
|
||||
);
|
||||
@@ -195,15 +199,15 @@ fn test_rename_struct() {
|
||||
vec![
|
||||
Token::StructStart("Superhero", Some(2)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a1"),
|
||||
Token::I32(1),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a3"),
|
||||
Token::I32(2),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::StructEnd,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -212,15 +216,15 @@ fn test_rename_struct() {
|
||||
&[
|
||||
Token::StructStart("SuperheroSer", Some(2)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a1"),
|
||||
Token::I32(1),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a4"),
|
||||
Token::I32(2),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::StructEnd,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -229,15 +233,15 @@ fn test_rename_struct() {
|
||||
vec![
|
||||
Token::StructStart("SuperheroDe", Some(2)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a1"),
|
||||
Token::I32(1),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a5"),
|
||||
Token::I32(2),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::StructEnd,
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -281,7 +285,7 @@ fn test_rename_enum() {
|
||||
assert_tokens(
|
||||
&RenameEnum::Superman(0),
|
||||
vec![
|
||||
Token::EnumNewtype("Superhero", "clark_kent"),
|
||||
Token::EnumNewType("Superhero", "clark_kent"),
|
||||
Token::I8(0),
|
||||
]
|
||||
);
|
||||
@@ -291,13 +295,13 @@ fn test_rename_enum() {
|
||||
vec![
|
||||
Token::EnumSeqStart("Superhero", "diana_prince", Some(2)),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::EnumSeqSep,
|
||||
Token::I8(0),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::EnumSeqSep,
|
||||
Token::I8(1),
|
||||
|
||||
Token::SeqEnd,
|
||||
Token::EnumSeqEnd,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -306,11 +310,11 @@ fn test_rename_enum() {
|
||||
vec![
|
||||
Token::EnumMapStart("Superhero", "barry_allan", Some(1)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("b"),
|
||||
Token::I32(1),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::EnumMapEnd,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -322,15 +326,15 @@ fn test_rename_enum() {
|
||||
&[
|
||||
Token::EnumMapStart("SuperheroSer", "dick_grayson", Some(2)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("a"),
|
||||
Token::I8(0),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("c"),
|
||||
Token::Str(""),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::EnumMapEnd,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -342,24 +346,26 @@ fn test_rename_enum() {
|
||||
vec![
|
||||
Token::EnumMapStart("SuperheroDe", "jason_todd", Some(2)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("a"),
|
||||
Token::I8(0),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("d"),
|
||||
Token::Str(""),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::EnumMapEnd,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize)]
|
||||
struct SkipSerializingStruct<'a, B, D, E> {
|
||||
struct SkipSerializingStruct<'a, B, C, D, E> where C: Trait {
|
||||
a: &'a i8,
|
||||
#[serde(skip_serializing)]
|
||||
b: B,
|
||||
#[serde(skip_serializing_if="self.c.should_skip()")]
|
||||
c: C,
|
||||
#[serde(skip_serializing_if_none)]
|
||||
d: Option<D>,
|
||||
#[serde(skip_serializing_if_empty)]
|
||||
@@ -373,29 +379,34 @@ fn test_skip_serializing_struct() {
|
||||
&SkipSerializingStruct {
|
||||
a: &a,
|
||||
b: 2,
|
||||
c: 3,
|
||||
d: Some(4),
|
||||
e: vec![5],
|
||||
},
|
||||
&[
|
||||
Token::StructStart("SkipSerializingStruct", Some(3)),
|
||||
Token::StructStart("SkipSerializingStruct", Some(4)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a"),
|
||||
Token::I8(1),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("c"),
|
||||
Token::I32(3),
|
||||
|
||||
Token::StructSep,
|
||||
Token::Str("d"),
|
||||
Token::Option(true),
|
||||
Token::I32(4),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("e"),
|
||||
Token::SeqStart(Some(1)),
|
||||
Token::SeqSep,
|
||||
Token::I32(5),
|
||||
Token::SeqEnd,
|
||||
|
||||
Token::MapEnd,
|
||||
Token::StructEnd,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -403,27 +414,30 @@ fn test_skip_serializing_struct() {
|
||||
&SkipSerializingStruct {
|
||||
a: &a,
|
||||
b: 2,
|
||||
c: 123,
|
||||
d: None::<u8>,
|
||||
e: Vec::<u8>::new(),
|
||||
},
|
||||
&[
|
||||
Token::StructStart("SkipSerializingStruct", Some(1)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a"),
|
||||
Token::I8(1),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::StructEnd,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize)]
|
||||
enum SkipSerializingEnum<'a, B, D, E> {
|
||||
enum SkipSerializingEnum<'a, B, C, D, E> where C: Trait {
|
||||
Struct {
|
||||
a: &'a i8,
|
||||
#[serde(skip_serializing)]
|
||||
_b: B,
|
||||
#[serde(skip_serializing_if="self.c.should_skip()")]
|
||||
c: C,
|
||||
#[serde(skip_serializing_if_none)]
|
||||
d: Option<D>,
|
||||
#[serde(skip_serializing_if_empty)]
|
||||
@@ -438,29 +452,34 @@ fn test_skip_serializing_enum() {
|
||||
&SkipSerializingEnum::Struct {
|
||||
a: &a,
|
||||
_b: 2,
|
||||
c: 3,
|
||||
d: Some(4),
|
||||
e: vec![5],
|
||||
},
|
||||
&[
|
||||
Token::EnumMapStart("SkipSerializingEnum", "Struct", Some(3)),
|
||||
Token::EnumMapStart("SkipSerializingEnum", "Struct", Some(4)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("a"),
|
||||
Token::I8(1),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("c"),
|
||||
Token::I32(3),
|
||||
|
||||
Token::EnumMapSep,
|
||||
Token::Str("d"),
|
||||
Token::Option(true),
|
||||
Token::I32(4),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("e"),
|
||||
Token::SeqStart(Some(1)),
|
||||
Token::SeqSep,
|
||||
Token::I32(5),
|
||||
Token::SeqEnd,
|
||||
|
||||
Token::MapEnd,
|
||||
Token::EnumMapEnd,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -468,17 +487,18 @@ fn test_skip_serializing_enum() {
|
||||
&SkipSerializingEnum::Struct {
|
||||
a: &a,
|
||||
_b: 2,
|
||||
c: 123,
|
||||
d: None::<u8>,
|
||||
e: Vec::<u8>::new(),
|
||||
},
|
||||
&[
|
||||
Token::EnumMapStart("SkipSerializingEnum", "Struct", Some(1)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("a"),
|
||||
Token::I8(1),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::EnumMapEnd,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -184,27 +184,27 @@ declare_tests! {
|
||||
],
|
||||
TupleStruct(1, 2, 3) => vec![
|
||||
Token::TupleStructStart("TupleStruct", Some(3)),
|
||||
Token::SeqSep,
|
||||
Token::TupleSeqSep,
|
||||
Token::I32(1),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::TupleSeqSep,
|
||||
Token::I32(2),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::TupleSeqSep,
|
||||
Token::I32(3),
|
||||
Token::SeqEnd,
|
||||
Token::TupleSeqEnd,
|
||||
],
|
||||
TupleStruct(1, 2, 3) => vec![
|
||||
Token::TupleStructStart("TupleStruct", None),
|
||||
Token::SeqSep,
|
||||
Token::TupleSeqSep,
|
||||
Token::I32(1),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::TupleSeqSep,
|
||||
Token::I32(2),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::TupleSeqSep,
|
||||
Token::I32(3),
|
||||
Token::SeqEnd,
|
||||
Token::TupleSeqEnd,
|
||||
],
|
||||
}
|
||||
test_btreeset {
|
||||
@@ -495,18 +495,18 @@ declare_tests! {
|
||||
],
|
||||
Struct { a: 1, b: 2, c: 3 } => vec![
|
||||
Token::StructStart("Struct", Some(3)),
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a"),
|
||||
Token::I32(1),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("b"),
|
||||
Token::I32(2),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("c"),
|
||||
Token::I32(3),
|
||||
Token::MapEnd,
|
||||
Token::StructEnd,
|
||||
],
|
||||
}
|
||||
test_enum_unit {
|
||||
@@ -516,39 +516,39 @@ declare_tests! {
|
||||
}
|
||||
test_enum_simple {
|
||||
Enum::Simple(1) => vec![
|
||||
Token::EnumNewtype("Enum", "Simple"),
|
||||
Token::EnumNewType("Enum", "Simple"),
|
||||
Token::I32(1),
|
||||
],
|
||||
}
|
||||
test_enum_seq {
|
||||
Enum::Seq(1, 2, 3) => vec![
|
||||
Token::EnumSeqStart("Enum", "Seq", Some(3)),
|
||||
Token::SeqSep,
|
||||
Token::EnumSeqSep,
|
||||
Token::I32(1),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::EnumSeqSep,
|
||||
Token::I32(2),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::EnumSeqSep,
|
||||
Token::I32(3),
|
||||
Token::SeqEnd,
|
||||
Token::EnumSeqEnd,
|
||||
],
|
||||
}
|
||||
test_enum_map {
|
||||
Enum::Map { a: 1, b: 2, c: 3 } => vec![
|
||||
Token::EnumMapStart("Enum", "Map", Some(3)),
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("a"),
|
||||
Token::I32(1),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("b"),
|
||||
Token::I32(2),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("c"),
|
||||
Token::I32(3),
|
||||
Token::MapEnd,
|
||||
Token::EnumMapEnd,
|
||||
],
|
||||
}
|
||||
test_enum_unit_usize {
|
||||
|
||||
@@ -123,7 +123,7 @@ pub struct GenericStruct<T> {
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct GenericNewtypeStruct<T>(T);
|
||||
pub struct GenericNewTypeStruct<T>(T);
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct GenericTupleStruct<T, U>(T, U);
|
||||
@@ -131,7 +131,7 @@ pub struct GenericTupleStruct<T, U>(T, U);
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum GenericEnum<T, U> {
|
||||
Unit,
|
||||
Newtype(T),
|
||||
NewType(T),
|
||||
Seq(T, U),
|
||||
Map { x: T, y: U },
|
||||
}
|
||||
@@ -153,16 +153,16 @@ fn test_ser_named_tuple() {
|
||||
&SerNamedTuple(&a, &mut b, c),
|
||||
&[
|
||||
Token::TupleStructStart("SerNamedTuple", Some(3)),
|
||||
Token::SeqSep,
|
||||
Token::TupleSeqSep,
|
||||
Token::I32(5),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::TupleSeqSep,
|
||||
Token::I32(6),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::TupleSeqSep,
|
||||
Token::I32(7),
|
||||
|
||||
Token::SeqEnd,
|
||||
Token::TupleSeqEnd,
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -172,7 +172,7 @@ fn test_de_named_tuple() {
|
||||
assert_de_tokens(
|
||||
&DeNamedTuple(5, 6, 7),
|
||||
vec![
|
||||
Token::TupleStructStart("DeNamedTuple", Some(3)),
|
||||
Token::SeqStart(Some(3)),
|
||||
Token::SeqSep,
|
||||
Token::I32(5),
|
||||
|
||||
@@ -185,6 +185,23 @@ fn test_de_named_tuple() {
|
||||
Token::SeqEnd,
|
||||
]
|
||||
);
|
||||
|
||||
assert_de_tokens(
|
||||
&DeNamedTuple(5, 6, 7),
|
||||
vec![
|
||||
Token::TupleStructStart("DeNamedTuple", Some(3)),
|
||||
Token::TupleSeqSep,
|
||||
Token::I32(5),
|
||||
|
||||
Token::TupleSeqSep,
|
||||
Token::I32(6),
|
||||
|
||||
Token::TupleSeqSep,
|
||||
Token::I32(7),
|
||||
|
||||
Token::TupleSeqEnd,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -202,19 +219,19 @@ fn test_ser_named_map() {
|
||||
&[
|
||||
Token::StructStart("SerNamedMap", Some(3)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a"),
|
||||
Token::I32(5),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("b"),
|
||||
Token::I32(6),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("c"),
|
||||
Token::I32(7),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::StructEnd,
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -230,19 +247,19 @@ fn test_de_named_map() {
|
||||
vec![
|
||||
Token::StructStart("DeNamedMap", Some(3)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a"),
|
||||
Token::I32(5),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("b"),
|
||||
Token::I32(6),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("c"),
|
||||
Token::I32(7),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::StructEnd,
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -278,19 +295,19 @@ fn test_ser_enum_seq() {
|
||||
&[
|
||||
Token::EnumSeqStart("SerEnum", "Seq", Some(4)),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::EnumSeqSep,
|
||||
Token::I8(1),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::EnumSeqSep,
|
||||
Token::I32(2),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::EnumSeqSep,
|
||||
Token::I32(3),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::EnumSeqSep,
|
||||
Token::I32(5),
|
||||
|
||||
Token::SeqEnd,
|
||||
Token::EnumSeqEnd,
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -316,23 +333,23 @@ fn test_ser_enum_map() {
|
||||
&[
|
||||
Token::EnumMapStart("SerEnum", "Map", Some(4)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("a"),
|
||||
Token::I8(1),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("b"),
|
||||
Token::I32(2),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("c"),
|
||||
Token::I32(3),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("e"),
|
||||
Token::I32(5),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::EnumMapEnd,
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -368,19 +385,19 @@ fn test_de_enum_seq() {
|
||||
vec![
|
||||
Token::EnumSeqStart("DeEnum", "Seq", Some(4)),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::EnumSeqSep,
|
||||
Token::I8(1),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::EnumSeqSep,
|
||||
Token::I32(2),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::EnumSeqSep,
|
||||
Token::I32(3),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::EnumSeqSep,
|
||||
Token::I32(5),
|
||||
|
||||
Token::SeqEnd,
|
||||
Token::EnumSeqEnd,
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -406,23 +423,23 @@ fn test_de_enum_map() {
|
||||
vec![
|
||||
Token::EnumMapStart("DeEnum", "Map", Some(4)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("a"),
|
||||
Token::I8(1),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("b"),
|
||||
Token::I32(2),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("c"),
|
||||
Token::I32(3),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("e"),
|
||||
Token::I32(5),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::EnumMapEnd,
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -434,7 +451,7 @@ fn test_lifetimes() {
|
||||
assert_ser_tokens(
|
||||
&Lifetimes::LifetimeSeq(&value),
|
||||
&[
|
||||
Token::EnumNewtype("Lifetimes", "LifetimeSeq"),
|
||||
Token::EnumNewType("Lifetimes", "LifetimeSeq"),
|
||||
Token::I32(5),
|
||||
]
|
||||
);
|
||||
@@ -442,7 +459,7 @@ fn test_lifetimes() {
|
||||
assert_ser_tokens(
|
||||
&Lifetimes::NoLifetimeSeq(5),
|
||||
&[
|
||||
Token::EnumNewtype("Lifetimes", "NoLifetimeSeq"),
|
||||
Token::EnumNewType("Lifetimes", "NoLifetimeSeq"),
|
||||
Token::I32(5),
|
||||
]
|
||||
);
|
||||
@@ -452,11 +469,11 @@ fn test_lifetimes() {
|
||||
&[
|
||||
Token::EnumMapStart("Lifetimes", "LifetimeMap", Some(1)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("a"),
|
||||
Token::I32(5),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::EnumMapEnd,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -465,11 +482,11 @@ fn test_lifetimes() {
|
||||
&[
|
||||
Token::EnumMapStart("Lifetimes", "NoLifetimeMap", Some(1)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("a"),
|
||||
Token::I32(5),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::EnumMapEnd,
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -481,11 +498,11 @@ fn test_generic_struct() {
|
||||
vec![
|
||||
Token::StructStart("GenericStruct", Some(1)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("x"),
|
||||
Token::U32(5),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::StructEnd,
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -493,9 +510,9 @@ fn test_generic_struct() {
|
||||
#[test]
|
||||
fn test_generic_newtype_struct() {
|
||||
assert_tokens(
|
||||
&GenericNewtypeStruct(5u32),
|
||||
&GenericNewTypeStruct(5u32),
|
||||
vec![
|
||||
Token::StructNewtype("GenericNewtypeStruct"),
|
||||
Token::StructNewType("GenericNewTypeStruct"),
|
||||
Token::U32(5),
|
||||
]
|
||||
);
|
||||
@@ -508,13 +525,13 @@ fn test_generic_tuple_struct() {
|
||||
vec![
|
||||
Token::TupleStructStart("GenericTupleStruct", Some(2)),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::TupleSeqSep,
|
||||
Token::U32(5),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::TupleSeqSep,
|
||||
Token::U32(6),
|
||||
|
||||
Token::SeqEnd,
|
||||
Token::TupleSeqEnd,
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -532,9 +549,9 @@ fn test_generic_enum_unit() {
|
||||
#[test]
|
||||
fn test_generic_enum_newtype() {
|
||||
assert_tokens(
|
||||
&GenericEnum::Newtype::<u32, u32>(5),
|
||||
&GenericEnum::NewType::<u32, u32>(5),
|
||||
vec![
|
||||
Token::EnumNewtype("GenericEnum", "Newtype"),
|
||||
Token::EnumNewType("GenericEnum", "NewType"),
|
||||
Token::U32(5),
|
||||
]
|
||||
);
|
||||
@@ -547,13 +564,13 @@ fn test_generic_enum_seq() {
|
||||
vec![
|
||||
Token::EnumSeqStart("GenericEnum", "Seq", Some(2)),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::EnumSeqSep,
|
||||
Token::U32(5),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::EnumSeqSep,
|
||||
Token::U32(6),
|
||||
|
||||
Token::SeqEnd,
|
||||
Token::EnumSeqEnd,
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -565,15 +582,15 @@ fn test_generic_enum_map() {
|
||||
vec![
|
||||
Token::EnumMapStart("GenericEnum", "Map", Some(2)),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("x"),
|
||||
Token::U32(5),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("y"),
|
||||
Token::U32(6),
|
||||
|
||||
Token::MapEnd,
|
||||
Token::EnumMapEnd,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -76,11 +76,11 @@ declare_ser_tests! {
|
||||
}
|
||||
test_result {
|
||||
Ok::<i32, i32>(0) => &[
|
||||
Token::EnumNewtype("Result", "Ok"),
|
||||
Token::EnumNewType("Result", "Ok"),
|
||||
Token::I32(0),
|
||||
],
|
||||
Err::<i32, i32>(1) => &[
|
||||
Token::EnumNewtype("Result", "Err"),
|
||||
Token::EnumNewType("Result", "Err"),
|
||||
Token::I32(1),
|
||||
],
|
||||
}
|
||||
@@ -214,56 +214,56 @@ declare_ser_tests! {
|
||||
test_tuple_struct {
|
||||
TupleStruct(1, 2, 3) => &[
|
||||
Token::TupleStructStart("TupleStruct", Some(3)),
|
||||
Token::SeqSep,
|
||||
Token::TupleSeqSep,
|
||||
Token::I32(1),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::TupleSeqSep,
|
||||
Token::I32(2),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::TupleSeqSep,
|
||||
Token::I32(3),
|
||||
Token::SeqEnd,
|
||||
Token::TupleSeqEnd,
|
||||
],
|
||||
}
|
||||
test_struct {
|
||||
Struct { a: 1, b: 2, c: 3 } => &[
|
||||
Token::StructStart("Struct", Some(3)),
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("a"),
|
||||
Token::I32(1),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("b"),
|
||||
Token::I32(2),
|
||||
|
||||
Token::MapSep,
|
||||
Token::StructSep,
|
||||
Token::Str("c"),
|
||||
Token::I32(3),
|
||||
Token::MapEnd,
|
||||
Token::StructEnd,
|
||||
],
|
||||
}
|
||||
test_enum {
|
||||
Enum::Unit => &[Token::EnumUnit("Enum", "Unit")],
|
||||
Enum::One(42) => &[Token::EnumNewtype("Enum", "One"), Token::I32(42)],
|
||||
Enum::One(42) => &[Token::EnumNewType("Enum", "One"), Token::I32(42)],
|
||||
Enum::Seq(1, 2) => &[
|
||||
Token::EnumSeqStart("Enum", "Seq", Some(2)),
|
||||
Token::SeqSep,
|
||||
Token::EnumSeqSep,
|
||||
Token::I32(1),
|
||||
|
||||
Token::SeqSep,
|
||||
Token::EnumSeqSep,
|
||||
Token::I32(2),
|
||||
Token::SeqEnd,
|
||||
Token::EnumSeqEnd,
|
||||
],
|
||||
Enum::Map { a: 1, b: 2 } => &[
|
||||
Token::EnumMapStart("Enum", "Map", Some(2)),
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("a"),
|
||||
Token::I32(1),
|
||||
|
||||
Token::MapSep,
|
||||
Token::EnumMapSep,
|
||||
Token::Str("b"),
|
||||
Token::I32(2),
|
||||
Token::MapEnd,
|
||||
Token::EnumMapEnd,
|
||||
],
|
||||
}
|
||||
test_num_bigint {
|
||||
|
||||
+351
-45
@@ -2,7 +2,8 @@ use std::fmt;
|
||||
use std::iter;
|
||||
use std::error;
|
||||
|
||||
use serde::{ser, de};
|
||||
use serde::ser::{self, Serialize};
|
||||
use serde::de;
|
||||
use serde::de::value::{self, ValueDeserializer};
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
@@ -30,23 +31,35 @@ pub enum Token<'a> {
|
||||
Unit,
|
||||
UnitStruct(&'a str),
|
||||
|
||||
StructNewtype(&'a str),
|
||||
StructNewType(&'a str),
|
||||
|
||||
EnumStart(&'a str),
|
||||
EnumUnit(&'a str, &'a str),
|
||||
EnumNewtype(&'a str, &'a str),
|
||||
EnumSeqStart(&'a str, &'a str, Option<usize>),
|
||||
EnumMapStart(&'a str, &'a str, Option<usize>),
|
||||
EnumNewType(&'a str, &'a str),
|
||||
|
||||
SeqStart(Option<usize>),
|
||||
TupleStructStart(&'a str, Option<usize>),
|
||||
SeqSep,
|
||||
SeqEnd,
|
||||
|
||||
TupleStructStart(&'a str, Option<usize>),
|
||||
TupleSeqSep,
|
||||
TupleSeqEnd,
|
||||
|
||||
MapStart(Option<usize>),
|
||||
StructStart(&'a str, Option<usize>),
|
||||
MapSep,
|
||||
MapEnd,
|
||||
|
||||
StructStart(&'a str, Option<usize>),
|
||||
StructSep,
|
||||
StructEnd,
|
||||
|
||||
EnumSeqStart(&'a str, &'a str, Option<usize>),
|
||||
EnumSeqSep,
|
||||
EnumSeqEnd,
|
||||
|
||||
EnumMapStart(&'a str, &'a str, Option<usize>),
|
||||
EnumMapSep,
|
||||
EnumMapEnd,
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -102,7 +115,7 @@ impl<'a, I> ser::Serializer for Serializer<I>
|
||||
value: T) -> Result<(), Error>
|
||||
where T: ser::Serialize,
|
||||
{
|
||||
assert_eq!(self.tokens.next(), Some(&Token::EnumNewtype(name, variant)));
|
||||
assert_eq!(self.tokens.next(), Some(&Token::EnumNewType(name, variant)));
|
||||
value.serialize(self)
|
||||
}
|
||||
|
||||
@@ -218,43 +231,65 @@ impl<'a, I> ser::Serializer for Serializer<I>
|
||||
self.visit_sequence(visitor)
|
||||
}
|
||||
|
||||
fn serialize_seq_elt<T>(&mut self, value: T) -> Result<(), Error>
|
||||
where T: ser::Serialize
|
||||
{
|
||||
assert_eq!(self.tokens.next(), Some(&Token::SeqSep));
|
||||
value.serialize(self)
|
||||
}
|
||||
|
||||
fn serialize_newtype_struct<T>(&mut self,
|
||||
name: &'static str,
|
||||
value: T) -> Result<(), Error>
|
||||
where T: ser::Serialize,
|
||||
{
|
||||
assert_eq!(self.tokens.next(), Some(&Token::StructNewtype(name)));
|
||||
assert_eq!(self.tokens.next(), Some(&Token::StructNewType(name)));
|
||||
value.serialize(self)
|
||||
}
|
||||
|
||||
fn serialize_tuple_struct<V>(&mut self, name: &str, visitor: V) -> Result<(), Error>
|
||||
fn serialize_tuple_struct<V>(&mut self, name: &str, mut visitor: V) -> Result<(), Error>
|
||||
where V: ser::SeqVisitor
|
||||
{
|
||||
let len = visitor.len();
|
||||
|
||||
assert_eq!(self.tokens.next(), Some(&Token::TupleStructStart(name, len)));
|
||||
|
||||
self.visit_sequence(visitor)
|
||||
while let Some(()) = try!(visitor.visit(self)) { }
|
||||
|
||||
assert_eq!(self.tokens.next(), Some(&Token::TupleSeqEnd));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_tuple_struct_elt<T>(&mut self, value: T) -> Result<(), Error>
|
||||
where T: ser::Serialize,
|
||||
{
|
||||
assert_eq!(self.tokens.next(), Some(&Token::TupleSeqSep));
|
||||
value.serialize(self)
|
||||
}
|
||||
|
||||
fn serialize_tuple_variant<V>(&mut self,
|
||||
name: &str,
|
||||
_variant_index: usize,
|
||||
variant: &str,
|
||||
visitor: V) -> Result<(), Error>
|
||||
name: &str,
|
||||
_variant_index: usize,
|
||||
variant: &str,
|
||||
mut visitor: V) -> Result<(), Error>
|
||||
where V: ser::SeqVisitor
|
||||
{
|
||||
let len = visitor.len();
|
||||
|
||||
assert_eq!(self.tokens.next(), Some(&Token::EnumSeqStart(name, variant, len)));
|
||||
|
||||
self.visit_sequence(visitor)
|
||||
while let Some(()) = try!(visitor.visit(self)) { }
|
||||
|
||||
assert_eq!(self.tokens.next(), Some(&Token::EnumSeqEnd));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_seq_elt<T>(&mut self, value: T) -> Result<(), Error>
|
||||
where T: ser::Serialize
|
||||
fn serialize_tuple_variant_elt<T>(&mut self, value: T) -> Result<(), Error>
|
||||
where T: ser::Serialize,
|
||||
{
|
||||
assert_eq!(self.tokens.next(), Some(&Token::SeqSep));
|
||||
assert_eq!(self.tokens.next(), Some(&Token::EnumSeqSep));
|
||||
value.serialize(self)
|
||||
}
|
||||
|
||||
@@ -268,35 +303,61 @@ impl<'a, I> ser::Serializer for Serializer<I>
|
||||
self.visit_mapping(visitor)
|
||||
}
|
||||
|
||||
fn serialize_struct<V>(&mut self, name: &str, visitor: V) -> Result<(), Error>
|
||||
fn serialize_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), Error>
|
||||
where K: ser::Serialize,
|
||||
V: ser::Serialize,
|
||||
{
|
||||
assert_eq!(self.tokens.next(), Some(&Token::MapSep));
|
||||
|
||||
try!(key.serialize(self));
|
||||
value.serialize(self)
|
||||
}
|
||||
|
||||
fn serialize_struct<V>(&mut self, name: &str, mut visitor: V) -> Result<(), Error>
|
||||
where V: ser::MapVisitor
|
||||
{
|
||||
let len = visitor.len();
|
||||
|
||||
assert_eq!(self.tokens.next(), Some(&Token::StructStart(name, len)));
|
||||
|
||||
self.visit_mapping(visitor)
|
||||
while let Some(()) = try!(visitor.visit(self)) { }
|
||||
|
||||
assert_eq!(self.tokens.next(), Some(&Token::StructEnd));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_struct_elt<T>(&mut self, key: &'static str, value: T) -> Result<(), Error>
|
||||
where T: ser::Serialize,
|
||||
{
|
||||
assert_eq!(self.tokens.next(), Some(&Token::StructSep));
|
||||
|
||||
try!(key.serialize(self));
|
||||
value.serialize(self)
|
||||
}
|
||||
|
||||
fn serialize_struct_variant<V>(&mut self,
|
||||
name: &str,
|
||||
_variant_index: usize,
|
||||
variant: &str,
|
||||
visitor: V) -> Result<(), Error>
|
||||
name: &str,
|
||||
_variant_index: usize,
|
||||
variant: &str,
|
||||
mut visitor: V) -> Result<(), Error>
|
||||
where V: ser::MapVisitor
|
||||
{
|
||||
let len = visitor.len();
|
||||
|
||||
assert_eq!(self.tokens.next(), Some(&Token::EnumMapStart(name, variant, len)));
|
||||
|
||||
self.visit_mapping(visitor)
|
||||
while let Some(()) = try!(visitor.visit(self)) { }
|
||||
|
||||
assert_eq!(self.tokens.next(), Some(&Token::EnumMapEnd));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), Error>
|
||||
where K: ser::Serialize,
|
||||
V: ser::Serialize,
|
||||
fn serialize_struct_variant_elt<T>(&mut self, key: &'static str, value: T) -> Result<(), Error>
|
||||
where T: ser::Serialize,
|
||||
{
|
||||
assert_eq!(self.tokens.next(), Some(&Token::MapSep));
|
||||
assert_eq!(self.tokens.next(), Some(&Token::EnumMapSep));
|
||||
|
||||
try!(key.serialize(self));
|
||||
value.serialize(self)
|
||||
@@ -383,6 +444,24 @@ impl<I> Deserializer<I>
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_tuple_seq<V>(&mut self, len: Option<usize>, mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::Visitor,
|
||||
{
|
||||
visitor.visit_seq(DeserializerTupleSeqVisitor {
|
||||
de: self,
|
||||
len: len,
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_variant_seq<V>(&mut self, len: Option<usize>, mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::Visitor,
|
||||
{
|
||||
visitor.visit_seq(DeserializerVariantSeqVisitor {
|
||||
de: self,
|
||||
len: len,
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_map<V>(&mut self, len: Option<usize>, mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::Visitor,
|
||||
{
|
||||
@@ -391,6 +470,24 @@ impl<I> Deserializer<I>
|
||||
len: len,
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_struct<V>(&mut self, len: Option<usize>, mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::Visitor,
|
||||
{
|
||||
visitor.visit_map(DeserializerStructVisitor {
|
||||
de: self,
|
||||
len: len,
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_variant_map<V>(&mut self, len: Option<usize>, mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::Visitor,
|
||||
{
|
||||
visitor.visit_map(DeserializerVariantMapVisitor {
|
||||
de: self,
|
||||
len: len,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<I> de::Deserializer for Deserializer<I>
|
||||
@@ -429,7 +526,6 @@ impl<I> de::Deserializer for Deserializer<I>
|
||||
Some(Token::MapStart(len)) | Some(Token::StructStart(_, len)) => {
|
||||
self.visit_map(len, visitor)
|
||||
}
|
||||
//Some(Token::Name(_)) => self.visit(visitor),
|
||||
Some(token) => Err(Error::UnexpectedToken(token)),
|
||||
None => Err(Error::EndOfStreamError),
|
||||
}
|
||||
@@ -473,7 +569,7 @@ impl<I> de::Deserializer for Deserializer<I>
|
||||
})
|
||||
}
|
||||
Some(&Token::EnumUnit(n, _))
|
||||
| Some(&Token::EnumNewtype(n, _))
|
||||
| Some(&Token::EnumNewType(n, _))
|
||||
| Some(&Token::EnumSeqStart(n, _, _))
|
||||
| Some(&Token::EnumMapStart(n, _, _)) if name == n => {
|
||||
visitor.visit(DeserializerVariantVisitor {
|
||||
@@ -506,12 +602,12 @@ impl<I> de::Deserializer for Deserializer<I>
|
||||
}
|
||||
|
||||
fn deserialize_newtype_struct<V>(&mut self,
|
||||
name: &str,
|
||||
mut visitor: V) -> Result<V::Value, Error>
|
||||
name: &str,
|
||||
mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::Visitor,
|
||||
{
|
||||
match self.tokens.peek() {
|
||||
Some(&Token::StructNewtype(n)) => {
|
||||
Some(&Token::StructNewType(n)) => {
|
||||
self.tokens.next();
|
||||
if name == n {
|
||||
visitor.visit_newtype_struct(self)
|
||||
@@ -525,9 +621,9 @@ impl<I> de::Deserializer for Deserializer<I>
|
||||
}
|
||||
|
||||
fn deserialize_tuple_struct<V>(&mut self,
|
||||
name: &str,
|
||||
len: usize,
|
||||
mut visitor: V) -> Result<V::Value, Error>
|
||||
name: &str,
|
||||
len: usize,
|
||||
mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::Visitor,
|
||||
{
|
||||
match self.tokens.peek() {
|
||||
@@ -542,7 +638,7 @@ impl<I> de::Deserializer for Deserializer<I>
|
||||
Some(&Token::TupleStructStart(n, _)) => {
|
||||
self.tokens.next();
|
||||
if name == n {
|
||||
self.visit_seq(Some(len), visitor)
|
||||
self.visit_tuple_seq(Some(len), visitor)
|
||||
} else {
|
||||
Err(Error::InvalidName(n))
|
||||
}
|
||||
@@ -557,16 +653,16 @@ impl<I> de::Deserializer for Deserializer<I>
|
||||
}
|
||||
|
||||
fn deserialize_struct<V>(&mut self,
|
||||
name: &str,
|
||||
fields: &'static [&'static str],
|
||||
visitor: V) -> Result<V::Value, Error>
|
||||
name: &str,
|
||||
fields: &'static [&'static str],
|
||||
visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::Visitor,
|
||||
{
|
||||
match self.tokens.peek() {
|
||||
Some(&Token::StructStart(n, _)) => {
|
||||
self.tokens.next();
|
||||
if name == n {
|
||||
self.visit_map(Some(fields.len()), visitor)
|
||||
self.visit_struct(Some(fields.len()), visitor)
|
||||
} else {
|
||||
Err(Error::InvalidName(n))
|
||||
}
|
||||
@@ -628,6 +724,96 @@ impl<'a, I> de::SeqVisitor for DeserializerSeqVisitor<'a, I>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct DeserializerTupleSeqVisitor<'a, I: 'a> where I: Iterator<Item=Token<'static>> {
|
||||
de: &'a mut Deserializer<I>,
|
||||
len: Option<usize>,
|
||||
}
|
||||
|
||||
impl<'a, I> de::SeqVisitor for DeserializerTupleSeqVisitor<'a, I>
|
||||
where I: Iterator<Item=Token<'static>>,
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
||||
where T: de::Deserialize,
|
||||
{
|
||||
match self.de.tokens.peek() {
|
||||
Some(&Token::TupleSeqSep) => {
|
||||
self.de.tokens.next();
|
||||
self.len = self.len.map(|len| len - 1);
|
||||
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
|
||||
}
|
||||
Some(&Token::TupleSeqEnd) => Ok(None),
|
||||
Some(_) => {
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStreamError),
|
||||
}
|
||||
}
|
||||
|
||||
fn end(&mut self) -> Result<(), Error> {
|
||||
//assert_eq!(self.len.unwrap_or(0), 0);
|
||||
match self.de.tokens.next() {
|
||||
Some(Token::TupleSeqEnd) => Ok(()),
|
||||
Some(token) => Err(Error::UnexpectedToken(token)),
|
||||
None => Err(Error::EndOfStreamError),
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let len = self.len.unwrap_or(0);
|
||||
(len, self.len)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct DeserializerVariantSeqVisitor<'a, I: 'a> where I: Iterator<Item=Token<'static>> {
|
||||
de: &'a mut Deserializer<I>,
|
||||
len: Option<usize>,
|
||||
}
|
||||
|
||||
impl<'a, I> de::SeqVisitor for DeserializerVariantSeqVisitor<'a, I>
|
||||
where I: Iterator<Item=Token<'static>>,
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
||||
where T: de::Deserialize,
|
||||
{
|
||||
match self.de.tokens.peek() {
|
||||
Some(&Token::EnumSeqSep) => {
|
||||
self.de.tokens.next();
|
||||
self.len = self.len.map(|len| len - 1);
|
||||
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
|
||||
}
|
||||
Some(&Token::EnumSeqEnd) => Ok(None),
|
||||
Some(_) => {
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStreamError),
|
||||
}
|
||||
}
|
||||
|
||||
fn end(&mut self) -> Result<(), Error> {
|
||||
//assert_eq!(self.len.unwrap_or(0), 0);
|
||||
match self.de.tokens.next() {
|
||||
Some(Token::EnumSeqEnd) => Ok(()),
|
||||
Some(token) => Err(Error::UnexpectedToken(token)),
|
||||
None => Err(Error::EndOfStreamError),
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let len = self.len.unwrap_or(0);
|
||||
(len, self.len)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct DeserializerMapVisitor<'a, I: 'a> where I: Iterator<Item=Token<'static>> {
|
||||
de: &'a mut Deserializer<I>,
|
||||
len: Option<usize>,
|
||||
@@ -679,6 +865,57 @@ impl<'a, I> de::MapVisitor for DeserializerMapVisitor<'a, I>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct DeserializerStructVisitor<'a, I: 'a> where I: Iterator<Item=Token<'static>> {
|
||||
de: &'a mut Deserializer<I>,
|
||||
len: Option<usize>,
|
||||
}
|
||||
|
||||
impl<'a, I> de::MapVisitor for DeserializerStructVisitor<'a, I>
|
||||
where I: Iterator<Item=Token<'static>>,
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
|
||||
where K: de::Deserialize,
|
||||
{
|
||||
match self.de.tokens.peek() {
|
||||
Some(&Token::StructSep) => {
|
||||
self.de.tokens.next();
|
||||
self.len = self.len.map(|len| if len > 0 { len - 1} else { 0 });
|
||||
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
|
||||
}
|
||||
Some(&Token::StructEnd) => Ok(None),
|
||||
Some(_) => {
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStreamError),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_value<V>(&mut self) -> Result<V, Error>
|
||||
where V: de::Deserialize,
|
||||
{
|
||||
Ok(try!(de::Deserialize::deserialize(self.de)))
|
||||
}
|
||||
|
||||
fn end(&mut self) -> Result<(), Error> {
|
||||
//assert_eq!(self.len.unwrap_or(0), 0);
|
||||
match self.de.tokens.next() {
|
||||
Some(Token::StructEnd) => Ok(()),
|
||||
Some(token) => Err(Error::UnexpectedToken(token)),
|
||||
None => Err(Error::EndOfStreamError),
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let len = self.len.unwrap_or(0);
|
||||
(len, self.len)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct DeserializerVariantVisitor<'a, I: 'a> where I: Iterator<Item=Token<'static>> {
|
||||
de: &'a mut Deserializer<I>,
|
||||
}
|
||||
@@ -693,7 +930,7 @@ impl<'a, I> de::VariantVisitor for DeserializerVariantVisitor<'a, I>
|
||||
{
|
||||
match self.de.tokens.peek() {
|
||||
Some(&Token::EnumUnit(_, v))
|
||||
| Some(&Token::EnumNewtype(_, v))
|
||||
| Some(&Token::EnumNewType(_, v))
|
||||
| Some(&Token::EnumSeqStart(_, v, _))
|
||||
| Some(&Token::EnumMapStart(_, v, _)) => {
|
||||
let mut de = ValueDeserializer::<Error>::into_deserializer(v);
|
||||
@@ -724,7 +961,7 @@ impl<'a, I> de::VariantVisitor for DeserializerVariantVisitor<'a, I>
|
||||
where T: de::Deserialize,
|
||||
{
|
||||
match self.de.tokens.peek() {
|
||||
Some(&Token::EnumNewtype(_, _)) => {
|
||||
Some(&Token::EnumNewType(_, _)) => {
|
||||
self.de.tokens.next();
|
||||
de::Deserialize::deserialize(self.de)
|
||||
}
|
||||
@@ -744,6 +981,15 @@ impl<'a, I> de::VariantVisitor for DeserializerVariantVisitor<'a, I>
|
||||
Some(&Token::EnumSeqStart(_, _, Some(enum_len))) => {
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
|
||||
if len == enum_len {
|
||||
self.de.visit_variant_seq(Some(len), visitor)
|
||||
} else {
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
}
|
||||
Some(&Token::SeqStart(Some(enum_len))) => {
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
|
||||
if len == enum_len {
|
||||
self.de.visit_seq(Some(len), visitor)
|
||||
} else {
|
||||
@@ -766,6 +1012,15 @@ impl<'a, I> de::VariantVisitor for DeserializerVariantVisitor<'a, I>
|
||||
Some(&Token::EnumMapStart(_, _, Some(enum_len))) => {
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
|
||||
if fields.len() == enum_len {
|
||||
self.de.visit_variant_map(Some(fields.len()), visitor)
|
||||
} else {
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
}
|
||||
Some(&Token::MapStart(Some(enum_len))) => {
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
|
||||
if fields.len() == enum_len {
|
||||
self.de.visit_map(Some(fields.len()), visitor)
|
||||
} else {
|
||||
@@ -780,6 +1035,57 @@ impl<'a, I> de::VariantVisitor for DeserializerVariantVisitor<'a, I>
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct DeserializerVariantMapVisitor<'a, I: 'a> where I: Iterator<Item=Token<'static>> {
|
||||
de: &'a mut Deserializer<I>,
|
||||
len: Option<usize>,
|
||||
}
|
||||
|
||||
impl<'a, I> de::MapVisitor for DeserializerVariantMapVisitor<'a, I>
|
||||
where I: Iterator<Item=Token<'static>>,
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
|
||||
where K: de::Deserialize,
|
||||
{
|
||||
match self.de.tokens.peek() {
|
||||
Some(&Token::EnumMapSep) => {
|
||||
self.de.tokens.next();
|
||||
self.len = self.len.map(|len| if len > 0 { len - 1} else { 0 });
|
||||
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
|
||||
}
|
||||
Some(&Token::EnumMapEnd) => Ok(None),
|
||||
Some(_) => {
|
||||
let token = self.de.tokens.next().unwrap();
|
||||
Err(Error::UnexpectedToken(token))
|
||||
}
|
||||
None => Err(Error::EndOfStreamError),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_value<V>(&mut self) -> Result<V, Error>
|
||||
where V: de::Deserialize,
|
||||
{
|
||||
Ok(try!(de::Deserialize::deserialize(self.de)))
|
||||
}
|
||||
|
||||
fn end(&mut self) -> Result<(), Error> {
|
||||
//assert_eq!(self.len.unwrap_or(0), 0);
|
||||
match self.de.tokens.next() {
|
||||
Some(Token::EnumMapEnd) => Ok(()),
|
||||
Some(token) => Err(Error::UnexpectedToken(token)),
|
||||
None => Err(Error::EndOfStreamError),
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let len = self.len.unwrap_or(0);
|
||||
(len, self.len)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub fn assert_ser_tokens<T>(value: &T, tokens: &[Token])
|
||||
|
||||
Reference in New Issue
Block a user