From ff02b0c7419015ba403444d609149aa45055e44f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 12 Apr 2016 23:42:24 -0700 Subject: [PATCH] fix(codegen): Take into account default=... when skip_deserializing --- serde_codegen/src/attr.rs | 7 ++++ serde_codegen/src/de.rs | 4 +-- serde_tests/tests/test_annotations.rs | 48 ++++++++++++++++++++++----- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/serde_codegen/src/attr.rs b/serde_codegen/src/attr.rs index 172b7f97..6caf91a2 100644 --- a/serde_codegen/src/attr.rs +++ b/serde_codegen/src/attr.rs @@ -249,6 +249,13 @@ impl FieldAttrs { // Parse `#[serde(skip_deserializing)]` ast::MetaItemKind::Word(ref name) if name == &"skip_deserializing" => { field_attrs.skip_deserializing_field = true; + + // Initialize field to Default::default() unless a different + // default is specified by `#[serde(default="...")]` + if field_attrs.default_expr_if_missing.is_none() { + let default_expr = builder.expr().default(); + field_attrs.default_expr_if_missing = Some(default_expr); + } } // Parse `#[serde(skip_serializing_if="...")]` diff --git a/serde_codegen/src/de.rs b/serde_codegen/src/de.rs index 2c5081a3..4b7b4623 100644 --- a/serde_codegen/src/de.rs +++ b/serde_codegen/src/de.rs @@ -437,7 +437,7 @@ fn deserialize_struct_as_seq( .map(|(i, &(_, ref attrs))| { let name = builder.id(format!("__field{}", i)); if attrs.skip_deserializing_field() { - let default = builder.expr().default(); + let default = attrs.expr_is_missing(); quote_stmt!(cx, let $name = $default; ).unwrap() @@ -1103,7 +1103,7 @@ fn deserialize_map( } }, if attrs.skip_deserializing_field() { - builder.expr().default() + attrs.expr_is_missing() } else { builder.expr().id(name) } diff --git a/serde_tests/tests/test_annotations.rs b/serde_tests/tests/test_annotations.rs index a1f27bf8..5d25af74 100644 --- a/serde_tests/tests/test_annotations.rs +++ b/serde_tests/tests/test_annotations.rs @@ -61,18 +61,25 @@ impl DeserializeWith for i32 { } #[derive(Debug, PartialEq, Serialize, Deserialize)] -struct DefaultStruct where C: MyDefault { +struct DefaultStruct + where C: MyDefault, + E: MyDefault, +{ a1: A, #[serde(default)] a2: B, #[serde(default="MyDefault::my_default")] a3: C, + #[serde(skip_deserializing)] + a4: D, + #[serde(skip_deserializing, default="MyDefault::my_default")] + a5: E, } #[test] fn test_default_struct() { assert_de_tokens( - &DefaultStruct { a1: 1, a2: 2, a3: 3 }, + &DefaultStruct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 }, vec![ Token::StructStart("DefaultStruct", Some(3)), @@ -88,12 +95,20 @@ fn test_default_struct() { Token::Str("a3"), Token::I32(3), + Token::StructSep, + Token::Str("a4"), + Token::I32(4), + + Token::StructSep, + Token::Str("a5"), + Token::I32(5), + Token::StructEnd, ] ); assert_de_tokens( - &DefaultStruct { a1: 1, a2: 0, a3: 123 }, + &DefaultStruct { a1: 1, a2: 0, a3: 123, a4: 0, a5: 123 }, vec![ Token::StructStart("DefaultStruct", Some(1)), @@ -107,22 +122,29 @@ fn test_default_struct() { } #[derive(Debug, PartialEq, Serialize, Deserialize)] -enum DefaultEnum where C: MyDefault { +enum DefaultEnum + where C: MyDefault, + E: MyDefault +{ Struct { a1: A, #[serde(default)] a2: B, #[serde(default="MyDefault::my_default")] a3: C, + #[serde(skip_deserializing)] + a4: D, + #[serde(skip_deserializing, default="MyDefault::my_default")] + a5: E, } } #[test] fn test_default_enum() { assert_de_tokens( - &DefaultEnum::Struct { a1: 1, a2: 2, a3: 3 }, + &DefaultEnum::Struct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 }, vec![ - Token::EnumMapStart("DefaultEnum", "Struct", Some(3)), + Token::EnumMapStart("DefaultEnum", "Struct", Some(5)), Token::EnumMapSep, Token::Str("a1"), @@ -136,14 +158,22 @@ fn test_default_enum() { Token::Str("a3"), Token::I32(3), + Token::EnumMapSep, + Token::Str("a4"), + Token::I32(4), + + Token::EnumMapSep, + Token::Str("a5"), + Token::I32(5), + Token::EnumMapEnd, ] ); assert_de_tokens( - &DefaultEnum::Struct { a1: 1, a2: 0, a3: 123 }, + &DefaultEnum::Struct { a1: 1, a2: 0, a3: 123, a4: 0, a5: 123 }, vec![ - Token::EnumMapStart("DefaultEnum", "Struct", Some(3)), + Token::EnumMapStart("DefaultEnum", "Struct", Some(5)), Token::EnumMapSep, Token::Str("a1"), @@ -164,7 +194,7 @@ struct DenyUnknown { fn test_ignore_unknown() { // 'Default' allows unknown. Basic smoke test of ignore... assert_de_tokens( - &DefaultStruct { a1: 1, a2: 2, a3: 3 }, + &DefaultStruct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 }, vec![ Token::StructStart("DefaultStruct", Some(5)),