Skip to content

Commit

Permalink
feat(serde-rs#1587): implement serde(strict_or_some_other_name) on enums
Browse files Browse the repository at this point in the history
This only has an effect on struct variants.
  • Loading branch information
Toromyx committed Oct 28, 2023
1 parent a3c11f3 commit 75e969d
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 18 deletions.
5 changes: 4 additions & 1 deletion serde_derive/src/internals/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ impl Container {
de_bound.set_opt(&meta.path, de);
} else if meta.path == STRICT_OR_SOME_OTHER_NAME {
// #[serde(strict_or_some_other_name)]
let msg = "#[serde(strict_or_some_other_name)] can only be used on structs with named fields";
let msg = "#[serde(strict_or_some_other_name)] can only be used on structs with named fields or enums";
match &item.data {
syn::Data::Struct(syn::DataStruct { fields, .. }) => {
match fields {
Expand All @@ -462,6 +462,9 @@ impl Container {
}
};
}
syn::Data::Enum(_) => {
strict_or_some_other_name.set_true(&meta.path);
}
_ => {
cx.syn_error(meta.error(msg));
}
Expand Down
89 changes: 89 additions & 0 deletions test_suite/tests/test_de_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ struct StructStrictOrSomeOtherName {
#[derive(Default, PartialEq, Debug)]
struct NotDeserializable;

#[derive(Debug, PartialEq, Deserialize)]
struct FlattenStrictStrictOrSomeOtherName {
#[serde(flatten)]
data: EnumStrictStrictOrSomeOtherName,
}

#[derive(PartialEq, Debug, Deserialize)]
#[serde(strict_or_some_other_name)]
enum EnumStrictStrictOrSomeOtherName {
Map { a: i32, b: i32, c: i32 },
}

#[derive(PartialEq, Debug, Deserialize)]
enum Enum {
#[allow(dead_code)]
Expand All @@ -74,6 +86,26 @@ enum EnumSkipAll {
Skipped,
}

#[derive(Debug, PartialEq, Deserialize)]
#[serde(tag = "type")]
#[serde(strict_or_some_other_name)]
enum InternallyTaggedStrictOrSomeOtherName {
A { a: u8 },
B(StructStrictOrSomeOtherName),
}

#[derive(Debug, PartialEq, Deserialize)]
#[serde(tag = "type")]
enum OuterStrictOrSomeOtherName {
Inner(InnerStrictOrSomeOtherName),
}

#[derive(Debug, PartialEq, Deserialize)]
#[serde(strict_or_some_other_name)]
enum InnerStrictOrSomeOtherName {
Struct { f: u8 },
}

#[test]
fn test_i8() {
let test = assert_de_tokens_error::<i8>;
Expand Down Expand Up @@ -1262,6 +1294,63 @@ fn test_enum_out_of_range() {
);
}

#[test]
fn test_struct_variant_strict_or_some_other_name_flatten() {
assert_de_tokens_error::<FlattenStrictStrictOrSomeOtherName>(
&[
Token::Map { len: None },
Token::Str("Map"), // variant
Token::Seq { len: Some(3) },
Token::U32(0), // a
Token::U32(42), // b
Token::U32(69), // c
Token::SeqEnd,
Token::MapEnd,
],
"invalid type: sequence, expected struct variant EnumStrictStrictOrSomeOtherName::Map",
);
}

#[test]
fn test_struct_variant_strict_or_some_other_name_internally_tagged() {
assert_de_tokens_error::<InternallyTaggedStrictOrSomeOtherName>(
&[
Token::Seq { len: Some(2) },
Token::Str("A"),
Token::U8(1),
Token::SeqEnd,
],
"invalid type: sequence, expected struct variant InternallyTaggedStrictOrSomeOtherName::A",
);
assert_de_tokens_error::<InternallyTaggedStrictOrSomeOtherName>(
&[
Token::Seq { len: Some(2) },
Token::Str("B"),
Token::I32(0),
Token::I32(42),
Token::SeqEnd,
],
"invalid type: sequence, expected struct StructStrictOrSomeOtherName",
);
}

#[test]
fn test_struct_variant_strict_or_some_other_name_enum_in_internally_tagged_enum() {
assert_de_tokens_error::<OuterStrictOrSomeOtherName>(
&[
Token::Map { len: Some(2) },
Token::Str("type"),
Token::Str("Inner"),
Token::Str("Struct"),
Token::Seq { len: Some(1) },
Token::U8(69),
Token::SeqEnd,
Token::MapEnd,
],
"invalid type: sequence, expected struct variant InnerStrictOrSomeOtherName::Struct",
);
}

#[test]
fn test_short_tuple() {
assert_de_tokens_error::<(u8, u8, u8)>(
Expand Down
9 changes: 0 additions & 9 deletions test_suite/tests/ui/strict-or-some-other-name/enum.rs

This file was deleted.

5 changes: 0 additions & 5 deletions test_suite/tests/ui/strict-or-some-other-name/enum.stderr

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: #[serde(strict_or_some_other_name)] can only be used on structs with named fields
error: #[serde(strict_or_some_other_name)] can only be used on structs with named fields or enums
--> tests/ui/strict-or-some-other-name/newtype-struct.rs:4:9
|
4 | #[serde(strict_or_some_other_name)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: #[serde(strict_or_some_other_name)] can only be used on structs with named fields
error: #[serde(strict_or_some_other_name)] can only be used on structs with named fields or enums
--> tests/ui/strict-or-some-other-name/tuple-struct.rs:4:9
|
4 | #[serde(strict_or_some_other_name)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: #[serde(strict_or_some_other_name)] can only be used on structs with named fields
error: #[serde(strict_or_some_other_name)] can only be used on structs with named fields or enums
--> tests/ui/strict-or-some-other-name/unit-struct.rs:4:9
|
4 | #[serde(strict_or_some_other_name)]
Expand Down

0 comments on commit 75e969d

Please sign in to comment.