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 authored and oli-obk committed Dec 27, 2024
1 parent b6f339c commit cb6eaea
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 @@ -54,6 +54,7 @@ enum Unsupported {
Sequence,
Tuple,
TupleStruct,
#[cfg(not(any(feature = "std", feature = "alloc")))]
Enum,
}

Expand All @@ -70,6 +71,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 @@ -1095,9 +1097,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 @@ -2655,11 +2655,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 cb6eaea

Please sign in to comment.