From 348bc6b25726ee3d514a5e2b98a646cdc28f9585 Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 11:50:46 +0500 Subject: [PATCH 01/10] Move flatten enum tests to a dedicated module (review with "ignore whitespace" option on and editor that shows line moves, for example, TortoiseGitMerge) --- test_suite/tests/test_annotations.rs | 616 ++++++++++++++------------- 1 file changed, 320 insertions(+), 296 deletions(-) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index 82a98c36..f8f87948 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -115,42 +115,6 @@ struct CollectOther { extra: HashMap, } -#[derive(Debug, PartialEq, Serialize, Deserialize)] -struct FlattenStructEnumWrapper { - #[serde(flatten)] - data: FlattenStructEnum, - #[serde(flatten)] - extra: HashMap, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "snake_case")] -enum FlattenStructEnum { - InsertInteger { index: u32, value: u32 }, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -struct FlattenStructTagContentEnumWrapper { - outer: u32, - #[serde(flatten)] - data: FlattenStructTagContentEnumNewtype, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -struct FlattenStructTagContentEnumNewtype(pub FlattenStructTagContentEnum); - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "snake_case", tag = "type", content = "value")] -enum FlattenStructTagContentEnum { - InsertInteger { index: u32, value: u32 }, - NewtypeVariant(FlattenStructTagContentEnumNewtypeVariant), -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -struct FlattenStructTagContentEnumNewtypeVariant { - value: u32, -} - #[test] fn test_default_struct() { assert_de_tokens( @@ -1644,149 +1608,6 @@ fn test_collect_other() { ); } -#[test] -fn test_flatten_struct_enum() { - let mut extra = HashMap::new(); - extra.insert("extra_key".into(), "extra value".into()); - let change_request = FlattenStructEnumWrapper { - data: FlattenStructEnum::InsertInteger { - index: 0, - value: 42, - }, - extra, - }; - assert_de_tokens( - &change_request, - &[ - Token::Map { len: None }, - Token::Str("insert_integer"), - Token::Map { len: None }, - Token::Str("index"), - Token::U32(0), - Token::Str("value"), - Token::U32(42), - Token::MapEnd, - Token::Str("extra_key"), - Token::Str("extra value"), - Token::MapEnd, - ], - ); - assert_ser_tokens( - &change_request, - &[ - Token::Map { len: None }, - Token::Str("insert_integer"), - Token::Struct { - len: 2, - name: "insert_integer", - }, - Token::Str("index"), - Token::U32(0), - Token::Str("value"), - Token::U32(42), - Token::StructEnd, - Token::Str("extra_key"), - Token::Str("extra value"), - Token::MapEnd, - ], - ); -} - -#[test] -fn test_flatten_struct_tag_content_enum() { - let change_request = FlattenStructTagContentEnumWrapper { - outer: 42, - data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::InsertInteger { - index: 0, - value: 42, - }), - }; - assert_de_tokens( - &change_request, - &[ - Token::Map { len: None }, - Token::Str("outer"), - Token::U32(42), - Token::Str("type"), - Token::Str("insert_integer"), - Token::Str("value"), - Token::Map { len: None }, - Token::Str("index"), - Token::U32(0), - Token::Str("value"), - Token::U32(42), - Token::MapEnd, - Token::MapEnd, - ], - ); - assert_ser_tokens( - &change_request, - &[ - Token::Map { len: None }, - Token::Str("outer"), - Token::U32(42), - Token::Str("type"), - Token::Str("insert_integer"), - Token::Str("value"), - Token::Struct { - len: 2, - name: "insert_integer", - }, - Token::Str("index"), - Token::U32(0), - Token::Str("value"), - Token::U32(42), - Token::StructEnd, - Token::MapEnd, - ], - ); -} - -#[test] -fn test_flatten_struct_tag_content_enum_newtype() { - let change_request = FlattenStructTagContentEnumWrapper { - outer: 42, - data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::NewtypeVariant( - FlattenStructTagContentEnumNewtypeVariant { value: 23 }, - )), - }; - assert_de_tokens( - &change_request, - &[ - Token::Map { len: None }, - Token::Str("outer"), - Token::U32(42), - Token::Str("type"), - Token::Str("newtype_variant"), - Token::Str("value"), - Token::Map { len: None }, - Token::Str("value"), - Token::U32(23), - Token::MapEnd, - Token::MapEnd, - ], - ); - assert_ser_tokens( - &change_request, - &[ - Token::Map { len: None }, - Token::Str("outer"), - Token::U32(42), - Token::Str("type"), - Token::Str("newtype_variant"), - Token::Str("value"), - Token::Struct { - len: 1, - name: "FlattenStructTagContentEnumNewtypeVariant", - }, - Token::Str("value"), - Token::U32(23), - Token::StructEnd, - Token::MapEnd, - ], - ); -} - #[test] fn test_unknown_field_in_flatten() { #[derive(Debug, PartialEq, Serialize, Deserialize)] @@ -2177,52 +1998,6 @@ fn test_flatten_enum_newtype() { ); } -#[test] -fn test_flatten_internally_tagged() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct S { - #[serde(flatten)] - x: X, - #[serde(flatten)] - y: Y, - } - - #[derive(Serialize, Deserialize, PartialEq, Debug)] - #[serde(tag = "typeX")] - enum X { - A { a: i32 }, - B { b: i32 }, - } - - #[derive(Serialize, Deserialize, PartialEq, Debug)] - #[serde(tag = "typeY")] - enum Y { - C { c: i32 }, - D { d: i32 }, - } - - let s = S { - x: X::B { b: 1 }, - y: Y::D { d: 2 }, - }; - - assert_tokens( - &s, - &[ - Token::Map { len: None }, - Token::Str("typeX"), - Token::Str("B"), - Token::Str("b"), - Token::I32(1), - Token::Str("typeY"), - Token::Str("D"), - Token::Str("d"), - Token::I32(2), - Token::MapEnd, - ], - ); -} - #[test] fn test_externally_tagged_enum_containing_flatten() { #[derive(Serialize, Deserialize, PartialEq, Debug)] @@ -2598,35 +2373,6 @@ fn test_partially_untagged_enum_desugared() { ); } -#[test] -fn test_flatten_untagged_enum() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct Outer { - #[serde(flatten)] - inner: Inner, - } - - #[derive(Serialize, Deserialize, PartialEq, Debug)] - #[serde(untagged)] - enum Inner { - Variant { a: i32 }, - } - - let data = Outer { - inner: Inner::Variant { a: 0 }, - }; - - assert_tokens( - &data, - &[ - Token::Map { len: None }, - Token::Str("a"), - Token::I32(0), - Token::MapEnd, - ], - ); -} - #[test] fn test_flatten_option() { #[derive(Serialize, Deserialize, PartialEq, Debug)] @@ -2783,48 +2529,6 @@ fn test_internally_tagged_unit_enum_with_unknown_fields() { ); } -#[test] -fn test_flattened_internally_tagged_unit_enum_with_unknown_fields() { - #[derive(Deserialize, PartialEq, Debug)] - struct S { - #[serde(flatten)] - x: X, - #[serde(flatten)] - y: Y, - } - - #[derive(Deserialize, PartialEq, Debug)] - #[serde(tag = "typeX")] - enum X { - A, - } - - #[derive(Deserialize, PartialEq, Debug)] - #[serde(tag = "typeY")] - enum Y { - B { c: u32 }, - } - - let s = S { - x: X::A, - y: Y::B { c: 0 }, - }; - - assert_de_tokens( - &s, - &[ - Token::Map { len: None }, - Token::Str("typeX"), - Token::Str("A"), - Token::Str("typeY"), - Token::Str("B"), - Token::Str("c"), - Token::I32(0), - Token::MapEnd, - ], - ); -} - #[test] fn test_flatten_any_after_flatten_struct() { #[derive(PartialEq, Debug)] @@ -3115,3 +2819,323 @@ fn test_expecting_message_identifier_enum() { r#"invalid type: map, expected something strange..."#, ); } + +mod flatten { + use super::*; + + mod enum_ { + use super::*; + + mod externally_tagged { + use super::*; + + #[derive(Debug, PartialEq, Serialize, Deserialize)] + struct FlattenStructEnumWrapper { + #[serde(flatten)] + data: FlattenStructEnum, + #[serde(flatten)] + extra: HashMap, + } + + #[derive(Debug, PartialEq, Serialize, Deserialize)] + #[serde(rename_all = "snake_case")] + enum FlattenStructEnum { + InsertInteger { index: u32, value: u32 }, + } + + #[test] + fn test_flatten_struct_enum() { + let mut extra = HashMap::new(); + extra.insert("extra_key".into(), "extra value".into()); + let change_request = FlattenStructEnumWrapper { + data: FlattenStructEnum::InsertInteger { + index: 0, + value: 42, + }, + extra, + }; + assert_de_tokens( + &change_request, + &[ + Token::Map { len: None }, + Token::Str("insert_integer"), + Token::Map { len: None }, + Token::Str("index"), + Token::U32(0), + Token::Str("value"), + Token::U32(42), + Token::MapEnd, + Token::Str("extra_key"), + Token::Str("extra value"), + Token::MapEnd, + ], + ); + assert_ser_tokens( + &change_request, + &[ + Token::Map { len: None }, + Token::Str("insert_integer"), + Token::Struct { + len: 2, + name: "insert_integer", + }, + Token::Str("index"), + Token::U32(0), + Token::Str("value"), + Token::U32(42), + Token::StructEnd, + Token::Str("extra_key"), + Token::Str("extra value"), + Token::MapEnd, + ], + ); + } + } + + mod adjacently_tagged { + use super::*; + + #[derive(Debug, PartialEq, Serialize, Deserialize)] + struct FlattenStructTagContentEnumWrapper { + outer: u32, + #[serde(flatten)] + data: FlattenStructTagContentEnumNewtype, + } + + #[derive(Debug, PartialEq, Serialize, Deserialize)] + struct FlattenStructTagContentEnumNewtype(pub FlattenStructTagContentEnum); + + #[derive(Debug, PartialEq, Serialize, Deserialize)] + #[serde(rename_all = "snake_case", tag = "type", content = "value")] + enum FlattenStructTagContentEnum { + InsertInteger { index: u32, value: u32 }, + NewtypeVariant(FlattenStructTagContentEnumNewtypeVariant), + } + + #[derive(Debug, PartialEq, Serialize, Deserialize)] + struct FlattenStructTagContentEnumNewtypeVariant { + value: u32, + } + + #[test] + fn test_flatten_struct_tag_content_enum() { + let change_request = FlattenStructTagContentEnumWrapper { + outer: 42, + data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::InsertInteger { + index: 0, + value: 42, + }), + }; + assert_de_tokens( + &change_request, + &[ + Token::Map { len: None }, + Token::Str("outer"), + Token::U32(42), + Token::Str("type"), + Token::Str("insert_integer"), + Token::Str("value"), + Token::Map { len: None }, + Token::Str("index"), + Token::U32(0), + Token::Str("value"), + Token::U32(42), + Token::MapEnd, + Token::MapEnd, + ], + ); + assert_ser_tokens( + &change_request, + &[ + Token::Map { len: None }, + Token::Str("outer"), + Token::U32(42), + Token::Str("type"), + Token::Str("insert_integer"), + Token::Str("value"), + Token::Struct { + len: 2, + name: "insert_integer", + }, + Token::Str("index"), + Token::U32(0), + Token::Str("value"), + Token::U32(42), + Token::StructEnd, + Token::MapEnd, + ], + ); + } + + #[test] + fn test_flatten_struct_tag_content_enum_newtype() { + let change_request = FlattenStructTagContentEnumWrapper { + outer: 42, + data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::NewtypeVariant( + FlattenStructTagContentEnumNewtypeVariant { value: 23 }, + )), + }; + assert_de_tokens( + &change_request, + &[ + Token::Map { len: None }, + Token::Str("outer"), + Token::U32(42), + Token::Str("type"), + Token::Str("newtype_variant"), + Token::Str("value"), + Token::Map { len: None }, + Token::Str("value"), + Token::U32(23), + Token::MapEnd, + Token::MapEnd, + ], + ); + assert_ser_tokens( + &change_request, + &[ + Token::Map { len: None }, + Token::Str("outer"), + Token::U32(42), + Token::Str("type"), + Token::Str("newtype_variant"), + Token::Str("value"), + Token::Struct { + len: 1, + name: "FlattenStructTagContentEnumNewtypeVariant", + }, + Token::Str("value"), + Token::U32(23), + Token::StructEnd, + Token::MapEnd, + ], + ); + } + } + + mod internally_tagged { + use super::*; + + #[test] + fn test_flatten_internally_tagged() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct S { + #[serde(flatten)] + x: X, + #[serde(flatten)] + y: Y, + } + + #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[serde(tag = "typeX")] + enum X { + A { a: i32 }, + B { b: i32 }, + } + + #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[serde(tag = "typeY")] + enum Y { + C { c: i32 }, + D { d: i32 }, + } + + let s = S { + x: X::B { b: 1 }, + y: Y::D { d: 2 }, + }; + + assert_tokens( + &s, + &[ + Token::Map { len: None }, + Token::Str("typeX"), + Token::Str("B"), + Token::Str("b"), + Token::I32(1), + Token::Str("typeY"), + Token::Str("D"), + Token::Str("d"), + Token::I32(2), + Token::MapEnd, + ], + ); + } + + #[test] + fn test_flattened_internally_tagged_unit_enum_with_unknown_fields() { + #[derive(Deserialize, PartialEq, Debug)] + struct S { + #[serde(flatten)] + x: X, + #[serde(flatten)] + y: Y, + } + + #[derive(Deserialize, PartialEq, Debug)] + #[serde(tag = "typeX")] + enum X { + A, + } + + #[derive(Deserialize, PartialEq, Debug)] + #[serde(tag = "typeY")] + enum Y { + B { c: u32 }, + } + + let s = S { + x: X::A, + y: Y::B { c: 0 }, + }; + + assert_de_tokens( + &s, + &[ + Token::Map { len: None }, + Token::Str("typeX"), + Token::Str("A"), + Token::Str("typeY"), + Token::Str("B"), + Token::Str("c"), + Token::I32(0), + Token::MapEnd, + ], + ); + } + } + + mod untagged { + use super::*; + + #[test] + fn test_flatten_untagged_enum() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Outer { + #[serde(flatten)] + inner: Inner, + } + + #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[serde(untagged)] + enum Inner { + Variant { a: i32 }, + } + + let data = Outer { + inner: Inner::Variant { a: 0 }, + }; + + assert_tokens( + &data, + &[ + Token::Map { len: None }, + Token::Str("a"), + Token::I32(0), + Token::MapEnd, + ], + ); + } + } + } +} From 52a7d40e6eef9c8d6571875b1651bc37b947ddac Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 12:48:27 +0500 Subject: [PATCH 02/10] Rename test types so their names reflects, what's tested --- test_suite/tests/test_annotations.rs | 89 ++++++++++++++-------------- 1 file changed, 43 insertions(+), 46 deletions(-) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index f8f87948..7cbd7eb8 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -2830,25 +2830,24 @@ mod flatten { use super::*; #[derive(Debug, PartialEq, Serialize, Deserialize)] - struct FlattenStructEnumWrapper { + struct Flatten { #[serde(flatten)] - data: FlattenStructEnum, + data: Enum, #[serde(flatten)] extra: HashMap, } #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(rename_all = "snake_case")] - enum FlattenStructEnum { - InsertInteger { index: u32, value: u32 }, + enum Enum { + Struct { index: u32, value: u32 }, } #[test] - fn test_flatten_struct_enum() { + fn struct_() { let mut extra = HashMap::new(); extra.insert("extra_key".into(), "extra value".into()); - let change_request = FlattenStructEnumWrapper { - data: FlattenStructEnum::InsertInteger { + let change_request = Flatten { + data: Enum::Struct { index: 0, value: 42, }, @@ -2858,7 +2857,7 @@ mod flatten { &change_request, &[ Token::Map { len: None }, - Token::Str("insert_integer"), + Token::Str("Struct"), Token::Map { len: None }, Token::Str("index"), Token::U32(0), @@ -2874,10 +2873,10 @@ mod flatten { &change_request, &[ Token::Map { len: None }, - Token::Str("insert_integer"), + Token::Str("Struct"), Token::Struct { len: 2, - name: "insert_integer", + name: "Struct", }, Token::Str("index"), Token::U32(0), @@ -2896,32 +2895,32 @@ mod flatten { use super::*; #[derive(Debug, PartialEq, Serialize, Deserialize)] - struct FlattenStructTagContentEnumWrapper { + struct Flatten { outer: u32, #[serde(flatten)] - data: FlattenStructTagContentEnumNewtype, + data: NewtypeWrapper, } #[derive(Debug, PartialEq, Serialize, Deserialize)] - struct FlattenStructTagContentEnumNewtype(pub FlattenStructTagContentEnum); + struct NewtypeWrapper(pub Enum); #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(rename_all = "snake_case", tag = "type", content = "value")] - enum FlattenStructTagContentEnum { - InsertInteger { index: u32, value: u32 }, - NewtypeVariant(FlattenStructTagContentEnumNewtypeVariant), + #[serde(tag = "type", content = "value")] + enum Enum { + Struct { index: u32, value: u32 }, + Newtype(NewtypeVariant), } #[derive(Debug, PartialEq, Serialize, Deserialize)] - struct FlattenStructTagContentEnumNewtypeVariant { + struct NewtypeVariant { value: u32, } #[test] - fn test_flatten_struct_tag_content_enum() { - let change_request = FlattenStructTagContentEnumWrapper { + fn struct_() { + let change_request = Flatten { outer: 42, - data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::InsertInteger { + data: NewtypeWrapper(Enum::Struct { index: 0, value: 42, }), @@ -2933,7 +2932,7 @@ mod flatten { Token::Str("outer"), Token::U32(42), Token::Str("type"), - Token::Str("insert_integer"), + Token::Str("Struct"), Token::Str("value"), Token::Map { len: None }, Token::Str("index"), @@ -2951,11 +2950,11 @@ mod flatten { Token::Str("outer"), Token::U32(42), Token::Str("type"), - Token::Str("insert_integer"), + Token::Str("Struct"), Token::Str("value"), Token::Struct { len: 2, - name: "insert_integer", + name: "Struct", }, Token::Str("index"), Token::U32(0), @@ -2968,12 +2967,10 @@ mod flatten { } #[test] - fn test_flatten_struct_tag_content_enum_newtype() { - let change_request = FlattenStructTagContentEnumWrapper { + fn newtype() { + let change_request = Flatten { outer: 42, - data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::NewtypeVariant( - FlattenStructTagContentEnumNewtypeVariant { value: 23 }, - )), + data: NewtypeWrapper(Enum::Newtype(NewtypeVariant { value: 23 })), }; assert_de_tokens( &change_request, @@ -2982,7 +2979,7 @@ mod flatten { Token::Str("outer"), Token::U32(42), Token::Str("type"), - Token::Str("newtype_variant"), + Token::Str("Newtype"), Token::Str("value"), Token::Map { len: None }, Token::Str("value"), @@ -2998,11 +2995,11 @@ mod flatten { Token::Str("outer"), Token::U32(42), Token::Str("type"), - Token::Str("newtype_variant"), + Token::Str("Newtype"), Token::Str("value"), Token::Struct { len: 1, - name: "FlattenStructTagContentEnumNewtypeVariant", + name: "NewtypeVariant", }, Token::Str("value"), Token::U32(23), @@ -3017,9 +3014,9 @@ mod flatten { use super::*; #[test] - fn test_flatten_internally_tagged() { + fn structs() { #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct S { + struct Flatten { #[serde(flatten)] x: X, #[serde(flatten)] @@ -3040,7 +3037,7 @@ mod flatten { D { d: i32 }, } - let s = S { + let s = Flatten { x: X::B { b: 1 }, y: Y::D { d: 2 }, }; @@ -3063,9 +3060,9 @@ mod flatten { } #[test] - fn test_flattened_internally_tagged_unit_enum_with_unknown_fields() { + fn unit_enum_with_unknown_fields() { #[derive(Deserialize, PartialEq, Debug)] - struct S { + struct Flatten { #[serde(flatten)] x: X, #[serde(flatten)] @@ -3084,7 +3081,7 @@ mod flatten { B { c: u32 }, } - let s = S { + let s = Flatten { x: X::A, y: Y::B { c: 0 }, }; @@ -3109,21 +3106,21 @@ mod flatten { use super::*; #[test] - fn test_flatten_untagged_enum() { + fn struct_() { #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct Outer { + struct Flatten { #[serde(flatten)] - inner: Inner, + data: Enum, } #[derive(Serialize, Deserialize, PartialEq, Debug)] #[serde(untagged)] - enum Inner { - Variant { a: i32 }, + enum Enum { + Struct { a: i32 }, } - let data = Outer { - inner: Inner::Variant { a: 0 }, + let data = Flatten { + data: Enum::Struct { a: 0 }, }; assert_tokens( From f7c5d93e6a334459d407641a8b0c8f1131963b18 Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 14:27:03 +0500 Subject: [PATCH 03/10] Pull up types from function into module, unify style --- test_suite/tests/test_annotations.rs | 64 +++++++++++++--------------- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index 7cbd7eb8..a75070a4 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -3015,7 +3015,7 @@ mod flatten { #[test] fn structs() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, Serialize, Deserialize)] struct Flatten { #[serde(flatten)] x: X, @@ -3023,27 +3023,25 @@ mod flatten { y: Y, } - #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(tag = "typeX")] enum X { A { a: i32 }, B { b: i32 }, } - #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(tag = "typeY")] enum Y { C { c: i32 }, D { d: i32 }, } - let s = Flatten { - x: X::B { b: 1 }, - y: Y::D { d: 2 }, - }; - assert_tokens( - &s, + &Flatten { + x: X::B { b: 1 }, + y: Y::D { d: 2 }, + }, &[ Token::Map { len: None }, Token::Str("typeX"), @@ -3061,7 +3059,7 @@ mod flatten { #[test] fn unit_enum_with_unknown_fields() { - #[derive(Deserialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, Deserialize)] struct Flatten { #[serde(flatten)] x: X, @@ -3069,25 +3067,23 @@ mod flatten { y: Y, } - #[derive(Deserialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, Deserialize)] #[serde(tag = "typeX")] enum X { A, } - #[derive(Deserialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, Deserialize)] #[serde(tag = "typeY")] enum Y { B { c: u32 }, } - let s = Flatten { - x: X::A, - y: Y::B { c: 0 }, - }; - assert_de_tokens( - &s, + &Flatten { + x: X::A, + y: Y::B { c: 0 }, + }, &[ Token::Map { len: None }, Token::Str("typeX"), @@ -3105,26 +3101,24 @@ mod flatten { mod untagged { use super::*; + #[derive(Debug, PartialEq, Serialize, Deserialize)] + struct Flatten { + #[serde(flatten)] + data: Enum, + } + + #[derive(Debug, PartialEq, Serialize, Deserialize)] + #[serde(untagged)] + enum Enum { + Struct { a: i32 }, + } + #[test] fn struct_() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct Flatten { - #[serde(flatten)] - data: Enum, - } - - #[derive(Serialize, Deserialize, PartialEq, Debug)] - #[serde(untagged)] - enum Enum { - Struct { a: i32 }, - } - - let data = Flatten { - data: Enum::Struct { a: 0 }, - }; - assert_tokens( - &data, + &Flatten { + data: Enum::Struct { a: 0 }, + }, &[ Token::Map { len: None }, Token::Str("a"), From ab21d4d017cf4826dc39b067a71dee0735b0d3df Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 12:53:41 +0500 Subject: [PATCH 04/10] Merge assert_de_tokens and assert_ser_tokens into assert_tokens --- test_suite/tests/test_annotations.rs | 95 +++++++--------------------- 1 file changed, 22 insertions(+), 73 deletions(-) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index a75070a4..d83a7872 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -2833,6 +2833,7 @@ mod flatten { struct Flatten { #[serde(flatten)] data: Enum, + #[serde(flatten)] extra: HashMap, } @@ -2846,31 +2847,14 @@ mod flatten { fn struct_() { let mut extra = HashMap::new(); extra.insert("extra_key".into(), "extra value".into()); - let change_request = Flatten { - data: Enum::Struct { - index: 0, - value: 42, + assert_tokens( + &Flatten { + data: Enum::Struct { + index: 0, + value: 42, + }, + extra, }, - extra, - }; - assert_de_tokens( - &change_request, - &[ - Token::Map { len: None }, - Token::Str("Struct"), - Token::Map { len: None }, - Token::Str("index"), - Token::U32(0), - Token::Str("value"), - Token::U32(42), - Token::MapEnd, - Token::Str("extra_key"), - Token::Str("extra value"), - Token::MapEnd, - ], - ); - assert_ser_tokens( - &change_request, &[ Token::Map { len: None }, Token::Str("Struct"), @@ -2897,6 +2881,7 @@ mod flatten { #[derive(Debug, PartialEq, Serialize, Deserialize)] struct Flatten { outer: u32, + #[serde(flatten)] data: NewtypeWrapper, } @@ -2918,33 +2903,14 @@ mod flatten { #[test] fn struct_() { - let change_request = Flatten { - outer: 42, - data: NewtypeWrapper(Enum::Struct { - index: 0, - value: 42, - }), - }; - assert_de_tokens( - &change_request, - &[ - Token::Map { len: None }, - Token::Str("outer"), - Token::U32(42), - Token::Str("type"), - Token::Str("Struct"), - Token::Str("value"), - Token::Map { len: None }, - Token::Str("index"), - Token::U32(0), - Token::Str("value"), - Token::U32(42), - Token::MapEnd, - Token::MapEnd, - ], - ); - assert_ser_tokens( - &change_request, + assert_tokens( + &Flatten { + outer: 42, + data: NewtypeWrapper(Enum::Struct { + index: 0, + value: 42, + }), + }, &[ Token::Map { len: None }, Token::Str("outer"), @@ -2968,28 +2934,11 @@ mod flatten { #[test] fn newtype() { - let change_request = Flatten { - outer: 42, - data: NewtypeWrapper(Enum::Newtype(NewtypeVariant { value: 23 })), - }; - assert_de_tokens( - &change_request, - &[ - Token::Map { len: None }, - Token::Str("outer"), - Token::U32(42), - Token::Str("type"), - Token::Str("Newtype"), - Token::Str("value"), - Token::Map { len: None }, - Token::Str("value"), - Token::U32(23), - Token::MapEnd, - Token::MapEnd, - ], - ); - assert_ser_tokens( - &change_request, + assert_tokens( + &Flatten { + outer: 42, + data: NewtypeWrapper(Enum::Newtype(NewtypeVariant { value: 23 })), + }, &[ Token::Map { len: None }, Token::Str("outer"), From f3d50e52093203e791b6ce9c2a1fefd2e727ae8f Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 12:56:04 +0500 Subject: [PATCH 05/10] Use FromIterator to fill HashMap --- test_suite/tests/test_annotations.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index d83a7872..f2e0b5e9 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -2828,6 +2828,7 @@ mod flatten { mod externally_tagged { use super::*; + use std::iter::FromIterator; #[derive(Debug, PartialEq, Serialize, Deserialize)] struct Flatten { @@ -2845,15 +2846,13 @@ mod flatten { #[test] fn struct_() { - let mut extra = HashMap::new(); - extra.insert("extra_key".into(), "extra value".into()); assert_tokens( &Flatten { data: Enum::Struct { index: 0, value: 42, }, - extra, + extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]), }, &[ Token::Map { len: None }, From 5b96cf1bde78eecbdbaa856fc175f1cc3da2e64a Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 12:59:12 +0500 Subject: [PATCH 06/10] Use traditional order for enum variants (Unit, Newtype, Tuple, Struct) and names for tag and content fields --- test_suite/tests/test_annotations.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index f2e0b5e9..f760085b 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -2856,7 +2856,7 @@ mod flatten { }, &[ Token::Map { len: None }, - Token::Str("Struct"), + Token::Str("Struct"), // variant Token::Struct { len: 2, name: "Struct", @@ -2889,10 +2889,10 @@ mod flatten { struct NewtypeWrapper(pub Enum); #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "type", content = "value")] + #[serde(tag = "tag", content = "content")] enum Enum { - Struct { index: u32, value: u32 }, Newtype(NewtypeVariant), + Struct { index: u32, value: u32 }, } #[derive(Debug, PartialEq, Serialize, Deserialize)] @@ -2914,9 +2914,9 @@ mod flatten { Token::Map { len: None }, Token::Str("outer"), Token::U32(42), - Token::Str("type"), + Token::Str("tag"), Token::Str("Struct"), - Token::Str("value"), + Token::Str("content"), Token::Struct { len: 2, name: "Struct", @@ -2942,9 +2942,9 @@ mod flatten { Token::Map { len: None }, Token::Str("outer"), Token::U32(42), - Token::Str("type"), + Token::Str("tag"), Token::Str("Newtype"), - Token::Str("value"), + Token::Str("content"), Token::Struct { len: 1, name: "NewtypeVariant", From 993966600e885654b157f4827294195f3428da2b Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 13:02:44 +0500 Subject: [PATCH 07/10] Implement tests for crate::private::de::content::VariantDeserializer failures (1): flatten::enum_::externally_tagged::tuple --- test_suite/tests/test_annotations.rs | 57 +++++++++++++++++++++++++++- test_suite/tests/test_macros.rs | 23 +++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index f760085b..2a3e3996 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -2841,11 +2841,66 @@ mod flatten { #[derive(Debug, PartialEq, Serialize, Deserialize)] enum Enum { + Tuple(u32, u32), Struct { index: u32, value: u32 }, } + /// Reaches crate::private::de::content::VariantDeserializer::tuple_variant + /// Content::Seq case + /// via FlatMapDeserializer::deserialize_enum #[test] - fn struct_() { + fn tuple() { + assert_tokens( + &Flatten { + data: Enum::Tuple(0, 42), + extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]), + }, + &[ + Token::Map { len: None }, + Token::Str("Tuple"), // variant + Token::Seq { len: Some(2) }, + Token::U32(0), + Token::U32(42), + Token::SeqEnd, + Token::Str("extra_key"), + Token::Str("extra value"), + Token::MapEnd, + ], + ); + } + + /// Reaches crate::private::de::content::VariantDeserializer::struct_variant + /// Content::Seq case + /// via FlatMapDeserializer::deserialize_enum + #[test] + fn struct_from_seq() { + assert_de_tokens( + &Flatten { + data: Enum::Struct { + index: 0, + value: 42, + }, + extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]), + }, + &[ + Token::Map { len: None }, + Token::Str("Struct"), // variant + Token::Seq { len: Some(2) }, + Token::U32(0), // index + Token::U32(42), // value + Token::SeqEnd, + Token::Str("extra_key"), + Token::Str("extra value"), + Token::MapEnd, + ], + ); + } + + /// Reaches crate::private::de::content::VariantDeserializer::struct_variant + /// Content::Map case + /// via FlatMapDeserializer::deserialize_enum + #[test] + fn struct_from_map() { assert_tokens( &Flatten { data: Enum::Struct { diff --git a/test_suite/tests/test_macros.rs b/test_suite/tests/test_macros.rs index 0594d8d4..7e700bd2 100644 --- a/test_suite/tests/test_macros.rs +++ b/test_suite/tests/test_macros.rs @@ -1430,6 +1430,9 @@ fn test_enum_in_internally_tagged_enum() { ], ); + // Reaches crate::private::de::content::VariantDeserializer::tuple_variant + // Content::Seq case + // via ContentDeserializer::deserialize_enum assert_tokens( &Outer::Inner(Inner::Tuple(1, 1)), &[ @@ -1448,6 +1451,9 @@ fn test_enum_in_internally_tagged_enum() { ], ); + // Reaches crate::private::de::content::VariantDeserializer::struct_variant + // Content::Map case + // via ContentDeserializer::deserialize_enum assert_tokens( &Outer::Inner(Inner::Struct { f: 1 }), &[ @@ -1465,6 +1471,23 @@ fn test_enum_in_internally_tagged_enum() { Token::MapEnd, ], ); + + // Reaches crate::private::de::content::VariantDeserializer::struct_variant + // Content::Seq case + // via ContentDeserializer::deserialize_enum + assert_de_tokens( + &Outer::Inner(Inner::Struct { f: 1 }), + &[ + Token::Map { len: Some(2) }, + Token::Str("type"), + Token::Str("Inner"), + Token::Str("Struct"), + Token::Seq { len: Some(1) }, + Token::U8(1), // f + Token::SeqEnd, + Token::MapEnd, + ], + ); } #[test] From 4f922e4e5b76b2bbeef6b9c8a8b4e55933a3f7b7 Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 12:23:33 +0500 Subject: [PATCH 08/10] Implement serialization of flattened tuple variants of externally tagged enums The Container struct struct Container { #[serde(flatten)] enum_field: Enum, } enum Enum { Tuple(u32, u32), } now can be serialized to JSON as { "enum_field": [1, 2] } Deserialization already works Fixes (1): flatten::enum_::externally_tagged::tuple --- serde/src/private/ser.rs | 53 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/serde/src/private/ser.rs b/serde/src/private/ser.rs index 4dd45eda..a73f259b 100644 --- a/serde/src/private/ser.rs +++ b/serde/src/private/ser.rs @@ -1025,7 +1025,7 @@ where type SerializeTupleStruct = Impossible; type SerializeMap = FlatMapSerializeMap<'a, M>; type SerializeStruct = FlatMapSerializeStruct<'a, M>; - type SerializeTupleVariant = Impossible; + type SerializeTupleVariant = FlatMapSerializeTupleVariantAsMapValue<'a, M>; type SerializeStructVariant = FlatMapSerializeStructVariantAsMapValue<'a, M>; fn serialize_bool(self, _: bool) -> Result { @@ -1157,10 +1157,11 @@ where self, _: &'static str, _: u32, - _: &'static str, + variant: &'static str, _: usize, ) -> Result { - Err(Self::bad_type(Unsupported::Enum)) + try!(self.0.serialize_key(variant)); + Ok(FlatMapSerializeTupleVariantAsMapValue::new(self.0)) } fn serialize_map(self, _: Option) -> Result { @@ -1259,6 +1260,52 @@ where } } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(feature = "std", feature = "alloc"))] +pub struct FlatMapSerializeTupleVariantAsMapValue<'a, M: 'a> { + map: &'a mut M, + fields: Vec, +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, M> FlatMapSerializeTupleVariantAsMapValue<'a, M> +where + M: SerializeMap + 'a, +{ + fn new(map: &'a mut M) -> Self { + FlatMapSerializeTupleVariantAsMapValue { + map: map, + fields: Vec::new(), + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, M> ser::SerializeTupleVariant for FlatMapSerializeTupleVariantAsMapValue<'a, M> +where + M: SerializeMap + 'a, +{ + type Ok = (); + type Error = M::Error; + + fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize, + { + let value = try!(value.serialize(ContentSerializer::::new())); + self.fields.push(value); + Ok(()) + } + + fn end(self) -> Result<(), Self::Error> { + try!(self.map.serialize_value(&Content::Seq(self.fields))); + Ok(()) + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + #[cfg(any(feature = "std", feature = "alloc"))] pub struct FlatMapSerializeStructVariantAsMapValue<'a, M: 'a> { map: &'a mut M, From 4513a9e6a75460d6277de2ea2f67fd70e000de54 Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 13:40:42 +0500 Subject: [PATCH 09/10] Move test_flatten_enum_newtype into new group of flatten tests - flatten::enum_::externally_tagged::newtype --- test_suite/tests/test_annotations.rs | 56 +++++++++++----------------- 1 file changed, 22 insertions(+), 34 deletions(-) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index 2a3e3996..068edc88 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -1964,40 +1964,6 @@ fn test_lifetime_propagation_for_flatten() { ); } -#[test] -fn test_flatten_enum_newtype() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct S { - #[serde(flatten)] - flat: E, - } - - #[derive(Serialize, Deserialize, PartialEq, Debug)] - enum E { - Q(HashMap), - } - - let e = E::Q({ - let mut map = HashMap::new(); - map.insert("k".to_owned(), "v".to_owned()); - map - }); - let s = S { flat: e }; - - assert_tokens( - &s, - &[ - Token::Map { len: None }, - Token::Str("Q"), - Token::Map { len: Some(1) }, - Token::Str("k"), - Token::Str("v"), - Token::MapEnd, - Token::MapEnd, - ], - ); -} - #[test] fn test_externally_tagged_enum_containing_flatten() { #[derive(Serialize, Deserialize, PartialEq, Debug)] @@ -2841,10 +2807,32 @@ mod flatten { #[derive(Debug, PartialEq, Serialize, Deserialize)] enum Enum { + Newtype(HashMap), Tuple(u32, u32), Struct { index: u32, value: u32 }, } + #[test] + fn newtype() { + assert_tokens( + &Flatten { + data: Enum::Newtype(HashMap::from_iter([("key".into(), "value".into())])), + extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]), + }, + &[ + Token::Map { len: None }, + Token::Str("Newtype"), // variant + Token::Map { len: Some(1) }, + Token::Str("key"), + Token::Str("value"), + Token::MapEnd, + Token::Str("extra_key"), + Token::Str("extra value"), + Token::MapEnd, + ], + ); + } + /// Reaches crate::private::de::content::VariantDeserializer::tuple_variant /// Content::Seq case /// via FlatMapDeserializer::deserialize_enum From 4e5e55bf1c1d2537af5622af9c904ed0d6e42b93 Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 9 May 2023 10:57:17 +0500 Subject: [PATCH 10/10] Remove custom implementations of SeqDeserializer and MapDeserializer for enums Those deserializers are used to deserialize tuple or struct variants from Content which is used by internally tagged enums and by flatten FlatMapDeserializer is reached in the following tests: flatten::enum_::externally_tagged::newtype flatten::enum_::externally_tagged::struct_from_map flatten::enum_::externally_tagged::struct_from_seq flatten::enum_::externally_tagged::tuple ContentDeserializer is reached in the following tests: test_enum_in_internally_tagged_enum test_internally_tagged_struct_variant_containing_unit_variant --- serde/src/private/de.rs | 176 +++++----------------------------------- 1 file changed, 19 insertions(+), 157 deletions(-) diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 3c0a187a..06b02489 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -207,6 +207,7 @@ mod content { use __private::size_hint; use actually_private; + use de::value::{MapDeserializer, SeqDeserializer}; use de::{ self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny, MapAccess, SeqAccess, Unexpected, Visitor, @@ -299,6 +300,17 @@ mod content { } } + impl<'de, E> de::IntoDeserializer<'de, E> for Content<'de> + where + E: de::Error, + { + type Deserializer = ContentDeserializer<'de, E>; + + fn into_deserializer(self) -> Self::Deserializer { + ContentDeserializer::new(self) + } + } + struct ContentVisitor<'de> { value: PhantomData>, } @@ -1074,7 +1086,7 @@ mod content { E: de::Error, { let seq = content.into_iter().map(ContentDeserializer::new); - let mut seq_visitor = de::value::SeqDeserializer::new(seq); + let mut seq_visitor = SeqDeserializer::new(seq); let value = try!(visitor.visit_seq(&mut seq_visitor)); try!(seq_visitor.end()); Ok(value) @@ -1091,7 +1103,7 @@ mod content { let map = content .into_iter() .map(|(k, v)| (ContentDeserializer::new(k), ContentDeserializer::new(v))); - let mut map_visitor = de::value::MapDeserializer::new(map); + let mut map_visitor = MapDeserializer::new(map); let value = try!(visitor.visit_map(&mut map_visitor)); try!(map_visitor.end()); Ok(value) @@ -1569,7 +1581,7 @@ mod content { { match self.value { Some(Content::Seq(v)) => { - de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor) + de::Deserializer::deserialize_any(SeqDeserializer::new(v.into_iter()), visitor) } Some(other) => Err(de::Error::invalid_type( other.unexpected(), @@ -1592,10 +1604,10 @@ mod content { { match self.value { Some(Content::Map(v)) => { - de::Deserializer::deserialize_any(MapDeserializer::new(v), visitor) + de::Deserializer::deserialize_any(MapDeserializer::new(v.into_iter()), visitor) } Some(Content::Seq(v)) => { - de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor) + de::Deserializer::deserialize_any(SeqDeserializer::new(v.into_iter()), visitor) } Some(other) => Err(de::Error::invalid_type( other.unexpected(), @@ -1609,156 +1621,6 @@ mod content { } } - struct SeqDeserializer<'de, E> - where - E: de::Error, - { - iter: > as IntoIterator>::IntoIter, - err: PhantomData, - } - - impl<'de, E> SeqDeserializer<'de, E> - where - E: de::Error, - { - fn new(vec: Vec>) -> Self { - SeqDeserializer { - iter: vec.into_iter(), - err: PhantomData, - } - } - } - - impl<'de, E> de::Deserializer<'de> for SeqDeserializer<'de, E> - where - E: de::Error, - { - type Error = E; - - #[inline] - fn deserialize_any(mut self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - let len = self.iter.len(); - if len == 0 { - visitor.visit_unit() - } else { - let ret = try!(visitor.visit_seq(&mut self)); - let remaining = self.iter.len(); - if remaining == 0 { - Ok(ret) - } else { - Err(de::Error::invalid_length(len, &"fewer elements in array")) - } - } - } - - forward_to_deserialize_any! { - bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string - bytes byte_buf option unit unit_struct newtype_struct seq tuple - tuple_struct map struct enum identifier ignored_any - } - } - - impl<'de, E> de::SeqAccess<'de> for SeqDeserializer<'de, E> - where - E: de::Error, - { - type Error = E; - - fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> - where - T: de::DeserializeSeed<'de>, - { - match self.iter.next() { - Some(value) => seed.deserialize(ContentDeserializer::new(value)).map(Some), - None => Ok(None), - } - } - - fn size_hint(&self) -> Option { - size_hint::from_bounds(&self.iter) - } - } - - struct MapDeserializer<'de, E> - where - E: de::Error, - { - iter: , Content<'de>)> as IntoIterator>::IntoIter, - value: Option>, - err: PhantomData, - } - - impl<'de, E> MapDeserializer<'de, E> - where - E: de::Error, - { - fn new(map: Vec<(Content<'de>, Content<'de>)>) -> Self { - MapDeserializer { - iter: map.into_iter(), - value: None, - err: PhantomData, - } - } - } - - impl<'de, E> de::MapAccess<'de> for MapDeserializer<'de, E> - where - E: de::Error, - { - type Error = E; - - fn next_key_seed(&mut self, seed: T) -> Result, Self::Error> - where - T: de::DeserializeSeed<'de>, - { - match self.iter.next() { - Some((key, value)) => { - self.value = Some(value); - seed.deserialize(ContentDeserializer::new(key)).map(Some) - } - None => Ok(None), - } - } - - fn next_value_seed(&mut self, seed: T) -> Result - where - T: de::DeserializeSeed<'de>, - { - match self.value.take() { - Some(value) => seed.deserialize(ContentDeserializer::new(value)), - None => Err(de::Error::custom("value is missing")), - } - } - - fn size_hint(&self) -> Option { - size_hint::from_bounds(&self.iter) - } - } - - impl<'de, E> de::Deserializer<'de> for MapDeserializer<'de, E> - where - E: de::Error, - { - type Error = E; - - #[inline] - fn deserialize_any(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - visitor.visit_map(self) - } - - forward_to_deserialize_any! { - bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string - bytes byte_buf option unit unit_struct newtype_struct seq tuple - tuple_struct map struct enum identifier ignored_any - } - } - /// Not public API. pub struct ContentRefDeserializer<'a, 'de: 'a, E> { content: &'a Content<'de>, @@ -1820,7 +1682,7 @@ mod content { E: de::Error, { let seq = content.iter().map(ContentRefDeserializer::new); - let mut seq_visitor = de::value::SeqDeserializer::new(seq); + let mut seq_visitor = SeqDeserializer::new(seq); let value = try!(visitor.visit_seq(&mut seq_visitor)); try!(seq_visitor.end()); Ok(value) @@ -1840,7 +1702,7 @@ mod content { ContentRefDeserializer::new(v), ) }); - let mut map_visitor = de::value::MapDeserializer::new(map); + let mut map_visitor = MapDeserializer::new(map); let value = try!(visitor.visit_map(&mut map_visitor)); try!(map_visitor.end()); Ok(value)