From aa0654332d26ea3d217eabc78ce6956735999bb0 Mon Sep 17 00:00:00 2001 From: Mingun Date: Sat, 22 Apr 2023 20:36:41 +0500 Subject: [PATCH 01/22] Convert test_internally_tagged_enum into module (review this commit with "ignore whitespace changes" option on) --- test_suite/tests/test_macros.rs | 229 +++++++++++++++++--------------- 1 file changed, 124 insertions(+), 105 deletions(-) diff --git a/test_suite/tests/test_macros.rs b/test_suite/tests/test_macros.rs index 7bd7a94e..4291841a 100644 --- a/test_suite/tests/test_macros.rs +++ b/test_suite/tests/test_macros.rs @@ -679,8 +679,9 @@ fn test_untagged_enum() { ); } -#[test] -fn test_internally_tagged_enum() { +mod internally_tagged_enum { + use super::*; + #[derive(Debug, PartialEq, Serialize, Deserialize)] struct Newtype(BTreeMap); @@ -699,119 +700,137 @@ fn test_internally_tagged_enum() { E(Struct), } - assert_tokens( - &InternallyTagged::A { a: 1 }, - &[ - Token::Struct { - name: "InternallyTagged", - len: 2, - }, - Token::Str("type"), - Token::Str("A"), - Token::Str("a"), - Token::U8(1), - Token::StructEnd, - ], - ); + #[test] + fn struct_() { + assert_tokens( + &InternallyTagged::A { a: 1 }, + &[ + Token::Struct { + name: "InternallyTagged", + len: 2, + }, + Token::Str("type"), + Token::Str("A"), + Token::Str("a"), + Token::U8(1), + Token::StructEnd, + ], + ); - assert_de_tokens( - &InternallyTagged::A { a: 1 }, - &[ - Token::Seq { len: Some(2) }, - Token::Str("A"), - Token::U8(1), - Token::SeqEnd, - ], - ); + assert_de_tokens( + &InternallyTagged::A { a: 1 }, + &[ + Token::Seq { len: Some(2) }, + Token::Str("A"), + Token::U8(1), + Token::SeqEnd, + ], + ); + } - assert_tokens( - &InternallyTagged::B, - &[ - Token::Struct { - name: "InternallyTagged", - len: 1, - }, - Token::Str("type"), - Token::Str("B"), - Token::StructEnd, - ], - ); + #[test] + fn unit() { + assert_tokens( + &InternallyTagged::B, + &[ + Token::Struct { + name: "InternallyTagged", + len: 1, + }, + Token::Str("type"), + Token::Str("B"), + Token::StructEnd, + ], + ); - assert_de_tokens( - &InternallyTagged::B, - &[Token::Seq { len: Some(1) }, Token::Str("B"), Token::SeqEnd], - ); + assert_de_tokens( + &InternallyTagged::B, + &[Token::Seq { len: Some(1) }, Token::Str("B"), Token::SeqEnd], + ); + } - assert_tokens( - &InternallyTagged::C(BTreeMap::new()), - &[ - Token::Map { len: Some(1) }, - Token::Str("type"), - Token::Str("C"), - Token::MapEnd, - ], - ); + #[test] + fn newtype_map() { + assert_tokens( + &InternallyTagged::C(BTreeMap::new()), + &[ + Token::Map { len: Some(1) }, + Token::Str("type"), + Token::Str("C"), + Token::MapEnd, + ], + ); - assert_de_tokens_error::( - &[ - Token::Seq { len: Some(2) }, - Token::Str("C"), - Token::Map { len: Some(0) }, - Token::MapEnd, - Token::SeqEnd, - ], - "invalid type: sequence, expected a map", - ); + assert_de_tokens_error::( + &[ + Token::Seq { len: Some(2) }, + Token::Str("C"), + Token::Map { len: Some(0) }, + Token::MapEnd, + Token::SeqEnd, + ], + "invalid type: sequence, expected a map", + ); + } - assert_tokens( - &InternallyTagged::D(Newtype(BTreeMap::new())), - &[ - Token::Map { len: Some(1) }, - Token::Str("type"), - Token::Str("D"), - Token::MapEnd, - ], - ); + #[test] + fn newtype_newtype() { + assert_tokens( + &InternallyTagged::D(Newtype(BTreeMap::new())), + &[ + Token::Map { len: Some(1) }, + Token::Str("type"), + Token::Str("D"), + Token::MapEnd, + ], + ); + } - assert_tokens( - &InternallyTagged::E(Struct { f: 6 }), - &[ - Token::Struct { - name: "Struct", - len: 2, - }, - Token::Str("type"), - Token::Str("E"), - Token::Str("f"), - Token::U8(6), - Token::StructEnd, - ], - ); + #[test] + fn newtype_struct() { + assert_tokens( + &InternallyTagged::E(Struct { f: 6 }), + &[ + Token::Struct { + name: "Struct", + len: 2, + }, + Token::Str("type"), + Token::Str("E"), + Token::Str("f"), + Token::U8(6), + Token::StructEnd, + ], + ); - assert_de_tokens( - &InternallyTagged::E(Struct { f: 6 }), - &[ - Token::Seq { len: Some(2) }, - Token::Str("E"), - Token::U8(6), - Token::SeqEnd, - ], - ); + assert_de_tokens( + &InternallyTagged::E(Struct { f: 6 }), + &[ + Token::Seq { len: Some(2) }, + Token::Str("E"), + Token::U8(6), + Token::SeqEnd, + ], + ); + } - assert_de_tokens_error::( - &[Token::Map { len: Some(0) }, Token::MapEnd], - "missing field `type`", - ); + #[test] + fn wrong_tag() { + assert_de_tokens_error::( + &[Token::Map { len: Some(0) }, Token::MapEnd], + "missing field `type`", + ); - assert_de_tokens_error::( - &[ - Token::Map { len: Some(1) }, - Token::Str("type"), - Token::Str("Z"), - Token::MapEnd, - ], - "unknown variant `Z`, expected one of `A`, `B`, `C`, `D`, `E`", - ); + assert_de_tokens_error::( + &[ + Token::Map { len: Some(1) }, + Token::Str("type"), + Token::Str("Z"), + Token::MapEnd, + ], + "unknown variant `Z`, expected one of `A`, `B`, `C`, `D`, `E`", + ); + } } #[test] From 99f905403b83013d998855224c4235007cbb96af Mon Sep 17 00:00:00 2001 From: Mingun Date: Thu, 27 Jul 2023 23:42:58 +0500 Subject: [PATCH 02/22] Move all internally tagged enum tests of `test_macros` into a dedicated module Moved: - test_internally_tagged_enum_with_untagged_variant => untagged_variant - test_internally_tagged_bytes => string_and_bytes mod - test_internally_tagged_struct_variant_containing_unit_variant => struct_variant_containing_unit_variant - test_internally_tagged_borrow => borrow - test_enum_in_internally_tagged_enum => newtype_variant_containing_externally_tagged_enum - test_internally_tagged_newtype_variant_containing_unit_struct => newtype_variant_containing_unit_struct (review this commit with "ignore whitespace changes" option on) --- test_suite/tests/test_macros.rs | 942 ++++++++++++++++---------------- 1 file changed, 479 insertions(+), 463 deletions(-) diff --git a/test_suite/tests/test_macros.rs b/test_suite/tests/test_macros.rs index 4291841a..84f2f444 100644 --- a/test_suite/tests/test_macros.rs +++ b/test_suite/tests/test_macros.rs @@ -831,350 +831,510 @@ mod internally_tagged_enum { "unknown variant `Z`, expected one of `A`, `B`, `C`, `D`, `E`", ); } -} -#[test] -fn test_internally_tagged_enum_with_untagged_variant() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "kind")] - enum InternallyTagged { - Tagged { - a: u8, - }, - #[serde(untagged)] - Untagged { - kind: String, - b: u8, - }, + #[test] + fn untagged_variant() { + #[derive(Debug, PartialEq, Serialize, Deserialize)] + #[serde(tag = "kind")] + enum InternallyTagged { + Tagged { + a: u8, + }, + #[serde(untagged)] + Untagged { + kind: String, + b: u8, + }, + } + + assert_de_tokens( + &InternallyTagged::Tagged { a: 1 }, + &[ + Token::Map { len: Some(2) }, + Token::Str("kind"), + Token::Str("Tagged"), + Token::Str("a"), + Token::U8(1), + Token::MapEnd, + ], + ); + + assert_tokens( + &InternallyTagged::Tagged { a: 1 }, + &[ + Token::Struct { + name: "InternallyTagged", + len: 2, + }, + Token::Str("kind"), + Token::Str("Tagged"), + Token::Str("a"), + Token::U8(1), + Token::StructEnd, + ], + ); + + assert_de_tokens( + &InternallyTagged::Untagged { + kind: "Foo".to_owned(), + b: 2, + }, + &[ + Token::Map { len: Some(2) }, + Token::Str("kind"), + Token::Str("Foo"), + Token::Str("b"), + Token::U8(2), + Token::MapEnd, + ], + ); + + assert_tokens( + &InternallyTagged::Untagged { + kind: "Foo".to_owned(), + b: 2, + }, + &[ + Token::Struct { + name: "InternallyTagged", + len: 2, + }, + Token::Str("kind"), + Token::Str("Foo"), + Token::Str("b"), + Token::U8(2), + Token::StructEnd, + ], + ); + + assert_tokens( + &InternallyTagged::Untagged { + kind: "Tagged".to_owned(), + b: 2, + }, + &[ + Token::Struct { + name: "InternallyTagged", + len: 2, + }, + Token::Str("kind"), + Token::Str("Tagged"), + Token::Str("b"), + Token::U8(2), + Token::StructEnd, + ], + ); } - assert_de_tokens( - &InternallyTagged::Tagged { a: 1 }, - &[ - Token::Map { len: Some(2) }, - Token::Str("kind"), - Token::Str("Tagged"), - Token::Str("a"), - Token::U8(1), - Token::MapEnd, - ], - ); + mod string_and_bytes { + use super::*; - assert_tokens( - &InternallyTagged::Tagged { a: 1 }, - &[ - Token::Struct { - name: "InternallyTagged", - len: 2, + #[derive(Debug, PartialEq, Deserialize)] + #[serde(tag = "type")] + enum InternallyTagged { + String { + string: String, }, - Token::Str("kind"), - Token::Str("Tagged"), - Token::Str("a"), - Token::U8(1), - Token::StructEnd, - ], - ); - - assert_de_tokens( - &InternallyTagged::Untagged { - kind: "Foo".to_owned(), - b: 2, - }, - &[ - Token::Map { len: Some(2) }, - Token::Str("kind"), - Token::Str("Foo"), - Token::Str("b"), - Token::U8(2), - Token::MapEnd, - ], - ); - - assert_tokens( - &InternallyTagged::Untagged { - kind: "Foo".to_owned(), - b: 2, - }, - &[ - Token::Struct { - name: "InternallyTagged", - len: 2, + Bytes { + #[serde(with = "bytes")] + bytes: Vec, }, - Token::Str("kind"), - Token::Str("Foo"), - Token::Str("b"), - Token::U8(2), - Token::StructEnd, - ], - ); + } - assert_tokens( - &InternallyTagged::Untagged { - kind: "Tagged".to_owned(), - b: 2, - }, - &[ - Token::Struct { - name: "InternallyTagged", - len: 2, - }, - Token::Str("kind"), - Token::Str("Tagged"), - Token::Str("b"), - Token::U8(2), - Token::StructEnd, - ], - ); -} + #[test] + fn string_from_string() { + assert_de_tokens( + &InternallyTagged::String { + string: "\0".to_owned(), + }, + &[ + Token::Struct { + name: "String", + len: 2, + }, + Token::Str("type"), + Token::Str("String"), + Token::Str("string"), + Token::Str("\0"), + Token::StructEnd, + ], + ); -#[test] -fn test_internally_tagged_bytes() { - #[derive(Debug, PartialEq, Deserialize)] - #[serde(tag = "type")] - enum InternallyTagged { - String { - string: String, - }, - Bytes { - #[serde(with = "bytes")] - bytes: Vec, - }, + assert_de_tokens( + &InternallyTagged::String { + string: "\0".to_owned(), + }, + &[ + Token::Struct { + name: "String", + len: 2, + }, + Token::Str("type"), + Token::Str("String"), + Token::Str("string"), + Token::String("\0"), + Token::StructEnd, + ], + ); + } + + #[test] + fn string_from_bytes() { + assert_de_tokens( + &InternallyTagged::String { + string: "\0".to_owned(), + }, + &[ + Token::Struct { + name: "String", + len: 2, + }, + Token::Str("type"), + Token::Str("String"), + Token::Str("string"), + Token::Bytes(b"\0"), + Token::StructEnd, + ], + ); + + assert_de_tokens( + &InternallyTagged::String { + string: "\0".to_owned(), + }, + &[ + Token::Struct { + name: "String", + len: 2, + }, + Token::Str("type"), + Token::Str("String"), + Token::Str("string"), + Token::ByteBuf(b"\0"), + Token::StructEnd, + ], + ); + } + + #[test] + fn bytes_from_string() { + assert_de_tokens( + &InternallyTagged::Bytes { bytes: vec![0] }, + &[ + Token::Struct { + name: "Bytes", + len: 2, + }, + Token::Str("type"), + Token::Str("Bytes"), + Token::Str("bytes"), + Token::Str("\0"), + Token::StructEnd, + ], + ); + + assert_de_tokens( + &InternallyTagged::Bytes { bytes: vec![0] }, + &[ + Token::Struct { + name: "Bytes", + len: 2, + }, + Token::Str("type"), + Token::Str("Bytes"), + Token::Str("bytes"), + Token::String("\0"), + Token::StructEnd, + ], + ); + } + + #[test] + fn bytes_from_bytes() { + assert_de_tokens( + &InternallyTagged::Bytes { bytes: vec![0] }, + &[ + Token::Struct { + name: "Bytes", + len: 2, + }, + Token::Str("type"), + Token::Str("Bytes"), + Token::Str("bytes"), + Token::Bytes(b"\0"), + Token::StructEnd, + ], + ); + + assert_de_tokens( + &InternallyTagged::Bytes { bytes: vec![0] }, + &[ + Token::Struct { + name: "Bytes", + len: 2, + }, + Token::Str("type"), + Token::Str("Bytes"), + Token::Str("bytes"), + Token::ByteBuf(b"\0"), + Token::StructEnd, + ], + ); + } + + #[test] + fn bytes_from_seq() { + assert_de_tokens( + &InternallyTagged::Bytes { bytes: vec![0] }, + &[ + Token::Struct { + name: "Bytes", + len: 2, + }, + Token::Str("type"), + Token::Str("Bytes"), + Token::Str("bytes"), + Token::Seq { len: Some(1) }, + Token::U8(0), + Token::SeqEnd, + Token::StructEnd, + ], + ); + } } - assert_de_tokens( - &InternallyTagged::String { - string: "\0".to_owned(), - }, - &[ - Token::Struct { - name: "String", - len: 2, - }, - Token::Str("type"), - Token::Str("String"), - Token::Str("string"), - Token::Str("\0"), - Token::StructEnd, - ], - ); + #[test] + fn struct_variant_containing_unit_variant() { + #[derive(Debug, PartialEq, Serialize, Deserialize)] + pub enum Level { + Info, + } - assert_de_tokens( - &InternallyTagged::String { - string: "\0".to_owned(), - }, - &[ - Token::Struct { - name: "String", - len: 2, - }, - Token::Str("type"), - Token::Str("String"), - Token::Str("string"), - Token::String("\0"), - Token::StructEnd, - ], - ); + #[derive(Debug, PartialEq, Serialize, Deserialize)] + #[serde(tag = "action")] + pub enum Message { + Log { level: Level }, + } - assert_de_tokens( - &InternallyTagged::String { - string: "\0".to_owned(), - }, - &[ - Token::Struct { - name: "String", - len: 2, - }, - Token::Str("type"), - Token::Str("String"), - Token::Str("string"), - Token::Bytes(b"\0"), - Token::StructEnd, - ], - ); + assert_de_tokens( + &Level::Info, + &[ + Token::Enum { name: "Level" }, + Token::BorrowedStr("Info"), + Token::Unit, + ], + ); - assert_de_tokens( - &InternallyTagged::String { - string: "\0".to_owned(), - }, - &[ - Token::Struct { - name: "String", - len: 2, - }, - Token::Str("type"), - Token::Str("String"), - Token::Str("string"), - Token::ByteBuf(b"\0"), - Token::StructEnd, - ], - ); + assert_de_tokens( + &Message::Log { level: Level::Info }, + &[ + Token::Struct { + name: "Message", + len: 2, + }, + Token::Str("action"), + Token::Str("Log"), + Token::Str("level"), + Token::Enum { name: "Level" }, + Token::BorrowedStr("Info"), + Token::Unit, + Token::StructEnd, + ], + ); - assert_de_tokens( - &InternallyTagged::Bytes { bytes: vec![0] }, - &[ - Token::Struct { - name: "Bytes", - len: 2, - }, - Token::Str("type"), - Token::Str("Bytes"), - Token::Str("bytes"), - Token::Str("\0"), - Token::StructEnd, - ], - ); + assert_de_tokens( + &Message::Log { level: Level::Info }, + &[ + Token::Map { len: Some(2) }, + Token::Str("action"), + Token::Str("Log"), + Token::Str("level"), + Token::Enum { name: "Level" }, + Token::BorrowedStr("Info"), + Token::Unit, + Token::MapEnd, + ], + ); - assert_de_tokens( - &InternallyTagged::Bytes { bytes: vec![0] }, - &[ - Token::Struct { - name: "Bytes", - len: 2, - }, - Token::Str("type"), - Token::Str("Bytes"), - Token::Str("bytes"), - Token::String("\0"), - Token::StructEnd, - ], - ); - - assert_de_tokens( - &InternallyTagged::Bytes { bytes: vec![0] }, - &[ - Token::Struct { - name: "Bytes", - len: 2, - }, - Token::Str("type"), - Token::Str("Bytes"), - Token::Str("bytes"), - Token::Bytes(b"\0"), - Token::StructEnd, - ], - ); - - assert_de_tokens( - &InternallyTagged::Bytes { bytes: vec![0] }, - &[ - Token::Struct { - name: "Bytes", - len: 2, - }, - Token::Str("type"), - Token::Str("Bytes"), - Token::Str("bytes"), - Token::ByteBuf(b"\0"), - Token::StructEnd, - ], - ); - - assert_de_tokens( - &InternallyTagged::Bytes { bytes: vec![0] }, - &[ - Token::Struct { - name: "Bytes", - len: 2, - }, - Token::Str("type"), - Token::Str("Bytes"), - Token::Str("bytes"), - Token::Seq { len: Some(1) }, - Token::U8(0), - Token::SeqEnd, - Token::StructEnd, - ], - ); -} - -#[test] -fn test_internally_tagged_struct_variant_containing_unit_variant() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - pub enum Level { - Info, + assert_de_tokens( + &Message::Log { level: Level::Info }, + &[ + Token::Seq { len: Some(2) }, + Token::Str("Log"), + Token::Enum { name: "Level" }, + Token::BorrowedStr("Info"), + Token::Unit, + Token::SeqEnd, + ], + ); } - #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "action")] - pub enum Message { - Log { level: Level }, + #[test] + fn borrow() { + #[derive(Debug, PartialEq, Serialize, Deserialize)] + #[serde(tag = "type")] + enum Input<'a> { + Package { name: &'a str }, + } + + assert_tokens( + &Input::Package { name: "borrowed" }, + &[ + Token::Struct { + name: "Input", + len: 2, + }, + Token::BorrowedStr("type"), + Token::BorrowedStr("Package"), + Token::BorrowedStr("name"), + Token::BorrowedStr("borrowed"), + Token::StructEnd, + ], + ); } - assert_de_tokens( - &Level::Info, - &[ - Token::Enum { name: "Level" }, - Token::BorrowedStr("Info"), - Token::Unit, - ], - ); + #[test] + fn newtype_variant_containing_externally_tagged_enum() { + #[derive(Debug, PartialEq, Serialize, Deserialize)] + #[serde(tag = "type")] + enum Outer { + Inner(Inner), + } - assert_de_tokens( - &Message::Log { level: Level::Info }, - &[ - Token::Struct { - name: "Message", - len: 2, - }, - Token::Str("action"), - Token::Str("Log"), - Token::Str("level"), - Token::Enum { name: "Level" }, - Token::BorrowedStr("Info"), - Token::Unit, - Token::StructEnd, - ], - ); + #[derive(Debug, PartialEq, Serialize, Deserialize)] + enum Inner { + Unit, + Newtype(u8), + Tuple(u8, u8), + Struct { f: u8 }, + } - assert_de_tokens( - &Message::Log { level: Level::Info }, - &[ - Token::Map { len: Some(2) }, - Token::Str("action"), - Token::Str("Log"), - Token::Str("level"), - Token::Enum { name: "Level" }, - Token::BorrowedStr("Info"), - Token::Unit, - Token::MapEnd, - ], - ); + assert_tokens( + &Outer::Inner(Inner::Unit), + &[ + Token::Map { len: Some(2) }, + Token::Str("type"), + Token::Str("Inner"), + Token::Str("Unit"), + Token::Unit, + Token::MapEnd, + ], + ); - assert_de_tokens( - &Message::Log { level: Level::Info }, - &[ - Token::Seq { len: Some(2) }, - Token::Str("Log"), - Token::Enum { name: "Level" }, - Token::BorrowedStr("Info"), - Token::Unit, - Token::SeqEnd, - ], - ); -} + assert_tokens( + &Outer::Inner(Inner::Newtype(1)), + &[ + Token::Map { len: Some(2) }, + Token::Str("type"), + Token::Str("Inner"), + Token::Str("Newtype"), + Token::U8(1), + Token::MapEnd, + ], + ); -#[test] -fn test_internally_tagged_borrow() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "type")] - pub enum Input<'a> { - Package { name: &'a str }, + // Reaches crate::private::de::content::VariantDeserializer::tuple_variant + // Content::Seq case + // via ContentDeserializer::deserialize_enum + assert_tokens( + &Outer::Inner(Inner::Tuple(1, 1)), + &[ + Token::Map { len: Some(2) }, + Token::Str("type"), + Token::Str("Inner"), + Token::Str("Tuple"), + Token::TupleStruct { + name: "Tuple", + len: 2, + }, + Token::U8(1), + Token::U8(1), + Token::TupleStructEnd, + Token::MapEnd, + ], + ); + + // Reaches crate::private::de::content::VariantDeserializer::struct_variant + // Content::Map case + // via ContentDeserializer::deserialize_enum + assert_tokens( + &Outer::Inner(Inner::Struct { f: 1 }), + &[ + Token::Map { len: Some(2) }, + Token::Str("type"), + Token::Str("Inner"), + Token::Str("Struct"), + Token::Struct { + name: "Struct", + len: 1, + }, + Token::Str("f"), + Token::U8(1), + Token::StructEnd, + 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, + ], + ); } - assert_tokens( - &Input::Package { name: "borrowed" }, - &[ - Token::Struct { - name: "Input", - len: 2, - }, - Token::BorrowedStr("type"), - Token::BorrowedStr("Package"), - Token::BorrowedStr("name"), - Token::BorrowedStr("borrowed"), - Token::StructEnd, - ], - ); + #[test] + fn newtype_variant_containing_unit_struct() { + #[derive(Debug, PartialEq, Serialize, Deserialize)] + struct Info; + + #[derive(Debug, PartialEq, Serialize, Deserialize)] + #[serde(tag = "topic")] + enum Message { + Info(Info), + } + + assert_tokens( + &Message::Info(Info), + &[ + Token::Map { len: Some(1) }, + Token::Str("topic"), + Token::Str("Info"), + Token::MapEnd, + ], + ); + + assert_de_tokens( + &Message::Info(Info), + &[ + Token::Struct { + name: "Message", + len: 1, + }, + Token::Str("topic"), + Token::Str("Info"), + Token::StructEnd, + ], + ); + + assert_de_tokens( + &Message::Info(Info), + &[ + Token::Seq { len: Some(1) }, + Token::Str("Info"), + Token::SeqEnd, + ], + ); + } } #[test] @@ -1571,106 +1731,6 @@ fn test_adjacently_tagged_enum_deny_unknown_fields() { ); } -#[test] -fn test_enum_in_internally_tagged_enum() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "type")] - enum Outer { - Inner(Inner), - } - - #[derive(Debug, PartialEq, Serialize, Deserialize)] - enum Inner { - Unit, - Newtype(u8), - Tuple(u8, u8), - Struct { f: u8 }, - } - - assert_tokens( - &Outer::Inner(Inner::Unit), - &[ - Token::Map { len: Some(2) }, - Token::Str("type"), - Token::Str("Inner"), - Token::Str("Unit"), - Token::Unit, - Token::MapEnd, - ], - ); - - assert_tokens( - &Outer::Inner(Inner::Newtype(1)), - &[ - Token::Map { len: Some(2) }, - Token::Str("type"), - Token::Str("Inner"), - Token::Str("Newtype"), - Token::U8(1), - Token::MapEnd, - ], - ); - - // Reaches crate::private::de::content::VariantDeserializer::tuple_variant - // Content::Seq case - // via ContentDeserializer::deserialize_enum - assert_tokens( - &Outer::Inner(Inner::Tuple(1, 1)), - &[ - Token::Map { len: Some(2) }, - Token::Str("type"), - Token::Str("Inner"), - Token::Str("Tuple"), - Token::TupleStruct { - name: "Tuple", - len: 2, - }, - Token::U8(1), - Token::U8(1), - Token::TupleStructEnd, - Token::MapEnd, - ], - ); - - // Reaches crate::private::de::content::VariantDeserializer::struct_variant - // Content::Map case - // via ContentDeserializer::deserialize_enum - assert_tokens( - &Outer::Inner(Inner::Struct { f: 1 }), - &[ - Token::Map { len: Some(2) }, - Token::Str("type"), - Token::Str("Inner"), - Token::Str("Struct"), - Token::Struct { - name: "Struct", - len: 1, - }, - Token::Str("f"), - Token::U8(1), - Token::StructEnd, - 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] fn test_internally_tagged_struct() { #[derive(Debug, PartialEq, Serialize, Deserialize)] @@ -2205,50 +2265,6 @@ fn test_untagged_newtype_variant_containing_unit_struct_not_map() { ); } -#[test] -fn test_internally_tagged_newtype_variant_containing_unit_struct() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - struct Info; - - #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "topic")] - enum Message { - Info(Info), - } - - assert_tokens( - &Message::Info(Info), - &[ - Token::Map { len: Some(1) }, - Token::Str("topic"), - Token::Str("Info"), - Token::MapEnd, - ], - ); - - assert_de_tokens( - &Message::Info(Info), - &[ - Token::Struct { - name: "Message", - len: 1, - }, - Token::Str("topic"), - Token::Str("Info"), - Token::StructEnd, - ], - ); - - assert_de_tokens( - &Message::Info(Info), - &[ - Token::Seq { len: Some(1) }, - Token::Str("Info"), - Token::SeqEnd, - ], - ); -} - #[test] fn test_packed_struct_can_derive_serialize() { #[derive(Copy, Clone, Serialize)] From da0ed4021df00153e86343ea0db710685f99eb28 Mon Sep 17 00:00:00 2001 From: Mingun Date: Sat, 22 Apr 2023 20:51:00 +0500 Subject: [PATCH 03/22] Give meaningful names to enum variants --- test_suite/tests/test_macros.rs | 50 ++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/test_suite/tests/test_macros.rs b/test_suite/tests/test_macros.rs index 84f2f444..64f0875d 100644 --- a/test_suite/tests/test_macros.rs +++ b/test_suite/tests/test_macros.rs @@ -693,24 +693,24 @@ mod internally_tagged_enum { #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(tag = "type")] enum InternallyTagged { - A { a: u8 }, - B, - C(BTreeMap), - D(Newtype), - E(Struct), + Struct { a: u8 }, + Unit, + NewtypeMap(BTreeMap), + NewtypeNewtype(Newtype), + NewtypeStruct(Struct), } #[test] fn struct_() { assert_tokens( - &InternallyTagged::A { a: 1 }, + &InternallyTagged::Struct { a: 1 }, &[ Token::Struct { name: "InternallyTagged", len: 2, }, Token::Str("type"), - Token::Str("A"), + Token::Str("Struct"), Token::Str("a"), Token::U8(1), Token::StructEnd, @@ -718,10 +718,10 @@ mod internally_tagged_enum { ); assert_de_tokens( - &InternallyTagged::A { a: 1 }, + &InternallyTagged::Struct { a: 1 }, &[ Token::Seq { len: Some(2) }, - Token::Str("A"), + Token::Str("Struct"), Token::U8(1), Token::SeqEnd, ], @@ -731,32 +731,36 @@ mod internally_tagged_enum { #[test] fn unit() { assert_tokens( - &InternallyTagged::B, + &InternallyTagged::Unit, &[ Token::Struct { name: "InternallyTagged", len: 1, }, Token::Str("type"), - Token::Str("B"), + Token::Str("Unit"), Token::StructEnd, ], ); assert_de_tokens( - &InternallyTagged::B, - &[Token::Seq { len: Some(1) }, Token::Str("B"), Token::SeqEnd], + &InternallyTagged::Unit, + &[ + Token::Seq { len: Some(1) }, + Token::Str("Unit"), + Token::SeqEnd, + ], ); } #[test] fn newtype_map() { assert_tokens( - &InternallyTagged::C(BTreeMap::new()), + &InternallyTagged::NewtypeMap(BTreeMap::new()), &[ Token::Map { len: Some(1) }, Token::Str("type"), - Token::Str("C"), + Token::Str("NewtypeMap"), Token::MapEnd, ], ); @@ -764,7 +768,7 @@ mod internally_tagged_enum { assert_de_tokens_error::( &[ Token::Seq { len: Some(2) }, - Token::Str("C"), + Token::Str("NewtypeMap"), Token::Map { len: Some(0) }, Token::MapEnd, Token::SeqEnd, @@ -776,11 +780,11 @@ mod internally_tagged_enum { #[test] fn newtype_newtype() { assert_tokens( - &InternallyTagged::D(Newtype(BTreeMap::new())), + &InternallyTagged::NewtypeNewtype(Newtype(BTreeMap::new())), &[ Token::Map { len: Some(1) }, Token::Str("type"), - Token::Str("D"), + Token::Str("NewtypeNewtype"), Token::MapEnd, ], ); @@ -789,14 +793,14 @@ mod internally_tagged_enum { #[test] fn newtype_struct() { assert_tokens( - &InternallyTagged::E(Struct { f: 6 }), + &InternallyTagged::NewtypeStruct(Struct { f: 6 }), &[ Token::Struct { name: "Struct", len: 2, }, Token::Str("type"), - Token::Str("E"), + Token::Str("NewtypeStruct"), Token::Str("f"), Token::U8(6), Token::StructEnd, @@ -804,10 +808,10 @@ mod internally_tagged_enum { ); assert_de_tokens( - &InternallyTagged::E(Struct { f: 6 }), + &InternallyTagged::NewtypeStruct(Struct { f: 6 }), &[ Token::Seq { len: Some(2) }, - Token::Str("E"), + Token::Str("NewtypeStruct"), Token::U8(6), Token::SeqEnd, ], @@ -828,7 +832,7 @@ mod internally_tagged_enum { Token::Str("Z"), Token::MapEnd, ], - "unknown variant `Z`, expected one of `A`, `B`, `C`, `D`, `E`", + "unknown variant `Z`, expected one of `Struct`, `Unit`, `NewtypeMap`, `NewtypeNewtype`, `NewtypeStruct`", ); } From 8c60f5aea7238bf21a6dc82aa497e8c49db0a0cc Mon Sep 17 00:00:00 2001 From: Mingun Date: Sat, 22 Apr 2023 20:54:00 +0500 Subject: [PATCH 04/22] Reorder enum variants and tests to canonical order (Unit, Newtype, Tuple, Struct) --- test_suite/tests/test_macros.rs | 88 ++++++++++++++++----------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/test_suite/tests/test_macros.rs b/test_suite/tests/test_macros.rs index 64f0875d..9404c383 100644 --- a/test_suite/tests/test_macros.rs +++ b/test_suite/tests/test_macros.rs @@ -693,39 +693,11 @@ mod internally_tagged_enum { #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(tag = "type")] enum InternallyTagged { - Struct { a: u8 }, Unit, - NewtypeMap(BTreeMap), NewtypeNewtype(Newtype), + NewtypeMap(BTreeMap), NewtypeStruct(Struct), - } - - #[test] - fn struct_() { - assert_tokens( - &InternallyTagged::Struct { a: 1 }, - &[ - Token::Struct { - name: "InternallyTagged", - len: 2, - }, - Token::Str("type"), - Token::Str("Struct"), - Token::Str("a"), - Token::U8(1), - Token::StructEnd, - ], - ); - - assert_de_tokens( - &InternallyTagged::Struct { a: 1 }, - &[ - Token::Seq { len: Some(2) }, - Token::Str("Struct"), - Token::U8(1), - Token::SeqEnd, - ], - ); + Struct { a: u8 }, } #[test] @@ -753,6 +725,19 @@ mod internally_tagged_enum { ); } + #[test] + fn newtype_newtype() { + assert_tokens( + &InternallyTagged::NewtypeNewtype(Newtype(BTreeMap::new())), + &[ + Token::Map { len: Some(1) }, + Token::Str("type"), + Token::Str("NewtypeNewtype"), + Token::MapEnd, + ], + ); + } + #[test] fn newtype_map() { assert_tokens( @@ -777,19 +762,6 @@ mod internally_tagged_enum { ); } - #[test] - fn newtype_newtype() { - assert_tokens( - &InternallyTagged::NewtypeNewtype(Newtype(BTreeMap::new())), - &[ - Token::Map { len: Some(1) }, - Token::Str("type"), - Token::Str("NewtypeNewtype"), - Token::MapEnd, - ], - ); - } - #[test] fn newtype_struct() { assert_tokens( @@ -818,6 +790,34 @@ mod internally_tagged_enum { ); } + #[test] + fn struct_() { + assert_tokens( + &InternallyTagged::Struct { a: 1 }, + &[ + Token::Struct { + name: "InternallyTagged", + len: 2, + }, + Token::Str("type"), + Token::Str("Struct"), + Token::Str("a"), + Token::U8(1), + Token::StructEnd, + ], + ); + + assert_de_tokens( + &InternallyTagged::Struct { a: 1 }, + &[ + Token::Seq { len: Some(2) }, + Token::Str("Struct"), + Token::U8(1), + Token::SeqEnd, + ], + ); + } + #[test] fn wrong_tag() { assert_de_tokens_error::( @@ -832,7 +832,7 @@ mod internally_tagged_enum { Token::Str("Z"), Token::MapEnd, ], - "unknown variant `Z`, expected one of `Struct`, `Unit`, `NewtypeMap`, `NewtypeNewtype`, `NewtypeStruct`", + "unknown variant `Z`, expected one of `Unit`, `NewtypeNewtype`, `NewtypeMap`, `NewtypeStruct`, `Struct`", ); } From 0939214c514086169e9bd3b8fc09b60ff3315e51 Mon Sep 17 00:00:00 2001 From: Mingun Date: Fri, 28 Jul 2023 00:30:15 +0500 Subject: [PATCH 05/22] Move internally tagged enum tests into a dedicated file Ctrl+X, Ctrl+V --- .../tests/test_enum_internally_tagged.rs | 671 ++++++++++++++++++ test_suite/tests/test_macros.rs | 662 ----------------- 2 files changed, 671 insertions(+), 662 deletions(-) create mode 100644 test_suite/tests/test_enum_internally_tagged.rs diff --git a/test_suite/tests/test_enum_internally_tagged.rs b/test_suite/tests/test_enum_internally_tagged.rs new file mode 100644 index 00000000..8c573a9e --- /dev/null +++ b/test_suite/tests/test_enum_internally_tagged.rs @@ -0,0 +1,671 @@ +#![deny(trivial_numeric_casts)] +#![allow( + clippy::derive_partial_eq_without_eq, + clippy::enum_variant_names, + clippy::redundant_field_names, + clippy::too_many_lines +)] + +mod bytes; + +use serde_derive::{Deserialize, Serialize}; +use serde_test::{assert_de_tokens, assert_de_tokens_error, assert_tokens, Token}; +use std::collections::BTreeMap; + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +struct Newtype(BTreeMap); + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +struct Struct { + f: u8, +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[serde(tag = "type")] +enum InternallyTagged { + Unit, + NewtypeNewtype(Newtype), + NewtypeMap(BTreeMap), + NewtypeStruct(Struct), + Struct { a: u8 }, +} + +#[test] +fn unit() { + assert_tokens( + &InternallyTagged::Unit, + &[ + Token::Struct { + name: "InternallyTagged", + len: 1, + }, + Token::Str("type"), + Token::Str("Unit"), + Token::StructEnd, + ], + ); + + assert_de_tokens( + &InternallyTagged::Unit, + &[ + Token::Seq { len: Some(1) }, + Token::Str("Unit"), + Token::SeqEnd, + ], + ); +} + +#[test] +fn newtype_newtype() { + assert_tokens( + &InternallyTagged::NewtypeNewtype(Newtype(BTreeMap::new())), + &[ + Token::Map { len: Some(1) }, + Token::Str("type"), + Token::Str("NewtypeNewtype"), + Token::MapEnd, + ], + ); +} + +#[test] +fn newtype_map() { + assert_tokens( + &InternallyTagged::NewtypeMap(BTreeMap::new()), + &[ + Token::Map { len: Some(1) }, + Token::Str("type"), + Token::Str("NewtypeMap"), + Token::MapEnd, + ], + ); + + assert_de_tokens_error::( + &[ + Token::Seq { len: Some(2) }, + Token::Str("NewtypeMap"), + Token::Map { len: Some(0) }, + Token::MapEnd, + Token::SeqEnd, + ], + "invalid type: sequence, expected a map", + ); +} + +#[test] +fn newtype_struct() { + assert_tokens( + &InternallyTagged::NewtypeStruct(Struct { f: 6 }), + &[ + Token::Struct { + name: "Struct", + len: 2, + }, + Token::Str("type"), + Token::Str("NewtypeStruct"), + Token::Str("f"), + Token::U8(6), + Token::StructEnd, + ], + ); + + assert_de_tokens( + &InternallyTagged::NewtypeStruct(Struct { f: 6 }), + &[ + Token::Seq { len: Some(2) }, + Token::Str("NewtypeStruct"), + Token::U8(6), + Token::SeqEnd, + ], + ); +} + +#[test] +fn struct_() { + assert_tokens( + &InternallyTagged::Struct { a: 1 }, + &[ + Token::Struct { + name: "InternallyTagged", + len: 2, + }, + Token::Str("type"), + Token::Str("Struct"), + Token::Str("a"), + Token::U8(1), + Token::StructEnd, + ], + ); + + assert_de_tokens( + &InternallyTagged::Struct { a: 1 }, + &[ + Token::Seq { len: Some(2) }, + Token::Str("Struct"), + Token::U8(1), + Token::SeqEnd, + ], + ); +} + +#[test] +fn wrong_tag() { + assert_de_tokens_error::( + &[Token::Map { len: Some(0) }, Token::MapEnd], + "missing field `type`", + ); + + assert_de_tokens_error::( + &[ + Token::Map { len: Some(1) }, + Token::Str("type"), + Token::Str("Z"), + Token::MapEnd, + ], + "unknown variant `Z`, expected one of `Unit`, `NewtypeNewtype`, `NewtypeMap`, `NewtypeStruct`, `Struct`", + ); +} + +#[test] +fn untagged_variant() { + #[derive(Debug, PartialEq, Serialize, Deserialize)] + #[serde(tag = "kind")] + enum InternallyTagged { + Tagged { + a: u8, + }, + #[serde(untagged)] + Untagged { + kind: String, + b: u8, + }, + } + + assert_de_tokens( + &InternallyTagged::Tagged { a: 1 }, + &[ + Token::Map { len: Some(2) }, + Token::Str("kind"), + Token::Str("Tagged"), + Token::Str("a"), + Token::U8(1), + Token::MapEnd, + ], + ); + + assert_tokens( + &InternallyTagged::Tagged { a: 1 }, + &[ + Token::Struct { + name: "InternallyTagged", + len: 2, + }, + Token::Str("kind"), + Token::Str("Tagged"), + Token::Str("a"), + Token::U8(1), + Token::StructEnd, + ], + ); + + assert_de_tokens( + &InternallyTagged::Untagged { + kind: "Foo".to_owned(), + b: 2, + }, + &[ + Token::Map { len: Some(2) }, + Token::Str("kind"), + Token::Str("Foo"), + Token::Str("b"), + Token::U8(2), + Token::MapEnd, + ], + ); + + assert_tokens( + &InternallyTagged::Untagged { + kind: "Foo".to_owned(), + b: 2, + }, + &[ + Token::Struct { + name: "InternallyTagged", + len: 2, + }, + Token::Str("kind"), + Token::Str("Foo"), + Token::Str("b"), + Token::U8(2), + Token::StructEnd, + ], + ); + + assert_tokens( + &InternallyTagged::Untagged { + kind: "Tagged".to_owned(), + b: 2, + }, + &[ + Token::Struct { + name: "InternallyTagged", + len: 2, + }, + Token::Str("kind"), + Token::Str("Tagged"), + Token::Str("b"), + Token::U8(2), + Token::StructEnd, + ], + ); +} + +mod string_and_bytes { + use super::*; + + #[derive(Debug, PartialEq, Deserialize)] + #[serde(tag = "type")] + enum InternallyTagged { + String { + string: String, + }, + Bytes { + #[serde(with = "bytes")] + bytes: Vec, + }, + } + + #[test] + fn string_from_string() { + assert_de_tokens( + &InternallyTagged::String { + string: "\0".to_owned(), + }, + &[ + Token::Struct { + name: "String", + len: 2, + }, + Token::Str("type"), + Token::Str("String"), + Token::Str("string"), + Token::Str("\0"), + Token::StructEnd, + ], + ); + + assert_de_tokens( + &InternallyTagged::String { + string: "\0".to_owned(), + }, + &[ + Token::Struct { + name: "String", + len: 2, + }, + Token::Str("type"), + Token::Str("String"), + Token::Str("string"), + Token::String("\0"), + Token::StructEnd, + ], + ); + } + + #[test] + fn string_from_bytes() { + assert_de_tokens( + &InternallyTagged::String { + string: "\0".to_owned(), + }, + &[ + Token::Struct { + name: "String", + len: 2, + }, + Token::Str("type"), + Token::Str("String"), + Token::Str("string"), + Token::Bytes(b"\0"), + Token::StructEnd, + ], + ); + + assert_de_tokens( + &InternallyTagged::String { + string: "\0".to_owned(), + }, + &[ + Token::Struct { + name: "String", + len: 2, + }, + Token::Str("type"), + Token::Str("String"), + Token::Str("string"), + Token::ByteBuf(b"\0"), + Token::StructEnd, + ], + ); + } + + #[test] + fn bytes_from_string() { + assert_de_tokens( + &InternallyTagged::Bytes { bytes: vec![0] }, + &[ + Token::Struct { + name: "Bytes", + len: 2, + }, + Token::Str("type"), + Token::Str("Bytes"), + Token::Str("bytes"), + Token::Str("\0"), + Token::StructEnd, + ], + ); + + assert_de_tokens( + &InternallyTagged::Bytes { bytes: vec![0] }, + &[ + Token::Struct { + name: "Bytes", + len: 2, + }, + Token::Str("type"), + Token::Str("Bytes"), + Token::Str("bytes"), + Token::String("\0"), + Token::StructEnd, + ], + ); + } + + #[test] + fn bytes_from_bytes() { + assert_de_tokens( + &InternallyTagged::Bytes { bytes: vec![0] }, + &[ + Token::Struct { + name: "Bytes", + len: 2, + }, + Token::Str("type"), + Token::Str("Bytes"), + Token::Str("bytes"), + Token::Bytes(b"\0"), + Token::StructEnd, + ], + ); + + assert_de_tokens( + &InternallyTagged::Bytes { bytes: vec![0] }, + &[ + Token::Struct { + name: "Bytes", + len: 2, + }, + Token::Str("type"), + Token::Str("Bytes"), + Token::Str("bytes"), + Token::ByteBuf(b"\0"), + Token::StructEnd, + ], + ); + } + + #[test] + fn bytes_from_seq() { + assert_de_tokens( + &InternallyTagged::Bytes { bytes: vec![0] }, + &[ + Token::Struct { + name: "Bytes", + len: 2, + }, + Token::Str("type"), + Token::Str("Bytes"), + Token::Str("bytes"), + Token::Seq { len: Some(1) }, + Token::U8(0), + Token::SeqEnd, + Token::StructEnd, + ], + ); + } +} + +#[test] +fn struct_variant_containing_unit_variant() { + #[derive(Debug, PartialEq, Serialize, Deserialize)] + pub enum Level { + Info, + } + + #[derive(Debug, PartialEq, Serialize, Deserialize)] + #[serde(tag = "action")] + pub enum Message { + Log { level: Level }, + } + + assert_de_tokens( + &Level::Info, + &[ + Token::Enum { name: "Level" }, + Token::BorrowedStr("Info"), + Token::Unit, + ], + ); + + assert_de_tokens( + &Message::Log { level: Level::Info }, + &[ + Token::Struct { + name: "Message", + len: 2, + }, + Token::Str("action"), + Token::Str("Log"), + Token::Str("level"), + Token::Enum { name: "Level" }, + Token::BorrowedStr("Info"), + Token::Unit, + Token::StructEnd, + ], + ); + + assert_de_tokens( + &Message::Log { level: Level::Info }, + &[ + Token::Map { len: Some(2) }, + Token::Str("action"), + Token::Str("Log"), + Token::Str("level"), + Token::Enum { name: "Level" }, + Token::BorrowedStr("Info"), + Token::Unit, + Token::MapEnd, + ], + ); + + assert_de_tokens( + &Message::Log { level: Level::Info }, + &[ + Token::Seq { len: Some(2) }, + Token::Str("Log"), + Token::Enum { name: "Level" }, + Token::BorrowedStr("Info"), + Token::Unit, + Token::SeqEnd, + ], + ); +} + +#[test] +fn borrow() { + #[derive(Debug, PartialEq, Serialize, Deserialize)] + #[serde(tag = "type")] + enum Input<'a> { + Package { name: &'a str }, + } + + assert_tokens( + &Input::Package { name: "borrowed" }, + &[ + Token::Struct { + name: "Input", + len: 2, + }, + Token::BorrowedStr("type"), + Token::BorrowedStr("Package"), + Token::BorrowedStr("name"), + Token::BorrowedStr("borrowed"), + Token::StructEnd, + ], + ); +} + +#[test] +fn newtype_variant_containing_externally_tagged_enum() { + #[derive(Debug, PartialEq, Serialize, Deserialize)] + #[serde(tag = "type")] + enum Outer { + Inner(Inner), + } + + #[derive(Debug, PartialEq, Serialize, Deserialize)] + enum Inner { + Unit, + Newtype(u8), + Tuple(u8, u8), + Struct { f: u8 }, + } + + assert_tokens( + &Outer::Inner(Inner::Unit), + &[ + Token::Map { len: Some(2) }, + Token::Str("type"), + Token::Str("Inner"), + Token::Str("Unit"), + Token::Unit, + Token::MapEnd, + ], + ); + + assert_tokens( + &Outer::Inner(Inner::Newtype(1)), + &[ + Token::Map { len: Some(2) }, + Token::Str("type"), + Token::Str("Inner"), + Token::Str("Newtype"), + Token::U8(1), + Token::MapEnd, + ], + ); + + // Reaches crate::private::de::content::VariantDeserializer::tuple_variant + // Content::Seq case + // via ContentDeserializer::deserialize_enum + assert_tokens( + &Outer::Inner(Inner::Tuple(1, 1)), + &[ + Token::Map { len: Some(2) }, + Token::Str("type"), + Token::Str("Inner"), + Token::Str("Tuple"), + Token::TupleStruct { + name: "Tuple", + len: 2, + }, + Token::U8(1), + Token::U8(1), + Token::TupleStructEnd, + Token::MapEnd, + ], + ); + + // Reaches crate::private::de::content::VariantDeserializer::struct_variant + // Content::Map case + // via ContentDeserializer::deserialize_enum + assert_tokens( + &Outer::Inner(Inner::Struct { f: 1 }), + &[ + Token::Map { len: Some(2) }, + Token::Str("type"), + Token::Str("Inner"), + Token::Str("Struct"), + Token::Struct { + name: "Struct", + len: 1, + }, + Token::Str("f"), + Token::U8(1), + Token::StructEnd, + 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] +fn newtype_variant_containing_unit_struct() { + #[derive(Debug, PartialEq, Serialize, Deserialize)] + struct Info; + + #[derive(Debug, PartialEq, Serialize, Deserialize)] + #[serde(tag = "topic")] + enum Message { + Info(Info), + } + + assert_tokens( + &Message::Info(Info), + &[ + Token::Map { len: Some(1) }, + Token::Str("topic"), + Token::Str("Info"), + Token::MapEnd, + ], + ); + + assert_de_tokens( + &Message::Info(Info), + &[ + Token::Struct { + name: "Message", + len: 1, + }, + Token::Str("topic"), + Token::Str("Info"), + Token::StructEnd, + ], + ); + + assert_de_tokens( + &Message::Info(Info), + &[ + Token::Seq { len: Some(1) }, + Token::Str("Info"), + Token::SeqEnd, + ], + ); +} \ No newline at end of file diff --git a/test_suite/tests/test_macros.rs b/test_suite/tests/test_macros.rs index 9404c383..72137ddd 100644 --- a/test_suite/tests/test_macros.rs +++ b/test_suite/tests/test_macros.rs @@ -679,668 +679,6 @@ fn test_untagged_enum() { ); } -mod internally_tagged_enum { - use super::*; - - #[derive(Debug, PartialEq, Serialize, Deserialize)] - struct Newtype(BTreeMap); - - #[derive(Debug, PartialEq, Serialize, Deserialize)] - struct Struct { - f: u8, - } - - #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "type")] - enum InternallyTagged { - Unit, - NewtypeNewtype(Newtype), - NewtypeMap(BTreeMap), - NewtypeStruct(Struct), - Struct { a: u8 }, - } - - #[test] - fn unit() { - assert_tokens( - &InternallyTagged::Unit, - &[ - Token::Struct { - name: "InternallyTagged", - len: 1, - }, - Token::Str("type"), - Token::Str("Unit"), - Token::StructEnd, - ], - ); - - assert_de_tokens( - &InternallyTagged::Unit, - &[ - Token::Seq { len: Some(1) }, - Token::Str("Unit"), - Token::SeqEnd, - ], - ); - } - - #[test] - fn newtype_newtype() { - assert_tokens( - &InternallyTagged::NewtypeNewtype(Newtype(BTreeMap::new())), - &[ - Token::Map { len: Some(1) }, - Token::Str("type"), - Token::Str("NewtypeNewtype"), - Token::MapEnd, - ], - ); - } - - #[test] - fn newtype_map() { - assert_tokens( - &InternallyTagged::NewtypeMap(BTreeMap::new()), - &[ - Token::Map { len: Some(1) }, - Token::Str("type"), - Token::Str("NewtypeMap"), - Token::MapEnd, - ], - ); - - assert_de_tokens_error::( - &[ - Token::Seq { len: Some(2) }, - Token::Str("NewtypeMap"), - Token::Map { len: Some(0) }, - Token::MapEnd, - Token::SeqEnd, - ], - "invalid type: sequence, expected a map", - ); - } - - #[test] - fn newtype_struct() { - assert_tokens( - &InternallyTagged::NewtypeStruct(Struct { f: 6 }), - &[ - Token::Struct { - name: "Struct", - len: 2, - }, - Token::Str("type"), - Token::Str("NewtypeStruct"), - Token::Str("f"), - Token::U8(6), - Token::StructEnd, - ], - ); - - assert_de_tokens( - &InternallyTagged::NewtypeStruct(Struct { f: 6 }), - &[ - Token::Seq { len: Some(2) }, - Token::Str("NewtypeStruct"), - Token::U8(6), - Token::SeqEnd, - ], - ); - } - - #[test] - fn struct_() { - assert_tokens( - &InternallyTagged::Struct { a: 1 }, - &[ - Token::Struct { - name: "InternallyTagged", - len: 2, - }, - Token::Str("type"), - Token::Str("Struct"), - Token::Str("a"), - Token::U8(1), - Token::StructEnd, - ], - ); - - assert_de_tokens( - &InternallyTagged::Struct { a: 1 }, - &[ - Token::Seq { len: Some(2) }, - Token::Str("Struct"), - Token::U8(1), - Token::SeqEnd, - ], - ); - } - - #[test] - fn wrong_tag() { - assert_de_tokens_error::( - &[Token::Map { len: Some(0) }, Token::MapEnd], - "missing field `type`", - ); - - assert_de_tokens_error::( - &[ - Token::Map { len: Some(1) }, - Token::Str("type"), - Token::Str("Z"), - Token::MapEnd, - ], - "unknown variant `Z`, expected one of `Unit`, `NewtypeNewtype`, `NewtypeMap`, `NewtypeStruct`, `Struct`", - ); - } - - #[test] - fn untagged_variant() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "kind")] - enum InternallyTagged { - Tagged { - a: u8, - }, - #[serde(untagged)] - Untagged { - kind: String, - b: u8, - }, - } - - assert_de_tokens( - &InternallyTagged::Tagged { a: 1 }, - &[ - Token::Map { len: Some(2) }, - Token::Str("kind"), - Token::Str("Tagged"), - Token::Str("a"), - Token::U8(1), - Token::MapEnd, - ], - ); - - assert_tokens( - &InternallyTagged::Tagged { a: 1 }, - &[ - Token::Struct { - name: "InternallyTagged", - len: 2, - }, - Token::Str("kind"), - Token::Str("Tagged"), - Token::Str("a"), - Token::U8(1), - Token::StructEnd, - ], - ); - - assert_de_tokens( - &InternallyTagged::Untagged { - kind: "Foo".to_owned(), - b: 2, - }, - &[ - Token::Map { len: Some(2) }, - Token::Str("kind"), - Token::Str("Foo"), - Token::Str("b"), - Token::U8(2), - Token::MapEnd, - ], - ); - - assert_tokens( - &InternallyTagged::Untagged { - kind: "Foo".to_owned(), - b: 2, - }, - &[ - Token::Struct { - name: "InternallyTagged", - len: 2, - }, - Token::Str("kind"), - Token::Str("Foo"), - Token::Str("b"), - Token::U8(2), - Token::StructEnd, - ], - ); - - assert_tokens( - &InternallyTagged::Untagged { - kind: "Tagged".to_owned(), - b: 2, - }, - &[ - Token::Struct { - name: "InternallyTagged", - len: 2, - }, - Token::Str("kind"), - Token::Str("Tagged"), - Token::Str("b"), - Token::U8(2), - Token::StructEnd, - ], - ); - } - - mod string_and_bytes { - use super::*; - - #[derive(Debug, PartialEq, Deserialize)] - #[serde(tag = "type")] - enum InternallyTagged { - String { - string: String, - }, - Bytes { - #[serde(with = "bytes")] - bytes: Vec, - }, - } - - #[test] - fn string_from_string() { - assert_de_tokens( - &InternallyTagged::String { - string: "\0".to_owned(), - }, - &[ - Token::Struct { - name: "String", - len: 2, - }, - Token::Str("type"), - Token::Str("String"), - Token::Str("string"), - Token::Str("\0"), - Token::StructEnd, - ], - ); - - assert_de_tokens( - &InternallyTagged::String { - string: "\0".to_owned(), - }, - &[ - Token::Struct { - name: "String", - len: 2, - }, - Token::Str("type"), - Token::Str("String"), - Token::Str("string"), - Token::String("\0"), - Token::StructEnd, - ], - ); - } - - #[test] - fn string_from_bytes() { - assert_de_tokens( - &InternallyTagged::String { - string: "\0".to_owned(), - }, - &[ - Token::Struct { - name: "String", - len: 2, - }, - Token::Str("type"), - Token::Str("String"), - Token::Str("string"), - Token::Bytes(b"\0"), - Token::StructEnd, - ], - ); - - assert_de_tokens( - &InternallyTagged::String { - string: "\0".to_owned(), - }, - &[ - Token::Struct { - name: "String", - len: 2, - }, - Token::Str("type"), - Token::Str("String"), - Token::Str("string"), - Token::ByteBuf(b"\0"), - Token::StructEnd, - ], - ); - } - - #[test] - fn bytes_from_string() { - assert_de_tokens( - &InternallyTagged::Bytes { bytes: vec![0] }, - &[ - Token::Struct { - name: "Bytes", - len: 2, - }, - Token::Str("type"), - Token::Str("Bytes"), - Token::Str("bytes"), - Token::Str("\0"), - Token::StructEnd, - ], - ); - - assert_de_tokens( - &InternallyTagged::Bytes { bytes: vec![0] }, - &[ - Token::Struct { - name: "Bytes", - len: 2, - }, - Token::Str("type"), - Token::Str("Bytes"), - Token::Str("bytes"), - Token::String("\0"), - Token::StructEnd, - ], - ); - } - - #[test] - fn bytes_from_bytes() { - assert_de_tokens( - &InternallyTagged::Bytes { bytes: vec![0] }, - &[ - Token::Struct { - name: "Bytes", - len: 2, - }, - Token::Str("type"), - Token::Str("Bytes"), - Token::Str("bytes"), - Token::Bytes(b"\0"), - Token::StructEnd, - ], - ); - - assert_de_tokens( - &InternallyTagged::Bytes { bytes: vec![0] }, - &[ - Token::Struct { - name: "Bytes", - len: 2, - }, - Token::Str("type"), - Token::Str("Bytes"), - Token::Str("bytes"), - Token::ByteBuf(b"\0"), - Token::StructEnd, - ], - ); - } - - #[test] - fn bytes_from_seq() { - assert_de_tokens( - &InternallyTagged::Bytes { bytes: vec![0] }, - &[ - Token::Struct { - name: "Bytes", - len: 2, - }, - Token::Str("type"), - Token::Str("Bytes"), - Token::Str("bytes"), - Token::Seq { len: Some(1) }, - Token::U8(0), - Token::SeqEnd, - Token::StructEnd, - ], - ); - } - } - - #[test] - fn struct_variant_containing_unit_variant() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - pub enum Level { - Info, - } - - #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "action")] - pub enum Message { - Log { level: Level }, - } - - assert_de_tokens( - &Level::Info, - &[ - Token::Enum { name: "Level" }, - Token::BorrowedStr("Info"), - Token::Unit, - ], - ); - - assert_de_tokens( - &Message::Log { level: Level::Info }, - &[ - Token::Struct { - name: "Message", - len: 2, - }, - Token::Str("action"), - Token::Str("Log"), - Token::Str("level"), - Token::Enum { name: "Level" }, - Token::BorrowedStr("Info"), - Token::Unit, - Token::StructEnd, - ], - ); - - assert_de_tokens( - &Message::Log { level: Level::Info }, - &[ - Token::Map { len: Some(2) }, - Token::Str("action"), - Token::Str("Log"), - Token::Str("level"), - Token::Enum { name: "Level" }, - Token::BorrowedStr("Info"), - Token::Unit, - Token::MapEnd, - ], - ); - - assert_de_tokens( - &Message::Log { level: Level::Info }, - &[ - Token::Seq { len: Some(2) }, - Token::Str("Log"), - Token::Enum { name: "Level" }, - Token::BorrowedStr("Info"), - Token::Unit, - Token::SeqEnd, - ], - ); - } - - #[test] - fn borrow() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "type")] - enum Input<'a> { - Package { name: &'a str }, - } - - assert_tokens( - &Input::Package { name: "borrowed" }, - &[ - Token::Struct { - name: "Input", - len: 2, - }, - Token::BorrowedStr("type"), - Token::BorrowedStr("Package"), - Token::BorrowedStr("name"), - Token::BorrowedStr("borrowed"), - Token::StructEnd, - ], - ); - } - - #[test] - fn newtype_variant_containing_externally_tagged_enum() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "type")] - enum Outer { - Inner(Inner), - } - - #[derive(Debug, PartialEq, Serialize, Deserialize)] - enum Inner { - Unit, - Newtype(u8), - Tuple(u8, u8), - Struct { f: u8 }, - } - - assert_tokens( - &Outer::Inner(Inner::Unit), - &[ - Token::Map { len: Some(2) }, - Token::Str("type"), - Token::Str("Inner"), - Token::Str("Unit"), - Token::Unit, - Token::MapEnd, - ], - ); - - assert_tokens( - &Outer::Inner(Inner::Newtype(1)), - &[ - Token::Map { len: Some(2) }, - Token::Str("type"), - Token::Str("Inner"), - Token::Str("Newtype"), - Token::U8(1), - Token::MapEnd, - ], - ); - - // Reaches crate::private::de::content::VariantDeserializer::tuple_variant - // Content::Seq case - // via ContentDeserializer::deserialize_enum - assert_tokens( - &Outer::Inner(Inner::Tuple(1, 1)), - &[ - Token::Map { len: Some(2) }, - Token::Str("type"), - Token::Str("Inner"), - Token::Str("Tuple"), - Token::TupleStruct { - name: "Tuple", - len: 2, - }, - Token::U8(1), - Token::U8(1), - Token::TupleStructEnd, - Token::MapEnd, - ], - ); - - // Reaches crate::private::de::content::VariantDeserializer::struct_variant - // Content::Map case - // via ContentDeserializer::deserialize_enum - assert_tokens( - &Outer::Inner(Inner::Struct { f: 1 }), - &[ - Token::Map { len: Some(2) }, - Token::Str("type"), - Token::Str("Inner"), - Token::Str("Struct"), - Token::Struct { - name: "Struct", - len: 1, - }, - Token::Str("f"), - Token::U8(1), - Token::StructEnd, - 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] - fn newtype_variant_containing_unit_struct() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - struct Info; - - #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "topic")] - enum Message { - Info(Info), - } - - assert_tokens( - &Message::Info(Info), - &[ - Token::Map { len: Some(1) }, - Token::Str("topic"), - Token::Str("Info"), - Token::MapEnd, - ], - ); - - assert_de_tokens( - &Message::Info(Info), - &[ - Token::Struct { - name: "Message", - len: 1, - }, - Token::Str("topic"), - Token::Str("Info"), - Token::StructEnd, - ], - ); - - assert_de_tokens( - &Message::Info(Info), - &[ - Token::Seq { len: Some(1) }, - Token::Str("Info"), - Token::SeqEnd, - ], - ); - } -} - #[test] fn test_adjacently_tagged_enum() { #[derive(Debug, PartialEq, Serialize, Deserialize)] From 2cbfd37072a5af4774a77c8d3f7661dd3c1af194 Mon Sep 17 00:00:00 2001 From: Mingun Date: Fri, 28 Jul 2023 00:46:02 +0500 Subject: [PATCH 06/22] Move all other internally tagged enum tests into a dedicated file Moved all except flattened tests: - test_internally_tagged_enum_with_skipped_conflict => with_skipped_conflict - test_internally_tagged_enum_new_type_with_unit => newtype_variant_containing_unit - test_internally_tagged_unit_enum_with_unknown_fields => unit_variant_with_unknown_fields - test_expecting_message_internally_tagged_enum => expecting_message - flatten::enum_::internally_tagged::straightforward => containing_flatten --- test_suite/tests/test_annotations.rs | 133 ----------------- .../tests/test_enum_internally_tagged.rs | 135 +++++++++++++++++- 2 files changed, 134 insertions(+), 134 deletions(-) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index 6864bf96..9aa32872 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -1607,58 +1607,6 @@ fn test_collect_other() { ); } -#[test] -fn test_internally_tagged_enum_with_skipped_conflict() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - #[serde(tag = "t")] - enum Data { - A, - #[serde(skip)] - #[allow(dead_code)] - B { - t: String, - }, - C { - #[serde(default, skip)] - t: String, - }, - } - - let data = Data::C { t: String::new() }; - - assert_tokens( - &data, - &[ - Token::Struct { - name: "Data", - len: 1, - }, - Token::Str("t"), - Token::Str("C"), - Token::StructEnd, - ], - ); -} - -#[test] -fn test_internally_tagged_enum_new_type_with_unit() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - #[serde(tag = "t")] - enum Data { - A(()), - } - - assert_tokens( - &Data::A(()), - &[ - Token::Map { len: Some(1) }, - Token::Str("t"), - Token::Str("A"), - Token::MapEnd, - ], - ); -} - #[test] fn test_adjacently_tagged_enum_bytes() { #[derive(Serialize, Deserialize, PartialEq, Debug)] @@ -1968,29 +1916,6 @@ fn test_transparent_tuple_struct() { assert_tokens(&Transparent(false, 1, false, PhantomData), &[Token::U32(1)]); } -#[test] -fn test_internally_tagged_unit_enum_with_unknown_fields() { - #[derive(Deserialize, PartialEq, Debug)] - #[serde(tag = "t")] - enum Data { - A, - } - - let data = Data::A; - - assert_de_tokens( - &data, - &[ - Token::Map { len: None }, - Token::Str("t"), - Token::Str("A"), - Token::Str("b"), - Token::I32(0), - Token::MapEnd, - ], - ); -} - #[test] fn test_expecting_message() { #[derive(Deserialize, PartialEq, Debug)] @@ -2055,27 +1980,6 @@ fn test_expecting_message_externally_tagged_enum() { ); } -#[test] -fn test_expecting_message_internally_tagged_enum() { - #[derive(Deserialize)] - #[serde(tag = "tag")] - #[serde(expecting = "something strange...")] - enum Enum { - InternallyTagged, - } - - assert_de_tokens_error::( - &[Token::Str("InternallyTagged")], - r#"invalid type: string "InternallyTagged", expected something strange..."#, - ); - - // Check that #[serde(expecting = "...")] doesn't affect variant identifier error message - assert_de_tokens_error::( - &[Token::Map { len: None }, Token::Str("tag"), Token::Unit], - "invalid type: unit value, expected variant identifier", - ); -} - #[test] fn test_expecting_message_adjacently_tagged_enum() { #[derive(Deserialize)] @@ -3123,43 +3027,6 @@ mod flatten { mod internally_tagged { use super::*; - #[test] - fn straightforward() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - #[serde(tag = "t")] - enum Data { - A { - a: i32, - #[serde(flatten)] - flat: Flat, - }, - } - - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct Flat { - b: i32, - } - - let data = Data::A { - a: 0, - flat: Flat { b: 0 }, - }; - - assert_tokens( - &data, - &[ - Token::Map { len: None }, - Token::Str("t"), - Token::Str("A"), - Token::Str("a"), - Token::I32(0), - Token::Str("b"), - Token::I32(0), - Token::MapEnd, - ], - ); - } - #[test] fn structs() { #[derive(Debug, PartialEq, Serialize, Deserialize)] diff --git a/test_suite/tests/test_enum_internally_tagged.rs b/test_suite/tests/test_enum_internally_tagged.rs index 8c573a9e..0a022028 100644 --- a/test_suite/tests/test_enum_internally_tagged.rs +++ b/test_suite/tests/test_enum_internally_tagged.rs @@ -668,4 +668,137 @@ fn newtype_variant_containing_unit_struct() { Token::SeqEnd, ], ); -} \ No newline at end of file +} + +#[test] +fn with_skipped_conflict() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[serde(tag = "t")] + enum Data { + A, + #[serde(skip)] + #[allow(dead_code)] + B { + t: String, + }, + C { + #[serde(default, skip)] + t: String, + }, + } + + let data = Data::C { t: String::new() }; + + assert_tokens( + &data, + &[ + Token::Struct { + name: "Data", + len: 1, + }, + Token::Str("t"), + Token::Str("C"), + Token::StructEnd, + ], + ); +} + +#[test] +fn containing_flatten() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[serde(tag = "t")] + enum Data { + A { + a: i32, + #[serde(flatten)] + flat: Flat, + }, + } + + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Flat { + b: i32, + } + + let data = Data::A { + a: 0, + flat: Flat { b: 0 }, + }; + + assert_tokens( + &data, + &[ + Token::Map { len: None }, + Token::Str("t"), + Token::Str("A"), + Token::Str("a"), + Token::I32(0), + Token::Str("b"), + Token::I32(0), + Token::MapEnd, + ], + ); +} + +#[test] +fn newtype_variant_containing_unit() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[serde(tag = "t")] + enum Data { + A(()), + } + + assert_tokens( + &Data::A(()), + &[ + Token::Map { len: Some(1) }, + Token::Str("t"), + Token::Str("A"), + Token::MapEnd, + ], + ); +} + +#[test] +fn unit_variant_with_unknown_fields() { + #[derive(Deserialize, PartialEq, Debug)] + #[serde(tag = "t")] + enum Data { + A, + } + + let data = Data::A; + + assert_de_tokens( + &data, + &[ + Token::Map { len: None }, + Token::Str("t"), + Token::Str("A"), + Token::Str("b"), + Token::I32(0), + Token::MapEnd, + ], + ); +} + +#[test] +fn expecting_message() { + #[derive(Deserialize)] + #[serde(tag = "tag")] + #[serde(expecting = "something strange...")] + enum Enum { + InternallyTagged, + } + + assert_de_tokens_error::( + &[Token::Str("InternallyTagged")], + r#"invalid type: string "InternallyTagged", expected something strange..."#, + ); + + // Check that #[serde(expecting = "...")] doesn't affect variant identifier error message + assert_de_tokens_error::( + &[Token::Map { len: None }, Token::Str("tag"), Token::Unit], + "invalid type: unit value, expected variant identifier", + ); +} From 9128201c78ae7674ae6c0c5876b7842c0d0c3664 Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 7 Aug 2023 21:12:23 +0500 Subject: [PATCH 07/22] Use the same order of derives --- test_suite/tests/test_enum_internally_tagged.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test_suite/tests/test_enum_internally_tagged.rs b/test_suite/tests/test_enum_internally_tagged.rs index 0a022028..751a80c9 100644 --- a/test_suite/tests/test_enum_internally_tagged.rs +++ b/test_suite/tests/test_enum_internally_tagged.rs @@ -672,7 +672,7 @@ fn newtype_variant_containing_unit_struct() { #[test] fn with_skipped_conflict() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(tag = "t")] enum Data { A, @@ -705,7 +705,7 @@ fn with_skipped_conflict() { #[test] fn containing_flatten() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(tag = "t")] enum Data { A { @@ -715,7 +715,7 @@ fn containing_flatten() { }, } - #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, Serialize, Deserialize)] struct Flat { b: i32, } @@ -742,7 +742,7 @@ fn containing_flatten() { #[test] fn newtype_variant_containing_unit() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(tag = "t")] enum Data { A(()), @@ -761,7 +761,7 @@ fn newtype_variant_containing_unit() { #[test] fn unit_variant_with_unknown_fields() { - #[derive(Deserialize, PartialEq, Debug)] + #[derive(Debug, PartialEq, Deserialize)] #[serde(tag = "t")] enum Data { A, From eb59c776ca5c14312a03ce8fc70ce8a071f27cad Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 7 Aug 2023 21:15:21 +0500 Subject: [PATCH 08/22] Use name "tag" to refer to tag field --- .../tests/test_enum_internally_tagged.rs | 100 +++++++++--------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/test_suite/tests/test_enum_internally_tagged.rs b/test_suite/tests/test_enum_internally_tagged.rs index 751a80c9..63b2c437 100644 --- a/test_suite/tests/test_enum_internally_tagged.rs +++ b/test_suite/tests/test_enum_internally_tagged.rs @@ -21,7 +21,7 @@ struct Struct { } #[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(tag = "type")] +#[serde(tag = "tag")] enum InternallyTagged { Unit, NewtypeNewtype(Newtype), @@ -39,7 +39,7 @@ fn unit() { name: "InternallyTagged", len: 1, }, - Token::Str("type"), + Token::Str("tag"), Token::Str("Unit"), Token::StructEnd, ], @@ -61,7 +61,7 @@ fn newtype_newtype() { &InternallyTagged::NewtypeNewtype(Newtype(BTreeMap::new())), &[ Token::Map { len: Some(1) }, - Token::Str("type"), + Token::Str("tag"), Token::Str("NewtypeNewtype"), Token::MapEnd, ], @@ -74,7 +74,7 @@ fn newtype_map() { &InternallyTagged::NewtypeMap(BTreeMap::new()), &[ Token::Map { len: Some(1) }, - Token::Str("type"), + Token::Str("tag"), Token::Str("NewtypeMap"), Token::MapEnd, ], @@ -101,7 +101,7 @@ fn newtype_struct() { name: "Struct", len: 2, }, - Token::Str("type"), + Token::Str("tag"), Token::Str("NewtypeStruct"), Token::Str("f"), Token::U8(6), @@ -129,7 +129,7 @@ fn struct_() { name: "InternallyTagged", len: 2, }, - Token::Str("type"), + Token::Str("tag"), Token::Str("Struct"), Token::Str("a"), Token::U8(1), @@ -152,13 +152,13 @@ fn struct_() { fn wrong_tag() { assert_de_tokens_error::( &[Token::Map { len: Some(0) }, Token::MapEnd], - "missing field `type`", + "missing field `tag`", ); assert_de_tokens_error::( &[ Token::Map { len: Some(1) }, - Token::Str("type"), + Token::Str("tag"), Token::Str("Z"), Token::MapEnd, ], @@ -169,14 +169,14 @@ fn wrong_tag() { #[test] fn untagged_variant() { #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "kind")] + #[serde(tag = "tag")] enum InternallyTagged { Tagged { a: u8, }, #[serde(untagged)] Untagged { - kind: String, + tag: String, b: u8, }, } @@ -185,7 +185,7 @@ fn untagged_variant() { &InternallyTagged::Tagged { a: 1 }, &[ Token::Map { len: Some(2) }, - Token::Str("kind"), + Token::Str("tag"), Token::Str("Tagged"), Token::Str("a"), Token::U8(1), @@ -200,7 +200,7 @@ fn untagged_variant() { name: "InternallyTagged", len: 2, }, - Token::Str("kind"), + Token::Str("tag"), Token::Str("Tagged"), Token::Str("a"), Token::U8(1), @@ -210,12 +210,12 @@ fn untagged_variant() { assert_de_tokens( &InternallyTagged::Untagged { - kind: "Foo".to_owned(), + tag: "Foo".to_owned(), b: 2, }, &[ Token::Map { len: Some(2) }, - Token::Str("kind"), + Token::Str("tag"), Token::Str("Foo"), Token::Str("b"), Token::U8(2), @@ -225,7 +225,7 @@ fn untagged_variant() { assert_tokens( &InternallyTagged::Untagged { - kind: "Foo".to_owned(), + tag: "Foo".to_owned(), b: 2, }, &[ @@ -233,7 +233,7 @@ fn untagged_variant() { name: "InternallyTagged", len: 2, }, - Token::Str("kind"), + Token::Str("tag"), Token::Str("Foo"), Token::Str("b"), Token::U8(2), @@ -243,7 +243,7 @@ fn untagged_variant() { assert_tokens( &InternallyTagged::Untagged { - kind: "Tagged".to_owned(), + tag: "Tagged".to_owned(), b: 2, }, &[ @@ -251,7 +251,7 @@ fn untagged_variant() { name: "InternallyTagged", len: 2, }, - Token::Str("kind"), + Token::Str("tag"), Token::Str("Tagged"), Token::Str("b"), Token::U8(2), @@ -264,7 +264,7 @@ mod string_and_bytes { use super::*; #[derive(Debug, PartialEq, Deserialize)] - #[serde(tag = "type")] + #[serde(tag = "tag")] enum InternallyTagged { String { string: String, @@ -286,7 +286,7 @@ mod string_and_bytes { name: "String", len: 2, }, - Token::Str("type"), + Token::Str("tag"), Token::Str("String"), Token::Str("string"), Token::Str("\0"), @@ -303,7 +303,7 @@ mod string_and_bytes { name: "String", len: 2, }, - Token::Str("type"), + Token::Str("tag"), Token::Str("String"), Token::Str("string"), Token::String("\0"), @@ -323,7 +323,7 @@ mod string_and_bytes { name: "String", len: 2, }, - Token::Str("type"), + Token::Str("tag"), Token::Str("String"), Token::Str("string"), Token::Bytes(b"\0"), @@ -340,7 +340,7 @@ mod string_and_bytes { name: "String", len: 2, }, - Token::Str("type"), + Token::Str("tag"), Token::Str("String"), Token::Str("string"), Token::ByteBuf(b"\0"), @@ -358,7 +358,7 @@ mod string_and_bytes { name: "Bytes", len: 2, }, - Token::Str("type"), + Token::Str("tag"), Token::Str("Bytes"), Token::Str("bytes"), Token::Str("\0"), @@ -373,7 +373,7 @@ mod string_and_bytes { name: "Bytes", len: 2, }, - Token::Str("type"), + Token::Str("tag"), Token::Str("Bytes"), Token::Str("bytes"), Token::String("\0"), @@ -391,7 +391,7 @@ mod string_and_bytes { name: "Bytes", len: 2, }, - Token::Str("type"), + Token::Str("tag"), Token::Str("Bytes"), Token::Str("bytes"), Token::Bytes(b"\0"), @@ -406,7 +406,7 @@ mod string_and_bytes { name: "Bytes", len: 2, }, - Token::Str("type"), + Token::Str("tag"), Token::Str("Bytes"), Token::Str("bytes"), Token::ByteBuf(b"\0"), @@ -424,7 +424,7 @@ mod string_and_bytes { name: "Bytes", len: 2, }, - Token::Str("type"), + Token::Str("tag"), Token::Str("Bytes"), Token::Str("bytes"), Token::Seq { len: Some(1) }, @@ -444,7 +444,7 @@ fn struct_variant_containing_unit_variant() { } #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "action")] + #[serde(tag = "tag")] pub enum Message { Log { level: Level }, } @@ -465,7 +465,7 @@ fn struct_variant_containing_unit_variant() { name: "Message", len: 2, }, - Token::Str("action"), + Token::Str("tag"), Token::Str("Log"), Token::Str("level"), Token::Enum { name: "Level" }, @@ -479,7 +479,7 @@ fn struct_variant_containing_unit_variant() { &Message::Log { level: Level::Info }, &[ Token::Map { len: Some(2) }, - Token::Str("action"), + Token::Str("tag"), Token::Str("Log"), Token::Str("level"), Token::Enum { name: "Level" }, @@ -505,7 +505,7 @@ fn struct_variant_containing_unit_variant() { #[test] fn borrow() { #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "type")] + #[serde(tag = "tag")] enum Input<'a> { Package { name: &'a str }, } @@ -517,7 +517,7 @@ fn borrow() { name: "Input", len: 2, }, - Token::BorrowedStr("type"), + Token::BorrowedStr("tag"), Token::BorrowedStr("Package"), Token::BorrowedStr("name"), Token::BorrowedStr("borrowed"), @@ -529,7 +529,7 @@ fn borrow() { #[test] fn newtype_variant_containing_externally_tagged_enum() { #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "type")] + #[serde(tag = "tag")] enum Outer { Inner(Inner), } @@ -546,7 +546,7 @@ fn newtype_variant_containing_externally_tagged_enum() { &Outer::Inner(Inner::Unit), &[ Token::Map { len: Some(2) }, - Token::Str("type"), + Token::Str("tag"), Token::Str("Inner"), Token::Str("Unit"), Token::Unit, @@ -558,7 +558,7 @@ fn newtype_variant_containing_externally_tagged_enum() { &Outer::Inner(Inner::Newtype(1)), &[ Token::Map { len: Some(2) }, - Token::Str("type"), + Token::Str("tag"), Token::Str("Inner"), Token::Str("Newtype"), Token::U8(1), @@ -573,7 +573,7 @@ fn newtype_variant_containing_externally_tagged_enum() { &Outer::Inner(Inner::Tuple(1, 1)), &[ Token::Map { len: Some(2) }, - Token::Str("type"), + Token::Str("tag"), Token::Str("Inner"), Token::Str("Tuple"), Token::TupleStruct { @@ -594,7 +594,7 @@ fn newtype_variant_containing_externally_tagged_enum() { &Outer::Inner(Inner::Struct { f: 1 }), &[ Token::Map { len: Some(2) }, - Token::Str("type"), + Token::Str("tag"), Token::Str("Inner"), Token::Str("Struct"), Token::Struct { @@ -615,7 +615,7 @@ fn newtype_variant_containing_externally_tagged_enum() { &Outer::Inner(Inner::Struct { f: 1 }), &[ Token::Map { len: Some(2) }, - Token::Str("type"), + Token::Str("tag"), Token::Str("Inner"), Token::Str("Struct"), Token::Seq { len: Some(1) }, @@ -632,7 +632,7 @@ fn newtype_variant_containing_unit_struct() { struct Info; #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "topic")] + #[serde(tag = "tag")] enum Message { Info(Info), } @@ -641,7 +641,7 @@ fn newtype_variant_containing_unit_struct() { &Message::Info(Info), &[ Token::Map { len: Some(1) }, - Token::Str("topic"), + Token::Str("tag"), Token::Str("Info"), Token::MapEnd, ], @@ -654,7 +654,7 @@ fn newtype_variant_containing_unit_struct() { name: "Message", len: 1, }, - Token::Str("topic"), + Token::Str("tag"), Token::Str("Info"), Token::StructEnd, ], @@ -673,7 +673,7 @@ fn newtype_variant_containing_unit_struct() { #[test] fn with_skipped_conflict() { #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "t")] + #[serde(tag = "tag")] enum Data { A, #[serde(skip)] @@ -696,7 +696,7 @@ fn with_skipped_conflict() { name: "Data", len: 1, }, - Token::Str("t"), + Token::Str("tag"), Token::Str("C"), Token::StructEnd, ], @@ -706,7 +706,7 @@ fn with_skipped_conflict() { #[test] fn containing_flatten() { #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "t")] + #[serde(tag = "tag")] enum Data { A { a: i32, @@ -729,7 +729,7 @@ fn containing_flatten() { &data, &[ Token::Map { len: None }, - Token::Str("t"), + Token::Str("tag"), Token::Str("A"), Token::Str("a"), Token::I32(0), @@ -743,7 +743,7 @@ fn containing_flatten() { #[test] fn newtype_variant_containing_unit() { #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "t")] + #[serde(tag = "tag")] enum Data { A(()), } @@ -752,7 +752,7 @@ fn newtype_variant_containing_unit() { &Data::A(()), &[ Token::Map { len: Some(1) }, - Token::Str("t"), + Token::Str("tag"), Token::Str("A"), Token::MapEnd, ], @@ -762,7 +762,7 @@ fn newtype_variant_containing_unit() { #[test] fn unit_variant_with_unknown_fields() { #[derive(Debug, PartialEq, Deserialize)] - #[serde(tag = "t")] + #[serde(tag = "tag")] enum Data { A, } @@ -773,7 +773,7 @@ fn unit_variant_with_unknown_fields() { &data, &[ Token::Map { len: None }, - Token::Str("t"), + Token::Str("tag"), Token::Str("A"), Token::Str("b"), Token::I32(0), From f97160f715f743145ba61a4fb45db587651d3fe8 Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 7 Aug 2023 21:42:47 +0500 Subject: [PATCH 09/22] Reuse type in unit_variant_with_unknown_fields and add test for sequence --- .../tests/test_enum_internally_tagged.rs | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/test_suite/tests/test_enum_internally_tagged.rs b/test_suite/tests/test_enum_internally_tagged.rs index 63b2c437..b7ff4615 100644 --- a/test_suite/tests/test_enum_internally_tagged.rs +++ b/test_suite/tests/test_enum_internally_tagged.rs @@ -761,25 +761,30 @@ fn newtype_variant_containing_unit() { #[test] fn unit_variant_with_unknown_fields() { - #[derive(Debug, PartialEq, Deserialize)] - #[serde(tag = "tag")] - enum Data { - A, - } - - let data = Data::A; + let value = InternallyTagged::Unit; assert_de_tokens( - &data, + &value, &[ Token::Map { len: None }, Token::Str("tag"), - Token::Str("A"), + Token::Str("Unit"), Token::Str("b"), Token::I32(0), Token::MapEnd, ], ); + + // Unknown elements are not allowed in sequences + assert_de_tokens_error::( + &[ + Token::Seq { len: None }, + Token::Str("Unit"), + Token::I32(0), + Token::SeqEnd, + ], + "invalid length 1, expected 0 elements in sequence", + ); } #[test] From 2d75ef6b30c21022f457d673b2ed5a715c153515 Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 7 Aug 2023 21:47:55 +0500 Subject: [PATCH 10/22] Reuse type in newtype_variant_containing_unit --- .../tests/test_enum_internally_tagged.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/test_suite/tests/test_enum_internally_tagged.rs b/test_suite/tests/test_enum_internally_tagged.rs index b7ff4615..646b1454 100644 --- a/test_suite/tests/test_enum_internally_tagged.rs +++ b/test_suite/tests/test_enum_internally_tagged.rs @@ -24,6 +24,7 @@ struct Struct { #[serde(tag = "tag")] enum InternallyTagged { Unit, + NewtypeUnit(()), NewtypeNewtype(Newtype), NewtypeMap(BTreeMap), NewtypeStruct(Struct), @@ -162,7 +163,13 @@ fn wrong_tag() { Token::Str("Z"), Token::MapEnd, ], - "unknown variant `Z`, expected one of `Unit`, `NewtypeNewtype`, `NewtypeMap`, `NewtypeStruct`, `Struct`", + "unknown variant `Z`, expected one of \ + `Unit`, \ + `NewtypeUnit`, \ + `NewtypeNewtype`, \ + `NewtypeMap`, \ + `NewtypeStruct`, \ + `Struct`", ); } @@ -742,18 +749,14 @@ fn containing_flatten() { #[test] fn newtype_variant_containing_unit() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "tag")] - enum Data { - A(()), - } + let value = InternallyTagged::NewtypeUnit(()); assert_tokens( - &Data::A(()), + &value, &[ Token::Map { len: Some(1) }, Token::Str("tag"), - Token::Str("A"), + Token::Str("NewtypeUnit"), Token::MapEnd, ], ); From 93bda5f1dc7b3f6618f1eecbd62cff3c4790e5c3 Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 7 Aug 2023 21:35:02 +0500 Subject: [PATCH 11/22] Rename unit struct to a generic name: Info->Unit --- test_suite/tests/test_enum_internally_tagged.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test_suite/tests/test_enum_internally_tagged.rs b/test_suite/tests/test_enum_internally_tagged.rs index 646b1454..cdf0d4e5 100644 --- a/test_suite/tests/test_enum_internally_tagged.rs +++ b/test_suite/tests/test_enum_internally_tagged.rs @@ -636,16 +636,16 @@ fn newtype_variant_containing_externally_tagged_enum() { #[test] fn newtype_variant_containing_unit_struct() { #[derive(Debug, PartialEq, Serialize, Deserialize)] - struct Info; + struct Unit; #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(tag = "tag")] enum Message { - Info(Info), + Info(Unit), } assert_tokens( - &Message::Info(Info), + &Message::Info(Unit), &[ Token::Map { len: Some(1) }, Token::Str("tag"), @@ -655,7 +655,7 @@ fn newtype_variant_containing_unit_struct() { ); assert_de_tokens( - &Message::Info(Info), + &Message::Info(Unit), &[ Token::Struct { name: "Message", @@ -668,7 +668,7 @@ fn newtype_variant_containing_unit_struct() { ); assert_de_tokens( - &Message::Info(Info), + &Message::Info(Unit), &[ Token::Seq { len: Some(1) }, Token::Str("Info"), From 48de0c51b0e64cbc538ecf469554d36126803bc0 Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 7 Aug 2023 21:36:16 +0500 Subject: [PATCH 12/22] Share unit struct Unit between all tests --- test_suite/tests/test_enum_internally_tagged.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test_suite/tests/test_enum_internally_tagged.rs b/test_suite/tests/test_enum_internally_tagged.rs index cdf0d4e5..55069a5f 100644 --- a/test_suite/tests/test_enum_internally_tagged.rs +++ b/test_suite/tests/test_enum_internally_tagged.rs @@ -12,6 +12,9 @@ use serde_derive::{Deserialize, Serialize}; use serde_test::{assert_de_tokens, assert_de_tokens_error, assert_tokens, Token}; use std::collections::BTreeMap; +#[derive(Debug, PartialEq, Serialize, Deserialize)] +struct Unit; + #[derive(Debug, PartialEq, Serialize, Deserialize)] struct Newtype(BTreeMap); @@ -635,9 +638,6 @@ fn newtype_variant_containing_externally_tagged_enum() { #[test] fn newtype_variant_containing_unit_struct() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - struct Unit; - #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(tag = "tag")] enum Message { From d3492d8d36af377ac4d07637b82a95862ca26c68 Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 7 Aug 2023 21:53:32 +0500 Subject: [PATCH 13/22] Reuse type in newtype_variant_containing_unit_struct --- .../tests/test_enum_internally_tagged.rs | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/test_suite/tests/test_enum_internally_tagged.rs b/test_suite/tests/test_enum_internally_tagged.rs index 55069a5f..b7568b9a 100644 --- a/test_suite/tests/test_enum_internally_tagged.rs +++ b/test_suite/tests/test_enum_internally_tagged.rs @@ -28,6 +28,7 @@ struct Struct { enum InternallyTagged { Unit, NewtypeUnit(()), + NewtypeUnitStruct(Unit), NewtypeNewtype(Newtype), NewtypeMap(BTreeMap), NewtypeStruct(Struct), @@ -169,6 +170,7 @@ fn wrong_tag() { "unknown variant `Z`, expected one of \ `Unit`, \ `NewtypeUnit`, \ + `NewtypeUnitStruct`, \ `NewtypeNewtype`, \ `NewtypeMap`, \ `NewtypeStruct`, \ @@ -638,40 +640,36 @@ fn newtype_variant_containing_externally_tagged_enum() { #[test] fn newtype_variant_containing_unit_struct() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "tag")] - enum Message { - Info(Unit), - } + let value = InternallyTagged::NewtypeUnitStruct(Unit); assert_tokens( - &Message::Info(Unit), + &value, &[ Token::Map { len: Some(1) }, Token::Str("tag"), - Token::Str("Info"), + Token::Str("NewtypeUnitStruct"), Token::MapEnd, ], ); assert_de_tokens( - &Message::Info(Unit), + &value, &[ Token::Struct { - name: "Message", + name: "InternallyTagged", len: 1, }, Token::Str("tag"), - Token::Str("Info"), + Token::Str("NewtypeUnitStruct"), Token::StructEnd, ], ); assert_de_tokens( - &Message::Info(Unit), + &value, &[ Token::Seq { len: Some(1) }, - Token::Str("Info"), + Token::Str("NewtypeUnitStruct"), // tag Token::SeqEnd, ], ); From e999600f8f705b5969a71abe85e008c6b18f2370 Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 7 Aug 2023 21:20:28 +0500 Subject: [PATCH 14/22] Rename externally tagged enum Inner to Enum --- test_suite/tests/test_enum_internally_tagged.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test_suite/tests/test_enum_internally_tagged.rs b/test_suite/tests/test_enum_internally_tagged.rs index b7568b9a..cf39ebe3 100644 --- a/test_suite/tests/test_enum_internally_tagged.rs +++ b/test_suite/tests/test_enum_internally_tagged.rs @@ -543,11 +543,11 @@ fn newtype_variant_containing_externally_tagged_enum() { #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(tag = "tag")] enum Outer { - Inner(Inner), + Inner(Enum), } #[derive(Debug, PartialEq, Serialize, Deserialize)] - enum Inner { + enum Enum { Unit, Newtype(u8), Tuple(u8, u8), @@ -555,7 +555,7 @@ fn newtype_variant_containing_externally_tagged_enum() { } assert_tokens( - &Outer::Inner(Inner::Unit), + &Outer::Inner(Enum::Unit), &[ Token::Map { len: Some(2) }, Token::Str("tag"), @@ -567,7 +567,7 @@ fn newtype_variant_containing_externally_tagged_enum() { ); assert_tokens( - &Outer::Inner(Inner::Newtype(1)), + &Outer::Inner(Enum::Newtype(1)), &[ Token::Map { len: Some(2) }, Token::Str("tag"), @@ -582,7 +582,7 @@ fn newtype_variant_containing_externally_tagged_enum() { // Content::Seq case // via ContentDeserializer::deserialize_enum assert_tokens( - &Outer::Inner(Inner::Tuple(1, 1)), + &Outer::Inner(Enum::Tuple(1, 1)), &[ Token::Map { len: Some(2) }, Token::Str("tag"), @@ -603,7 +603,7 @@ fn newtype_variant_containing_externally_tagged_enum() { // Content::Map case // via ContentDeserializer::deserialize_enum assert_tokens( - &Outer::Inner(Inner::Struct { f: 1 }), + &Outer::Inner(Enum::Struct { f: 1 }), &[ Token::Map { len: Some(2) }, Token::Str("tag"), @@ -624,7 +624,7 @@ fn newtype_variant_containing_externally_tagged_enum() { // Content::Seq case // via ContentDeserializer::deserialize_enum assert_de_tokens( - &Outer::Inner(Inner::Struct { f: 1 }), + &Outer::Inner(Enum::Struct { f: 1 }), &[ Token::Map { len: Some(2) }, Token::Str("tag"), From 28a775db22e66c85c2b1410e23e212a4f345b63c Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 7 Aug 2023 21:30:37 +0500 Subject: [PATCH 15/22] Share externally tagged enum Enum between all tests and reuse in struct_variant_containing_unit_variant --- .../tests/test_enum_internally_tagged.rs | 51 +++++++++---------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/test_suite/tests/test_enum_internally_tagged.rs b/test_suite/tests/test_enum_internally_tagged.rs index cf39ebe3..e7beae0b 100644 --- a/test_suite/tests/test_enum_internally_tagged.rs +++ b/test_suite/tests/test_enum_internally_tagged.rs @@ -23,6 +23,14 @@ struct Struct { f: u8, } +#[derive(Debug, PartialEq, Serialize, Deserialize)] +enum Enum { + Unit, + Newtype(u8), + Tuple(u8, u8), + Struct { f: u8 }, +} + #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(tag = "tag")] enum InternallyTagged { @@ -450,28 +458,25 @@ mod string_and_bytes { #[test] fn struct_variant_containing_unit_variant() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - pub enum Level { - Info, - } - #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(tag = "tag")] - pub enum Message { - Log { level: Level }, + enum Message { + Log { level: Enum }, } assert_de_tokens( - &Level::Info, + &Enum::Unit, &[ - Token::Enum { name: "Level" }, - Token::BorrowedStr("Info"), + Token::Enum { name: "Enum" }, + Token::BorrowedStr("Unit"), Token::Unit, ], ); + let value = Message::Log { level: Enum::Unit }; + assert_de_tokens( - &Message::Log { level: Level::Info }, + &value, &[ Token::Struct { name: "Message", @@ -480,34 +485,34 @@ fn struct_variant_containing_unit_variant() { Token::Str("tag"), Token::Str("Log"), Token::Str("level"), - Token::Enum { name: "Level" }, - Token::BorrowedStr("Info"), + Token::Enum { name: "Enum" }, + Token::BorrowedStr("Unit"), Token::Unit, Token::StructEnd, ], ); assert_de_tokens( - &Message::Log { level: Level::Info }, + &value, &[ Token::Map { len: Some(2) }, Token::Str("tag"), Token::Str("Log"), Token::Str("level"), - Token::Enum { name: "Level" }, - Token::BorrowedStr("Info"), + Token::Enum { name: "Enum" }, + Token::BorrowedStr("Unit"), Token::Unit, Token::MapEnd, ], ); assert_de_tokens( - &Message::Log { level: Level::Info }, + &value, &[ Token::Seq { len: Some(2) }, Token::Str("Log"), - Token::Enum { name: "Level" }, - Token::BorrowedStr("Info"), + Token::Enum { name: "Enum" }, + Token::BorrowedStr("Unit"), Token::Unit, Token::SeqEnd, ], @@ -546,14 +551,6 @@ fn newtype_variant_containing_externally_tagged_enum() { Inner(Enum), } - #[derive(Debug, PartialEq, Serialize, Deserialize)] - enum Enum { - Unit, - Newtype(u8), - Tuple(u8, u8), - Struct { f: u8 }, - } - assert_tokens( &Outer::Inner(Enum::Unit), &[ From 41b9c33c2bb8dfa8731cfe8318290719cc5404be Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 7 Aug 2023 21:58:50 +0500 Subject: [PATCH 16/22] Reuse type in newtype_variant_containing_externally_tagged_enum --- .../tests/test_enum_internally_tagged.rs | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/test_suite/tests/test_enum_internally_tagged.rs b/test_suite/tests/test_enum_internally_tagged.rs index e7beae0b..904985d3 100644 --- a/test_suite/tests/test_enum_internally_tagged.rs +++ b/test_suite/tests/test_enum_internally_tagged.rs @@ -40,6 +40,7 @@ enum InternallyTagged { NewtypeNewtype(Newtype), NewtypeMap(BTreeMap), NewtypeStruct(Struct), + NewtypeEnum(Enum), Struct { a: u8 }, } @@ -182,6 +183,7 @@ fn wrong_tag() { `NewtypeNewtype`, \ `NewtypeMap`, \ `NewtypeStruct`, \ + `NewtypeEnum`, \ `Struct`", ); } @@ -545,18 +547,12 @@ fn borrow() { #[test] fn newtype_variant_containing_externally_tagged_enum() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "tag")] - enum Outer { - Inner(Enum), - } - assert_tokens( - &Outer::Inner(Enum::Unit), + &InternallyTagged::NewtypeEnum(Enum::Unit), &[ Token::Map { len: Some(2) }, Token::Str("tag"), - Token::Str("Inner"), + Token::Str("NewtypeEnum"), Token::Str("Unit"), Token::Unit, Token::MapEnd, @@ -564,11 +560,11 @@ fn newtype_variant_containing_externally_tagged_enum() { ); assert_tokens( - &Outer::Inner(Enum::Newtype(1)), + &InternallyTagged::NewtypeEnum(Enum::Newtype(1)), &[ Token::Map { len: Some(2) }, Token::Str("tag"), - Token::Str("Inner"), + Token::Str("NewtypeEnum"), Token::Str("Newtype"), Token::U8(1), Token::MapEnd, @@ -579,11 +575,11 @@ fn newtype_variant_containing_externally_tagged_enum() { // Content::Seq case // via ContentDeserializer::deserialize_enum assert_tokens( - &Outer::Inner(Enum::Tuple(1, 1)), + &InternallyTagged::NewtypeEnum(Enum::Tuple(1, 1)), &[ Token::Map { len: Some(2) }, Token::Str("tag"), - Token::Str("Inner"), + Token::Str("NewtypeEnum"), Token::Str("Tuple"), Token::TupleStruct { name: "Tuple", @@ -600,11 +596,11 @@ fn newtype_variant_containing_externally_tagged_enum() { // Content::Map case // via ContentDeserializer::deserialize_enum assert_tokens( - &Outer::Inner(Enum::Struct { f: 1 }), + &InternallyTagged::NewtypeEnum(Enum::Struct { f: 1 }), &[ Token::Map { len: Some(2) }, Token::Str("tag"), - Token::Str("Inner"), + Token::Str("NewtypeEnum"), Token::Str("Struct"), Token::Struct { name: "Struct", @@ -621,11 +617,11 @@ fn newtype_variant_containing_externally_tagged_enum() { // Content::Seq case // via ContentDeserializer::deserialize_enum assert_de_tokens( - &Outer::Inner(Enum::Struct { f: 1 }), + &InternallyTagged::NewtypeEnum(Enum::Struct { f: 1 }), &[ Token::Map { len: Some(2) }, Token::Str("tag"), - Token::Str("Inner"), + Token::Str("NewtypeEnum"), Token::Str("Struct"), Token::Seq { len: Some(1) }, Token::U8(1), // f From 7c0e6bd18f28eb15c622f7d3bb08a119ffe26929 Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 7 Aug 2023 22:55:35 +0500 Subject: [PATCH 17/22] Reuse type in struct_variant_containing_unit_variant --- .../tests/test_enum_internally_tagged.rs | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/test_suite/tests/test_enum_internally_tagged.rs b/test_suite/tests/test_enum_internally_tagged.rs index 904985d3..900a9b33 100644 --- a/test_suite/tests/test_enum_internally_tagged.rs +++ b/test_suite/tests/test_enum_internally_tagged.rs @@ -42,6 +42,7 @@ enum InternallyTagged { NewtypeStruct(Struct), NewtypeEnum(Enum), Struct { a: u8 }, + StructEnum { enum_: Enum }, } #[test] @@ -184,7 +185,8 @@ fn wrong_tag() { `NewtypeMap`, \ `NewtypeStruct`, \ `NewtypeEnum`, \ - `Struct`", + `Struct`, \ + `StructEnum`", ); } @@ -460,12 +462,6 @@ mod string_and_bytes { #[test] fn struct_variant_containing_unit_variant() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - #[serde(tag = "tag")] - enum Message { - Log { level: Enum }, - } - assert_de_tokens( &Enum::Unit, &[ @@ -475,18 +471,18 @@ fn struct_variant_containing_unit_variant() { ], ); - let value = Message::Log { level: Enum::Unit }; + let value = InternallyTagged::StructEnum { enum_: Enum::Unit }; assert_de_tokens( &value, &[ Token::Struct { - name: "Message", + name: "InternallyTagged", len: 2, }, Token::Str("tag"), - Token::Str("Log"), - Token::Str("level"), + Token::Str("StructEnum"), + Token::Str("enum_"), Token::Enum { name: "Enum" }, Token::BorrowedStr("Unit"), Token::Unit, @@ -499,8 +495,8 @@ fn struct_variant_containing_unit_variant() { &[ Token::Map { len: Some(2) }, Token::Str("tag"), - Token::Str("Log"), - Token::Str("level"), + Token::Str("StructEnum"), + Token::Str("enum_"), Token::Enum { name: "Enum" }, Token::BorrowedStr("Unit"), Token::Unit, @@ -512,8 +508,8 @@ fn struct_variant_containing_unit_variant() { &value, &[ Token::Seq { len: Some(2) }, - Token::Str("Log"), - Token::Enum { name: "Enum" }, + Token::Str("StructEnum"), // tag + Token::Enum { name: "Enum" }, // enum_ Token::BorrowedStr("Unit"), Token::Unit, Token::SeqEnd, From 8bfe0d0ac04e01b9fd3658c5707c62da651d3770 Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 7 Aug 2023 22:51:46 +0500 Subject: [PATCH 18/22] Move and rename tests: - newtype_variant_containing_unit -> newtype_unit - newtype_variant_containing_unit_struct -> newtype_unit_struct - newtype_variant_containing_externally_tagged_enum -> newtype_enum - struct_variant_containing_unit_variant -> struct_enum --- .../tests/test_enum_internally_tagged.rs | 390 +++++++++--------- 1 file changed, 195 insertions(+), 195 deletions(-) diff --git a/test_suite/tests/test_enum_internally_tagged.rs b/test_suite/tests/test_enum_internally_tagged.rs index 900a9b33..91607605 100644 --- a/test_suite/tests/test_enum_internally_tagged.rs +++ b/test_suite/tests/test_enum_internally_tagged.rs @@ -70,6 +70,58 @@ fn unit() { ); } +#[test] +fn newtype_unit() { + let value = InternallyTagged::NewtypeUnit(()); + + assert_tokens( + &value, + &[ + Token::Map { len: Some(1) }, + Token::Str("tag"), + Token::Str("NewtypeUnit"), + Token::MapEnd, + ], + ); +} + +#[test] +fn newtype_unit_struct() { + let value = InternallyTagged::NewtypeUnitStruct(Unit); + + assert_tokens( + &value, + &[ + Token::Map { len: Some(1) }, + Token::Str("tag"), + Token::Str("NewtypeUnitStruct"), + Token::MapEnd, + ], + ); + + assert_de_tokens( + &value, + &[ + Token::Struct { + name: "InternallyTagged", + len: 1, + }, + Token::Str("tag"), + Token::Str("NewtypeUnitStruct"), + Token::StructEnd, + ], + ); + + assert_de_tokens( + &value, + &[ + Token::Seq { len: Some(1) }, + Token::Str("NewtypeUnitStruct"), // tag + Token::SeqEnd, + ], + ); +} + #[test] fn newtype_newtype() { assert_tokens( @@ -135,6 +187,92 @@ fn newtype_struct() { ); } +#[test] +fn newtype_enum() { + assert_tokens( + &InternallyTagged::NewtypeEnum(Enum::Unit), + &[ + Token::Map { len: Some(2) }, + Token::Str("tag"), + Token::Str("NewtypeEnum"), + Token::Str("Unit"), + Token::Unit, + Token::MapEnd, + ], + ); + + assert_tokens( + &InternallyTagged::NewtypeEnum(Enum::Newtype(1)), + &[ + Token::Map { len: Some(2) }, + Token::Str("tag"), + Token::Str("NewtypeEnum"), + Token::Str("Newtype"), + Token::U8(1), + Token::MapEnd, + ], + ); + + // Reaches crate::private::de::content::VariantDeserializer::tuple_variant + // Content::Seq case + // via ContentDeserializer::deserialize_enum + assert_tokens( + &InternallyTagged::NewtypeEnum(Enum::Tuple(1, 1)), + &[ + Token::Map { len: Some(2) }, + Token::Str("tag"), + Token::Str("NewtypeEnum"), + Token::Str("Tuple"), + Token::TupleStruct { + name: "Tuple", + len: 2, + }, + Token::U8(1), + Token::U8(1), + Token::TupleStructEnd, + Token::MapEnd, + ], + ); + + // Reaches crate::private::de::content::VariantDeserializer::struct_variant + // Content::Map case + // via ContentDeserializer::deserialize_enum + assert_tokens( + &InternallyTagged::NewtypeEnum(Enum::Struct { f: 1 }), + &[ + Token::Map { len: Some(2) }, + Token::Str("tag"), + Token::Str("NewtypeEnum"), + Token::Str("Struct"), + Token::Struct { + name: "Struct", + len: 1, + }, + Token::Str("f"), + Token::U8(1), + Token::StructEnd, + Token::MapEnd, + ], + ); + + // Reaches crate::private::de::content::VariantDeserializer::struct_variant + // Content::Seq case + // via ContentDeserializer::deserialize_enum + assert_de_tokens( + &InternallyTagged::NewtypeEnum(Enum::Struct { f: 1 }), + &[ + Token::Map { len: Some(2) }, + Token::Str("tag"), + Token::Str("NewtypeEnum"), + Token::Str("Struct"), + Token::Seq { len: Some(1) }, + Token::U8(1), // f + Token::SeqEnd, + Token::MapEnd, + ], + ); +} + #[test] fn struct_() { assert_tokens( @@ -163,6 +301,63 @@ fn struct_() { ); } +#[test] +fn struct_enum() { + assert_de_tokens( + &Enum::Unit, + &[ + Token::Enum { name: "Enum" }, + Token::BorrowedStr("Unit"), + Token::Unit, + ], + ); + + let value = InternallyTagged::StructEnum { enum_: Enum::Unit }; + + assert_de_tokens( + &value, + &[ + Token::Struct { + name: "InternallyTagged", + len: 2, + }, + Token::Str("tag"), + Token::Str("StructEnum"), + Token::Str("enum_"), + Token::Enum { name: "Enum" }, + Token::BorrowedStr("Unit"), + Token::Unit, + Token::StructEnd, + ], + ); + + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::Str("tag"), + Token::Str("StructEnum"), + Token::Str("enum_"), + Token::Enum { name: "Enum" }, + Token::BorrowedStr("Unit"), + Token::Unit, + Token::MapEnd, + ], + ); + + assert_de_tokens( + &value, + &[ + Token::Seq { len: Some(2) }, + Token::Str("StructEnum"), // tag + Token::Enum { name: "Enum" }, // enum_ + Token::BorrowedStr("Unit"), + Token::Unit, + Token::SeqEnd, + ], + ); +} + #[test] fn wrong_tag() { assert_de_tokens_error::( @@ -460,63 +655,6 @@ mod string_and_bytes { } } -#[test] -fn struct_variant_containing_unit_variant() { - assert_de_tokens( - &Enum::Unit, - &[ - Token::Enum { name: "Enum" }, - Token::BorrowedStr("Unit"), - Token::Unit, - ], - ); - - let value = InternallyTagged::StructEnum { enum_: Enum::Unit }; - - assert_de_tokens( - &value, - &[ - Token::Struct { - name: "InternallyTagged", - len: 2, - }, - Token::Str("tag"), - Token::Str("StructEnum"), - Token::Str("enum_"), - Token::Enum { name: "Enum" }, - Token::BorrowedStr("Unit"), - Token::Unit, - Token::StructEnd, - ], - ); - - assert_de_tokens( - &value, - &[ - Token::Map { len: Some(2) }, - Token::Str("tag"), - Token::Str("StructEnum"), - Token::Str("enum_"), - Token::Enum { name: "Enum" }, - Token::BorrowedStr("Unit"), - Token::Unit, - Token::MapEnd, - ], - ); - - assert_de_tokens( - &value, - &[ - Token::Seq { len: Some(2) }, - Token::Str("StructEnum"), // tag - Token::Enum { name: "Enum" }, // enum_ - Token::BorrowedStr("Unit"), - Token::Unit, - Token::SeqEnd, - ], - ); -} - #[test] fn borrow() { #[derive(Debug, PartialEq, Serialize, Deserialize)] @@ -541,129 +679,6 @@ fn borrow() { ); } -#[test] -fn newtype_variant_containing_externally_tagged_enum() { - assert_tokens( - &InternallyTagged::NewtypeEnum(Enum::Unit), - &[ - Token::Map { len: Some(2) }, - Token::Str("tag"), - Token::Str("NewtypeEnum"), - Token::Str("Unit"), - Token::Unit, - Token::MapEnd, - ], - ); - - assert_tokens( - &InternallyTagged::NewtypeEnum(Enum::Newtype(1)), - &[ - Token::Map { len: Some(2) }, - Token::Str("tag"), - Token::Str("NewtypeEnum"), - Token::Str("Newtype"), - Token::U8(1), - Token::MapEnd, - ], - ); - - // Reaches crate::private::de::content::VariantDeserializer::tuple_variant - // Content::Seq case - // via ContentDeserializer::deserialize_enum - assert_tokens( - &InternallyTagged::NewtypeEnum(Enum::Tuple(1, 1)), - &[ - Token::Map { len: Some(2) }, - Token::Str("tag"), - Token::Str("NewtypeEnum"), - Token::Str("Tuple"), - Token::TupleStruct { - name: "Tuple", - len: 2, - }, - Token::U8(1), - Token::U8(1), - Token::TupleStructEnd, - Token::MapEnd, - ], - ); - - // Reaches crate::private::de::content::VariantDeserializer::struct_variant - // Content::Map case - // via ContentDeserializer::deserialize_enum - assert_tokens( - &InternallyTagged::NewtypeEnum(Enum::Struct { f: 1 }), - &[ - Token::Map { len: Some(2) }, - Token::Str("tag"), - Token::Str("NewtypeEnum"), - Token::Str("Struct"), - Token::Struct { - name: "Struct", - len: 1, - }, - Token::Str("f"), - Token::U8(1), - Token::StructEnd, - Token::MapEnd, - ], - ); - - // Reaches crate::private::de::content::VariantDeserializer::struct_variant - // Content::Seq case - // via ContentDeserializer::deserialize_enum - assert_de_tokens( - &InternallyTagged::NewtypeEnum(Enum::Struct { f: 1 }), - &[ - Token::Map { len: Some(2) }, - Token::Str("tag"), - Token::Str("NewtypeEnum"), - Token::Str("Struct"), - Token::Seq { len: Some(1) }, - Token::U8(1), // f - Token::SeqEnd, - Token::MapEnd, - ], - ); -} - -#[test] -fn newtype_variant_containing_unit_struct() { - let value = InternallyTagged::NewtypeUnitStruct(Unit); - - assert_tokens( - &value, - &[ - Token::Map { len: Some(1) }, - Token::Str("tag"), - Token::Str("NewtypeUnitStruct"), - Token::MapEnd, - ], - ); - - assert_de_tokens( - &value, - &[ - Token::Struct { - name: "InternallyTagged", - len: 1, - }, - Token::Str("tag"), - Token::Str("NewtypeUnitStruct"), - Token::StructEnd, - ], - ); - - assert_de_tokens( - &value, - &[ - Token::Seq { len: Some(1) }, - Token::Str("NewtypeUnitStruct"), // tag - Token::SeqEnd, - ], - ); -} - #[test] fn with_skipped_conflict() { #[derive(Debug, PartialEq, Serialize, Deserialize)] @@ -734,21 +749,6 @@ fn containing_flatten() { ); } -#[test] -fn newtype_variant_containing_unit() { - let value = InternallyTagged::NewtypeUnit(()); - - assert_tokens( - &value, - &[ - Token::Map { len: Some(1) }, - Token::Str("tag"), - Token::Str("NewtypeUnit"), - Token::MapEnd, - ], - ); -} - #[test] fn unit_variant_with_unknown_fields() { let value = InternallyTagged::Unit; From 4987fd15f7bf26c5c7809fd772a218e8782a6d59 Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 8 Aug 2023 00:54:36 +0500 Subject: [PATCH 19/22] Convert newtype_enum and struct_enum tests into modules Separate testing each variant kind of enum (unit, newtype, tuple, struct) results in more specific information if that checks fail (review this commit with "ignore whitespace changes" option on) --- .../tests/test_enum_internally_tagged.rs | 279 ++++++++++-------- 1 file changed, 148 insertions(+), 131 deletions(-) diff --git a/test_suite/tests/test_enum_internally_tagged.rs b/test_suite/tests/test_enum_internally_tagged.rs index 91607605..38c8dc61 100644 --- a/test_suite/tests/test_enum_internally_tagged.rs +++ b/test_suite/tests/test_enum_internally_tagged.rs @@ -187,90 +187,103 @@ fn newtype_struct() { ); } -#[test] -fn newtype_enum() { - assert_tokens( - &InternallyTagged::NewtypeEnum(Enum::Unit), - &[ - Token::Map { len: Some(2) }, - Token::Str("tag"), - Token::Str("NewtypeEnum"), - Token::Str("Unit"), - Token::Unit, - Token::MapEnd, - ], - ); +mod newtype_enum { + use super::*; - assert_tokens( - &InternallyTagged::NewtypeEnum(Enum::Newtype(1)), - &[ - Token::Map { len: Some(2) }, - Token::Str("tag"), - Token::Str("NewtypeEnum"), - Token::Str("Newtype"), - Token::U8(1), - Token::MapEnd, - ], - ); + #[test] + fn unit() { + assert_tokens( + &InternallyTagged::NewtypeEnum(Enum::Unit), + &[ + Token::Map { len: Some(2) }, + Token::Str("tag"), + Token::Str("NewtypeEnum"), + Token::Str("Unit"), + Token::Unit, + Token::MapEnd, + ], + ); + } - // Reaches crate::private::de::content::VariantDeserializer::tuple_variant - // Content::Seq case - // via ContentDeserializer::deserialize_enum - assert_tokens( - &InternallyTagged::NewtypeEnum(Enum::Tuple(1, 1)), - &[ - Token::Map { len: Some(2) }, - Token::Str("tag"), - Token::Str("NewtypeEnum"), - Token::Str("Tuple"), - Token::TupleStruct { - name: "Tuple", - len: 2, - }, - Token::U8(1), - Token::U8(1), - Token::TupleStructEnd, - Token::MapEnd, - ], - ); + #[test] + fn newtype() { + assert_tokens( + &InternallyTagged::NewtypeEnum(Enum::Newtype(1)), + &[ + Token::Map { len: Some(2) }, + Token::Str("tag"), + Token::Str("NewtypeEnum"), + Token::Str("Newtype"), + Token::U8(1), + Token::MapEnd, + ], + ); + } - // Reaches crate::private::de::content::VariantDeserializer::struct_variant - // Content::Map case - // via ContentDeserializer::deserialize_enum - assert_tokens( - &InternallyTagged::NewtypeEnum(Enum::Struct { f: 1 }), - &[ - Token::Map { len: Some(2) }, - Token::Str("tag"), - Token::Str("NewtypeEnum"), - Token::Str("Struct"), - Token::Struct { - name: "Struct", - len: 1, - }, - Token::Str("f"), - Token::U8(1), - Token::StructEnd, - Token::MapEnd, - ], - ); + #[test] + fn tuple() { + // Reaches crate::private::de::content::VariantDeserializer::tuple_variant + // Content::Seq case + // via ContentDeserializer::deserialize_enum + assert_tokens( + &InternallyTagged::NewtypeEnum(Enum::Tuple(1, 1)), + &[ + Token::Map { len: Some(2) }, + Token::Str("tag"), + Token::Str("NewtypeEnum"), + Token::Str("Tuple"), + Token::TupleStruct { + name: "Tuple", + len: 2, + }, + Token::U8(1), + Token::U8(1), + Token::TupleStructEnd, + Token::MapEnd, + ], + ); + } - // Reaches crate::private::de::content::VariantDeserializer::struct_variant - // Content::Seq case - // via ContentDeserializer::deserialize_enum - assert_de_tokens( - &InternallyTagged::NewtypeEnum(Enum::Struct { f: 1 }), - &[ - Token::Map { len: Some(2) }, - Token::Str("tag"), - Token::Str("NewtypeEnum"), - Token::Str("Struct"), - Token::Seq { len: Some(1) }, - Token::U8(1), // f - Token::SeqEnd, - Token::MapEnd, - ], - ); + #[test] + fn struct_() { + // Reaches crate::private::de::content::VariantDeserializer::struct_variant + // Content::Map case + // via ContentDeserializer::deserialize_enum + assert_tokens( + &InternallyTagged::NewtypeEnum(Enum::Struct { f: 1 }), + &[ + Token::Map { len: Some(2) }, + Token::Str("tag"), + Token::Str("NewtypeEnum"), + Token::Str("Struct"), + Token::Struct { + name: "Struct", + len: 1, + }, + Token::Str("f"), + Token::U8(1), + Token::StructEnd, + Token::MapEnd, + ], + ); + + // Reaches crate::private::de::content::VariantDeserializer::struct_variant + // Content::Seq case + // via ContentDeserializer::deserialize_enum + assert_de_tokens( + &InternallyTagged::NewtypeEnum(Enum::Struct { f: 1 }), + &[ + Token::Map { len: Some(2) }, + Token::Str("tag"), + Token::Str("NewtypeEnum"), + Token::Str("Struct"), + Token::Seq { len: Some(1) }, + Token::U8(1), // f + Token::SeqEnd, + Token::MapEnd, + ], + ); + } } #[test] @@ -301,61 +314,65 @@ fn struct_() { ); } -#[test] -fn struct_enum() { - assert_de_tokens( - &Enum::Unit, - &[ - Token::Enum { name: "Enum" }, - Token::BorrowedStr("Unit"), - Token::Unit, - ], - ); +mod struct_enum { + use super::*; - let value = InternallyTagged::StructEnum { enum_: Enum::Unit }; + #[test] + fn unit() { + assert_de_tokens( + &Enum::Unit, + &[ + Token::Enum { name: "Enum" }, + Token::BorrowedStr("Unit"), + Token::Unit, + ], + ); - assert_de_tokens( - &value, - &[ - Token::Struct { - name: "InternallyTagged", - len: 2, - }, - Token::Str("tag"), - Token::Str("StructEnum"), - Token::Str("enum_"), - Token::Enum { name: "Enum" }, - Token::BorrowedStr("Unit"), - Token::Unit, - Token::StructEnd, - ], - ); + let value = InternallyTagged::StructEnum { enum_: Enum::Unit }; - assert_de_tokens( - &value, - &[ - Token::Map { len: Some(2) }, - Token::Str("tag"), - Token::Str("StructEnum"), - Token::Str("enum_"), - Token::Enum { name: "Enum" }, - Token::BorrowedStr("Unit"), - Token::Unit, - Token::MapEnd, - ], - ); + assert_de_tokens( + &value, + &[ + Token::Struct { + name: "InternallyTagged", + len: 2, + }, + Token::Str("tag"), + Token::Str("StructEnum"), + Token::Str("enum_"), + Token::Enum { name: "Enum" }, + Token::BorrowedStr("Unit"), + Token::Unit, + Token::StructEnd, + ], + ); - assert_de_tokens( - &value, - &[ - Token::Seq { len: Some(2) }, - Token::Str("StructEnum"), // tag - Token::Enum { name: "Enum" }, // enum_ - Token::BorrowedStr("Unit"), - Token::Unit, - Token::SeqEnd, - ], - ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::Str("tag"), + Token::Str("StructEnum"), + Token::Str("enum_"), + Token::Enum { name: "Enum" }, + Token::BorrowedStr("Unit"), + Token::Unit, + Token::MapEnd, + ], + ); + + assert_de_tokens( + &value, + &[ + Token::Seq { len: Some(2) }, + Token::Str("StructEnum"), // tag + Token::Enum { name: "Enum" }, // enum_ + Token::BorrowedStr("Unit"), + Token::Unit, + Token::SeqEnd, + ], + ); + } } #[test] From 47954502af93d856aca1fb92d8fecb931e469ff1 Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 8 Aug 2023 01:20:15 +0500 Subject: [PATCH 20/22] Add tests with borrowed strings for the tag field name and tag value --- .../tests/test_enum_internally_tagged.rs | 268 ++++++++++++++++-- 1 file changed, 252 insertions(+), 16 deletions(-) diff --git a/test_suite/tests/test_enum_internally_tagged.rs b/test_suite/tests/test_enum_internally_tagged.rs index 38c8dc61..4c800256 100644 --- a/test_suite/tests/test_enum_internally_tagged.rs +++ b/test_suite/tests/test_enum_internally_tagged.rs @@ -59,12 +59,32 @@ fn unit() { Token::StructEnd, ], ); + assert_de_tokens( + &InternallyTagged::Unit, + &[ + Token::Struct { + name: "InternallyTagged", + len: 1, + }, + Token::BorrowedStr("tag"), + Token::BorrowedStr("Unit"), + Token::StructEnd, + ], + ); assert_de_tokens( &InternallyTagged::Unit, &[ Token::Seq { len: Some(1) }, - Token::Str("Unit"), + Token::Str("Unit"), // tag + Token::SeqEnd, + ], + ); + assert_de_tokens( + &InternallyTagged::Unit, + &[ + Token::Seq { len: Some(1) }, + Token::BorrowedStr("Unit"), // tag Token::SeqEnd, ], ); @@ -83,6 +103,15 @@ fn newtype_unit() { Token::MapEnd, ], ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(1) }, + Token::BorrowedStr("tag"), + Token::BorrowedStr("NewtypeUnit"), + Token::MapEnd, + ], + ); } #[test] @@ -98,6 +127,15 @@ fn newtype_unit_struct() { Token::MapEnd, ], ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(1) }, + Token::BorrowedStr("tag"), + Token::BorrowedStr("NewtypeUnitStruct"), + Token::MapEnd, + ], + ); assert_de_tokens( &value, @@ -111,6 +149,18 @@ fn newtype_unit_struct() { Token::StructEnd, ], ); + assert_de_tokens( + &value, + &[ + Token::Struct { + name: "InternallyTagged", + len: 1, + }, + Token::BorrowedStr("tag"), + Token::BorrowedStr("NewtypeUnitStruct"), + Token::StructEnd, + ], + ); assert_de_tokens( &value, @@ -120,6 +170,14 @@ fn newtype_unit_struct() { Token::SeqEnd, ], ); + assert_de_tokens( + &value, + &[ + Token::Seq { len: Some(1) }, + Token::BorrowedStr("NewtypeUnitStruct"), // tag + Token::SeqEnd, + ], + ); } #[test] @@ -137,8 +195,10 @@ fn newtype_newtype() { #[test] fn newtype_map() { + let value = InternallyTagged::NewtypeMap(BTreeMap::new()); + assert_tokens( - &InternallyTagged::NewtypeMap(BTreeMap::new()), + &value, &[ Token::Map { len: Some(1) }, Token::Str("tag"), @@ -146,11 +206,20 @@ fn newtype_map() { Token::MapEnd, ], ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(1) }, + Token::BorrowedStr("tag"), + Token::BorrowedStr("NewtypeMap"), + Token::MapEnd, + ], + ); assert_de_tokens_error::( &[ Token::Seq { len: Some(2) }, - Token::Str("NewtypeMap"), + Token::Str("NewtypeMap"), // tag Token::Map { len: Some(0) }, Token::MapEnd, Token::SeqEnd, @@ -161,8 +230,10 @@ fn newtype_map() { #[test] fn newtype_struct() { + let value = InternallyTagged::NewtypeStruct(Struct { f: 6 }); + assert_tokens( - &InternallyTagged::NewtypeStruct(Struct { f: 6 }), + &value, &[ Token::Struct { name: "Struct", @@ -175,12 +246,35 @@ fn newtype_struct() { Token::StructEnd, ], ); + assert_de_tokens( + &value, + &[ + Token::Struct { + name: "Struct", + len: 2, + }, + Token::BorrowedStr("tag"), + Token::BorrowedStr("NewtypeStruct"), + Token::BorrowedStr("f"), + Token::U8(6), + Token::StructEnd, + ], + ); assert_de_tokens( - &InternallyTagged::NewtypeStruct(Struct { f: 6 }), + &value, &[ Token::Seq { len: Some(2) }, - Token::Str("NewtypeStruct"), + Token::Str("NewtypeStruct"), // tag + Token::U8(6), + Token::SeqEnd, + ], + ); + assert_de_tokens( + &value, + &[ + Token::Seq { len: Some(2) }, + Token::BorrowedStr("NewtypeStruct"), // tag Token::U8(6), Token::SeqEnd, ], @@ -192,8 +286,10 @@ mod newtype_enum { #[test] fn unit() { + let value = InternallyTagged::NewtypeEnum(Enum::Unit); + assert_tokens( - &InternallyTagged::NewtypeEnum(Enum::Unit), + &value, &[ Token::Map { len: Some(2) }, Token::Str("tag"), @@ -203,12 +299,25 @@ mod newtype_enum { Token::MapEnd, ], ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::BorrowedStr("tag"), + Token::BorrowedStr("NewtypeEnum"), + Token::BorrowedStr("Unit"), + Token::Unit, + Token::MapEnd, + ], + ); } #[test] fn newtype() { + let value = InternallyTagged::NewtypeEnum(Enum::Newtype(1)); + assert_tokens( - &InternallyTagged::NewtypeEnum(Enum::Newtype(1)), + &value, &[ Token::Map { len: Some(2) }, Token::Str("tag"), @@ -218,15 +327,28 @@ mod newtype_enum { Token::MapEnd, ], ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::BorrowedStr("tag"), + Token::BorrowedStr("NewtypeEnum"), + Token::BorrowedStr("Newtype"), + Token::U8(1), + Token::MapEnd, + ], + ); } #[test] fn tuple() { + let value = InternallyTagged::NewtypeEnum(Enum::Tuple(1, 1)); + // Reaches crate::private::de::content::VariantDeserializer::tuple_variant // Content::Seq case // via ContentDeserializer::deserialize_enum assert_tokens( - &InternallyTagged::NewtypeEnum(Enum::Tuple(1, 1)), + &value, &[ Token::Map { len: Some(2) }, Token::Str("tag"), @@ -242,15 +364,34 @@ mod newtype_enum { Token::MapEnd, ], ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::BorrowedStr("tag"), + Token::BorrowedStr("NewtypeEnum"), + Token::BorrowedStr("Tuple"), + Token::TupleStruct { + name: "Tuple", + len: 2, + }, + Token::U8(1), + Token::U8(1), + Token::TupleStructEnd, + Token::MapEnd, + ], + ); } #[test] fn struct_() { + let value = InternallyTagged::NewtypeEnum(Enum::Struct { f: 1 }); + // Reaches crate::private::de::content::VariantDeserializer::struct_variant // Content::Map case // via ContentDeserializer::deserialize_enum assert_tokens( - &InternallyTagged::NewtypeEnum(Enum::Struct { f: 1 }), + &value, &[ Token::Map { len: Some(2) }, Token::Str("tag"), @@ -266,12 +407,29 @@ mod newtype_enum { Token::MapEnd, ], ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::BorrowedStr("tag"), + Token::BorrowedStr("NewtypeEnum"), + Token::BorrowedStr("Struct"), + Token::Struct { + name: "Struct", + len: 1, + }, + Token::BorrowedStr("f"), + Token::U8(1), + Token::StructEnd, + Token::MapEnd, + ], + ); // Reaches crate::private::de::content::VariantDeserializer::struct_variant // Content::Seq case // via ContentDeserializer::deserialize_enum assert_de_tokens( - &InternallyTagged::NewtypeEnum(Enum::Struct { f: 1 }), + &value, &[ Token::Map { len: Some(2) }, Token::Str("tag"), @@ -283,13 +441,28 @@ mod newtype_enum { Token::MapEnd, ], ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::BorrowedStr("tag"), + Token::BorrowedStr("NewtypeEnum"), + Token::BorrowedStr("Struct"), + Token::Seq { len: Some(1) }, + Token::U8(1), // f + Token::SeqEnd, + Token::MapEnd, + ], + ); } } #[test] fn struct_() { + let value = InternallyTagged::Struct { a: 1 }; + assert_tokens( - &InternallyTagged::Struct { a: 1 }, + &value, &[ Token::Struct { name: "InternallyTagged", @@ -302,12 +475,35 @@ fn struct_() { Token::StructEnd, ], ); + assert_de_tokens( + &value, + &[ + Token::Struct { + name: "InternallyTagged", + len: 2, + }, + Token::BorrowedStr("tag"), + Token::BorrowedStr("Struct"), + Token::BorrowedStr("a"), + Token::U8(1), + Token::StructEnd, + ], + ); assert_de_tokens( - &InternallyTagged::Struct { a: 1 }, + &value, &[ Token::Seq { len: Some(2) }, - Token::Str("Struct"), + Token::Str("Struct"), // tag + Token::U8(1), + Token::SeqEnd, + ], + ); + assert_de_tokens( + &value, + &[ + Token::Seq { len: Some(2) }, + Token::BorrowedStr("Struct"), // tag Token::U8(1), Token::SeqEnd, ], @@ -330,7 +526,7 @@ mod struct_enum { let value = InternallyTagged::StructEnum { enum_: Enum::Unit }; - assert_de_tokens( + assert_tokens( &value, &[ Token::Struct { @@ -341,6 +537,22 @@ mod struct_enum { Token::Str("StructEnum"), Token::Str("enum_"), Token::Enum { name: "Enum" }, + Token::Str("Unit"), + Token::Unit, + Token::StructEnd, + ], + ); + assert_de_tokens( + &value, + &[ + Token::Struct { + name: "InternallyTagged", + len: 2, + }, + Token::BorrowedStr("tag"), + Token::BorrowedStr("StructEnum"), + Token::BorrowedStr("enum_"), + Token::Enum { name: "Enum" }, Token::BorrowedStr("Unit"), Token::Unit, Token::StructEnd, @@ -355,6 +567,19 @@ mod struct_enum { Token::Str("StructEnum"), Token::Str("enum_"), Token::Enum { name: "Enum" }, + Token::Str("Unit"), + Token::Unit, + Token::MapEnd, + ], + ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::BorrowedStr("tag"), + Token::BorrowedStr("StructEnum"), + Token::BorrowedStr("enum_"), + Token::Enum { name: "Enum" }, Token::BorrowedStr("Unit"), Token::Unit, Token::MapEnd, @@ -367,6 +592,17 @@ mod struct_enum { Token::Seq { len: Some(2) }, Token::Str("StructEnum"), // tag Token::Enum { name: "Enum" }, // enum_ + Token::Str("Unit"), + Token::Unit, + Token::SeqEnd, + ], + ); + assert_de_tokens( + &value, + &[ + Token::Seq { len: Some(2) }, + Token::BorrowedStr("StructEnum"), // tag + Token::Enum { name: "Enum" }, // enum_ Token::BorrowedStr("Unit"), Token::Unit, Token::SeqEnd, @@ -786,7 +1022,7 @@ fn unit_variant_with_unknown_fields() { assert_de_tokens_error::( &[ Token::Seq { len: None }, - Token::Str("Unit"), + Token::Str("Unit"), // tag Token::I32(0), Token::SeqEnd, ], From 71ed1f2f127ef3847f35ecbe0cd8e2b5e7b42be1 Mon Sep 17 00:00:00 2001 From: Mingun Date: Mon, 3 Oct 2022 23:07:12 +0500 Subject: [PATCH 21/22] Add tests for special and general cases for internally tagged enums Special case is the tag field first (so the enum variant are known after reading the first entry from map). General case is the tag field not the first (so we need to buffer entries until we found an entry with tag) --- .../tests/test_enum_internally_tagged.rs | 396 +++++++++++++++++- 1 file changed, 389 insertions(+), 7 deletions(-) diff --git a/test_suite/tests/test_enum_internally_tagged.rs b/test_suite/tests/test_enum_internally_tagged.rs index 4c800256..9527da58 100644 --- a/test_suite/tests/test_enum_internally_tagged.rs +++ b/test_suite/tests/test_enum_internally_tagged.rs @@ -11,6 +11,7 @@ mod bytes; use serde_derive::{Deserialize, Serialize}; use serde_test::{assert_de_tokens, assert_de_tokens_error, assert_tokens, Token}; use std::collections::BTreeMap; +use std::iter::FromIterator; #[derive(Debug, PartialEq, Serialize, Deserialize)] struct Unit; @@ -197,6 +198,7 @@ fn newtype_newtype() { fn newtype_map() { let value = InternallyTagged::NewtypeMap(BTreeMap::new()); + // Special case: empty map assert_tokens( &value, &[ @@ -216,6 +218,59 @@ fn newtype_map() { ], ); + let value = InternallyTagged::NewtypeMap(BTreeMap::from_iter([( + "field".to_string(), + "value".to_string(), + )])); + + // Special case: tag field ("tag") is the first field + assert_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::Str("tag"), + Token::Str("NewtypeMap"), + Token::Str("field"), + Token::Str("value"), + Token::MapEnd, + ], + ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::BorrowedStr("tag"), + Token::BorrowedStr("NewtypeMap"), + Token::BorrowedStr("field"), + Token::BorrowedStr("value"), + Token::MapEnd, + ], + ); + + // General case: tag field ("tag") is not the first field + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::Str("field"), + Token::Str("value"), + Token::Str("tag"), + Token::Str("NewtypeMap"), + Token::MapEnd, + ], + ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::BorrowedStr("field"), + Token::BorrowedStr("value"), + Token::BorrowedStr("tag"), + Token::BorrowedStr("NewtypeMap"), + Token::MapEnd, + ], + ); + assert_de_tokens_error::( &[ Token::Seq { len: Some(2) }, @@ -232,6 +287,7 @@ fn newtype_map() { fn newtype_struct() { let value = InternallyTagged::NewtypeStruct(Struct { f: 6 }); + // Special case: tag field ("tag") is the first field assert_tokens( &value, &[ @@ -261,6 +317,36 @@ fn newtype_struct() { ], ); + // General case: tag field ("tag") is not the first field + assert_de_tokens( + &value, + &[ + Token::Struct { + name: "Struct", + len: 2, + }, + Token::Str("f"), + Token::U8(6), + Token::Str("tag"), + Token::Str("NewtypeStruct"), + Token::StructEnd, + ], + ); + assert_de_tokens( + &value, + &[ + Token::Struct { + name: "Struct", + len: 2, + }, + Token::BorrowedStr("f"), + Token::U8(6), + Token::BorrowedStr("tag"), + Token::BorrowedStr("NewtypeStruct"), + Token::StructEnd, + ], + ); + assert_de_tokens( &value, &[ @@ -288,6 +374,7 @@ mod newtype_enum { fn unit() { let value = InternallyTagged::NewtypeEnum(Enum::Unit); + // Special case: tag field ("tag") is the first field assert_tokens( &value, &[ @@ -310,12 +397,37 @@ mod newtype_enum { Token::MapEnd, ], ); + + // General case: tag field ("tag") is not the first field + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::Str("Unit"), + Token::Unit, + Token::Str("tag"), + Token::Str("NewtypeEnum"), + Token::MapEnd, + ], + ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::BorrowedStr("Unit"), + Token::Unit, + Token::BorrowedStr("tag"), + Token::BorrowedStr("NewtypeEnum"), + Token::MapEnd, + ], + ); } #[test] fn newtype() { let value = InternallyTagged::NewtypeEnum(Enum::Newtype(1)); + // Special case: tag field ("tag") is the first field assert_tokens( &value, &[ @@ -338,15 +450,37 @@ mod newtype_enum { Token::MapEnd, ], ); + + // General case: tag field ("tag") is not the first field + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::Str("Newtype"), + Token::U8(1), + Token::Str("tag"), + Token::Str("NewtypeEnum"), + Token::MapEnd, + ], + ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::BorrowedStr("Newtype"), + Token::U8(1), + Token::BorrowedStr("tag"), + Token::BorrowedStr("NewtypeEnum"), + Token::MapEnd, + ], + ); } #[test] fn tuple() { let value = InternallyTagged::NewtypeEnum(Enum::Tuple(1, 1)); - // Reaches crate::private::de::content::VariantDeserializer::tuple_variant - // Content::Seq case - // via ContentDeserializer::deserialize_enum + // Special case: tag field ("tag") is the first field assert_tokens( &value, &[ @@ -381,15 +515,52 @@ mod newtype_enum { Token::MapEnd, ], ); + + // Special case: tag field ("tag") is not the first field + // Reaches crate::private::de::content::VariantDeserializer::tuple_variant + // Content::Seq case + // via ContentDeserializer::deserialize_enum + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::Str("Tuple"), + Token::TupleStruct { + name: "Tuple", + len: 2, + }, + Token::U8(1), + Token::U8(1), + Token::TupleStructEnd, + Token::Str("tag"), + Token::Str("NewtypeEnum"), + Token::MapEnd, + ], + ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::BorrowedStr("Tuple"), + Token::TupleStruct { + name: "Tuple", + len: 2, + }, + Token::U8(1), + Token::U8(1), + Token::TupleStructEnd, + Token::BorrowedStr("tag"), + Token::BorrowedStr("NewtypeEnum"), + Token::MapEnd, + ], + ); } #[test] fn struct_() { let value = InternallyTagged::NewtypeEnum(Enum::Struct { f: 1 }); - // Reaches crate::private::de::content::VariantDeserializer::struct_variant - // Content::Map case - // via ContentDeserializer::deserialize_enum + // Special case: tag field ("tag") is the first field assert_tokens( &value, &[ @@ -425,9 +596,46 @@ mod newtype_enum { ], ); + // General case: tag field ("tag") is not the first field // Reaches crate::private::de::content::VariantDeserializer::struct_variant - // Content::Seq case + // Content::Map case // via ContentDeserializer::deserialize_enum + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::Str("Struct"), + Token::Struct { + name: "Struct", + len: 1, + }, + Token::Str("f"), + Token::U8(1), + Token::StructEnd, + Token::Str("tag"), + Token::Str("NewtypeEnum"), + Token::MapEnd, + ], + ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::BorrowedStr("Struct"), + Token::Struct { + name: "Struct", + len: 1, + }, + Token::BorrowedStr("f"), + Token::U8(1), + Token::StructEnd, + Token::BorrowedStr("tag"), + Token::BorrowedStr("NewtypeEnum"), + Token::MapEnd, + ], + ); + + // Special case: tag field ("tag") is the first field assert_de_tokens( &value, &[ @@ -454,6 +662,37 @@ mod newtype_enum { Token::MapEnd, ], ); + + // General case: tag field ("tag") is not the first field + // Reaches crate::private::de::content::VariantDeserializer::struct_variant + // Content::Seq case + // via ContentDeserializer::deserialize_enum + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::Str("Struct"), + Token::Seq { len: Some(1) }, + Token::U8(1), // f + Token::SeqEnd, + Token::Str("tag"), + Token::Str("NewtypeEnum"), + Token::MapEnd, + ], + ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::BorrowedStr("Struct"), + Token::Seq { len: Some(1) }, + Token::U8(1), // f + Token::SeqEnd, + Token::BorrowedStr("tag"), + Token::BorrowedStr("NewtypeEnum"), + Token::MapEnd, + ], + ); } } @@ -461,6 +700,7 @@ mod newtype_enum { fn struct_() { let value = InternallyTagged::Struct { a: 1 }; + // Special case: tag field ("tag") is the first field assert_tokens( &value, &[ @@ -490,6 +730,84 @@ fn struct_() { ], ); + // General case: tag field ("tag") is not the first field + assert_de_tokens( + &value, + &[ + Token::Struct { + name: "InternallyTagged", + len: 2, + }, + Token::Str("a"), + Token::U8(1), + Token::Str("tag"), + Token::Str("Struct"), + Token::StructEnd, + ], + ); + assert_de_tokens( + &value, + &[ + Token::Struct { + name: "InternallyTagged", + len: 2, + }, + Token::BorrowedStr("a"), + Token::U8(1), + Token::BorrowedStr("tag"), + Token::BorrowedStr("Struct"), + Token::StructEnd, + ], + ); + + // Special case: tag field ("tag") is the first field + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::Str("tag"), + Token::Str("Struct"), + Token::Str("a"), + Token::U8(1), + Token::MapEnd, + ], + ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::BorrowedStr("tag"), + Token::BorrowedStr("Struct"), + Token::BorrowedStr("a"), + Token::U8(1), + Token::MapEnd, + ], + ); + + // General case: tag field ("tag") is not the first field + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::Str("a"), + Token::U8(1), + Token::Str("tag"), + Token::Str("Struct"), + Token::MapEnd, + ], + ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::BorrowedStr("a"), + Token::U8(1), + Token::BorrowedStr("tag"), + Token::BorrowedStr("Struct"), + Token::MapEnd, + ], + ); + assert_de_tokens( &value, &[ @@ -526,6 +844,7 @@ mod struct_enum { let value = InternallyTagged::StructEnum { enum_: Enum::Unit }; + // Special case: tag field ("tag") is the first field assert_tokens( &value, &[ @@ -559,6 +878,41 @@ mod struct_enum { ], ); + // General case: tag field ("tag") is not the first field + assert_de_tokens( + &value, + &[ + Token::Struct { + name: "InternallyTagged", + len: 2, + }, + Token::Str("enum_"), + Token::Enum { name: "Enum" }, + Token::Str("Unit"), + Token::Unit, + Token::Str("tag"), + Token::Str("StructEnum"), + Token::StructEnd, + ], + ); + assert_de_tokens( + &value, + &[ + Token::Struct { + name: "InternallyTagged", + len: 2, + }, + Token::BorrowedStr("enum_"), + Token::Enum { name: "Enum" }, + Token::BorrowedStr("Unit"), + Token::Unit, + Token::BorrowedStr("tag"), + Token::BorrowedStr("StructEnum"), + Token::StructEnd, + ], + ); + + // Special case: tag field ("tag") is the first field assert_de_tokens( &value, &[ @@ -586,6 +940,34 @@ mod struct_enum { ], ); + // General case: tag field ("tag") is not the first field + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::Str("enum_"), + Token::Enum { name: "Enum" }, + Token::Str("Unit"), + Token::Unit, + Token::Str("tag"), + Token::Str("StructEnum"), + Token::MapEnd, + ], + ); + assert_de_tokens( + &value, + &[ + Token::Map { len: Some(2) }, + Token::BorrowedStr("enum_"), + Token::Enum { name: "Enum" }, + Token::BorrowedStr("Unit"), + Token::Unit, + Token::BorrowedStr("tag"), + Token::BorrowedStr("StructEnum"), + Token::MapEnd, + ], + ); + assert_de_tokens( &value, &[ From 2adb0e99b024aab039a9fc6fdd384e84c8ae8297 Mon Sep 17 00:00:00 2001 From: Mingun Date: Tue, 8 Aug 2023 01:56:51 +0500 Subject: [PATCH 22/22] Add additional checks for unit and newtype_unit tests - check that unit variant can be deserialized from a map - check that newtype variant with unit can be deserialized from a struct --- .../tests/test_enum_internally_tagged.rs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/test_suite/tests/test_enum_internally_tagged.rs b/test_suite/tests/test_enum_internally_tagged.rs index 9527da58..b4d428c4 100644 --- a/test_suite/tests/test_enum_internally_tagged.rs +++ b/test_suite/tests/test_enum_internally_tagged.rs @@ -73,6 +73,25 @@ fn unit() { ], ); + assert_de_tokens( + &InternallyTagged::Unit, + &[ + Token::Map { len: Some(1) }, + Token::Str("tag"), + Token::Str("Unit"), + Token::MapEnd, + ], + ); + assert_de_tokens( + &InternallyTagged::Unit, + &[ + Token::Map { len: Some(1) }, + Token::BorrowedStr("tag"), + Token::BorrowedStr("Unit"), + Token::MapEnd, + ], + ); + assert_de_tokens( &InternallyTagged::Unit, &[ @@ -113,6 +132,31 @@ fn newtype_unit() { Token::MapEnd, ], ); + + assert_de_tokens( + &value, + &[ + Token::Struct { + name: "InternallyTagged", + len: 1, + }, + Token::Str("tag"), + Token::Str("NewtypeUnit"), + Token::StructEnd, + ], + ); + assert_de_tokens( + &value, + &[ + Token::Struct { + name: "InternallyTagged", + len: 1, + }, + Token::BorrowedStr("tag"), + Token::BorrowedStr("NewtypeUnit"), + Token::StructEnd, + ], + ); } #[test]