Skip to content

Commit 6aed101

Browse files
authored
Merge pull request #2303 from tage64/master
Serialize and deserialize a tagged newtype variant over unit () as if it was a unit variant
2 parents 55cf0ac + e2ccfd9 commit 6aed101

File tree

3 files changed

+32
-3
lines changed

3 files changed

+32
-3
lines changed

serde/src/private/de.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,6 +1262,16 @@ mod content {
12621262
{
12631263
match self.content {
12641264
Content::Unit => visitor.visit_unit(),
1265+
1266+
// As a special case, allow deserializing newtype variant containing unit. E.G:
1267+
// #[derive(Deserialize)]
1268+
// #[serde(tag = "result")]
1269+
// enum Response<T> {
1270+
// Success(T),
1271+
// }
1272+
//
1273+
// We want {"result": "Success"} to deserialize into `Response<T>`.
1274+
Content::Map(ref v) if v.is_empty() => visitor.visit_unit(),
12651275
_ => Err(self.invalid_type(&visitor)),
12661276
}
12671277
}

serde/src/private/ser.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ enum Unsupported {
5151
String,
5252
ByteArray,
5353
Optional,
54-
Unit,
5554
#[cfg(any(feature = "std", feature = "alloc"))]
5655
UnitStruct,
5756
Sequence,
@@ -70,7 +69,6 @@ impl Display for Unsupported {
7069
Unsupported::String => formatter.write_str("a string"),
7170
Unsupported::ByteArray => formatter.write_str("a byte array"),
7271
Unsupported::Optional => formatter.write_str("an optional"),
73-
Unsupported::Unit => formatter.write_str("unit"),
7472
#[cfg(any(feature = "std", feature = "alloc"))]
7573
Unsupported::UnitStruct => formatter.write_str("unit struct"),
7674
Unsupported::Sequence => formatter.write_str("a sequence"),
@@ -184,7 +182,9 @@ where
184182
}
185183

186184
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
187-
Err(self.bad_type(Unsupported::Unit))
185+
let mut map = try!(self.delegate.serialize_map(Some(1)));
186+
try!(map.serialize_entry(self.tag, self.variant_name));
187+
map.end()
188188
}
189189

190190
fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> {

test_suite/tests/test_annotations.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2302,6 +2302,25 @@ fn test_internally_tagged_enum_containing_flatten() {
23022302
);
23032303
}
23042304

2305+
#[test]
2306+
fn test_internally_tagged_enum_new_type_with_unit() {
2307+
#[derive(Serialize, Deserialize, PartialEq, Debug)]
2308+
#[serde(tag = "t")]
2309+
enum Data {
2310+
A(()),
2311+
}
2312+
2313+
assert_tokens(
2314+
&Data::A(()),
2315+
&[
2316+
Token::Map { len: Some(1) },
2317+
Token::Str("t"),
2318+
Token::Str("A"),
2319+
Token::MapEnd,
2320+
],
2321+
);
2322+
}
2323+
23052324
#[test]
23062325
fn test_adjacently_tagged_enum_containing_flatten() {
23072326
#[derive(Serialize, Deserialize, PartialEq, Debug)]

0 commit comments

Comments
 (0)