Skip to content

Commit

Permalink
Fix roundtrip inconsistency:
Browse files Browse the repository at this point in the history
- deserialization of flatten unit variant is possible
- serialization of such variant gives Err("can only flatten structs and maps (got an enum)")
  • Loading branch information
Mingun committed Aug 3, 2024
1 parent 28a0922 commit 7fc1636
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 2 deletions.
6 changes: 4 additions & 2 deletions serde/src/private/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ enum Unsupported {
Sequence,
Tuple,
TupleStruct,
#[cfg(not(any(feature = "std", feature = "alloc")))]
Enum,
}

Expand All @@ -74,6 +75,7 @@ impl Display for Unsupported {
Unsupported::Sequence => formatter.write_str("a sequence"),
Unsupported::Tuple => formatter.write_str("a tuple"),
Unsupported::TupleStruct => formatter.write_str("a tuple struct"),
#[cfg(not(any(feature = "std", feature = "alloc")))]
Unsupported::Enum => formatter.write_str("an enum"),
}
}
Expand Down Expand Up @@ -1099,9 +1101,9 @@ where
self,
_: &'static str,
_: u32,
_: &'static str,
variant: &'static str,
) -> Result<Self::Ok, Self::Error> {
Err(Self::bad_type(Unsupported::Enum))
self.0.serialize_entry(variant, &())
}

fn serialize_newtype_struct<T>(
Expand Down
35 changes: 35 additions & 0 deletions test_suite/tests/test_annotations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2912,11 +2912,46 @@ mod flatten {

#[derive(Debug, PartialEq, Serialize, Deserialize)]
enum Enum {
Unit,
Newtype(HashMap<String, String>),
Tuple(u32, u32),
Struct { index: u32, value: u32 },
}

#[test]
fn unit() {
let value = Flatten {
data: Enum::Unit,
extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]),
};
assert_tokens(
&value,
&[
Token::Map { len: None },
// data
Token::Str("Unit"), // variant
Token::Unit,
// extra
Token::Str("extra_key"),
Token::Str("extra value"),
Token::MapEnd,
],
);
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// extra
Token::Str("extra_key"),
Token::Str("extra value"),
// data
Token::Str("Unit"), // variant
Token::Unit,
Token::MapEnd,
],
);
}

#[test]
fn newtype() {
assert_tokens(
Expand Down

0 comments on commit 7fc1636

Please sign in to comment.