diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index f0697d64f..7cb540c14 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -1262,6 +1262,16 @@ mod content { { match self.content { Content::Unit => visitor.visit_unit(), + + // As a special case, allow deserializing newtype variant containing unit. E.G: + // #[derive(Deserialize)] + // #[serde(tag = "result")] + // enum Response { + // Success(T), + // } + // + // We want {"result": "Success"} to deserialize into `Response`. + Content::Map(ref v) if v.is_empty() => visitor.visit_unit(), _ => Err(self.invalid_type(&visitor)), } } diff --git a/serde/src/private/ser.rs b/serde/src/private/ser.rs index 6ee999389..293d8a865 100644 --- a/serde/src/private/ser.rs +++ b/serde/src/private/ser.rs @@ -51,7 +51,6 @@ enum Unsupported { String, ByteArray, Optional, - Unit, #[cfg(any(feature = "std", feature = "alloc"))] UnitStruct, Sequence, @@ -70,7 +69,6 @@ impl Display for Unsupported { Unsupported::String => formatter.write_str("a string"), Unsupported::ByteArray => formatter.write_str("a byte array"), Unsupported::Optional => formatter.write_str("an optional"), - Unsupported::Unit => formatter.write_str("unit"), #[cfg(any(feature = "std", feature = "alloc"))] Unsupported::UnitStruct => formatter.write_str("unit struct"), Unsupported::Sequence => formatter.write_str("a sequence"), @@ -184,7 +182,9 @@ where } fn serialize_unit(self) -> Result { - Err(self.bad_type(Unsupported::Unit)) + let mut map = try!(self.delegate.serialize_map(Some(1))); + try!(map.serialize_entry(self.tag, self.variant_name)); + map.end() } fn serialize_unit_struct(self, _: &'static str) -> Result { diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index 0317def6d..9f9e2135d 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -2302,6 +2302,25 @@ fn test_internally_tagged_enum_containing_flatten() { ); } +#[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_containing_flatten() { #[derive(Serialize, Deserialize, PartialEq, Debug)]