From 8c0a2015be65fe6977995fc2bb6e05f8747deb07 Mon Sep 17 00:00:00 2001 From: Alex Shapiro Date: Wed, 15 Nov 2017 13:08:34 -0800 Subject: [PATCH] Fix error when deserializing untagged enum Serde's `ContentDeserializer` and `ContentRefDeserializer` cannot deserialize struct enum variant associated data when that data is encoded as a sequence. This failure leads to errors when decoding an enum nested in another untagged enum. For example: #[derive(Serialize, Deserialize)] #[serde(untagged)] enum Foo { A(Bar), } #[derive(Serialize, Deserialize)] enum Bar { B{f1: String}, } let data1 = Foo::A(Bar::B{f1: "Hello".into()}); let bytes = rmp_serde::to_vec(&data1).unwrap(); let data2 = rmp_serde::from_slice::(&bytes).unwrap(); Deserializing fails with the error `Syntax("data did not match any variant of untagged enum Foo")`, but the underlying failure occurs when decoding the associated data of `Bar::B`. This pull request fixes the issue by allowing `ContentDeserializer` and `ContentRefDeserializer` to deserialize sequence-encoded struct enum variant data. --- serde/src/private/de.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index d9382bc6..67f1d947 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -1246,6 +1246,9 @@ mod content { Some(Content::Map(v)) => { de::Deserializer::deserialize_any(MapDeserializer::new(v), visitor) } + Some(Content::Seq(v)) => { + de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor) + } Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant"),), _ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"),), } @@ -1640,6 +1643,9 @@ mod content { Some(&Content::Map(ref v)) => { de::Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor) } + Some(&Content::Seq(ref v)) => { + de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor) + } Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant"),), _ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"),), }