From 6fefeb17db48fa54aadfaa93e36d2fe7fc477577 Mon Sep 17 00:00:00 2001 From: frederik-uni <147479464+frederik-uni@users.noreply.github.com> Date: Sat, 19 Oct 2024 01:27:47 +0200 Subject: [PATCH 1/8] add missing visit_enum --- serde/src/private/de.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 50ae6ed15..c30cc7373 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -525,13 +525,16 @@ mod content { Ok(Content::Map(vec)) } - fn visit_enum(self, _visitor: V) -> Result + fn visit_enum(self, visitor: V) -> Result where V: EnumAccess<'de>, { - Err(de::Error::custom( - "untagged and internally tagged enums do not support enum input", - )) + use crate::de::VariantAccess; + let (key, data) = tri!(visitor.variant::()); + Ok(Content::Map(vec![( + Content::String(key), + tri!(data.newtype_variant::()), + )])) } } From 1286b8a0e007fccfe7eaa25ca19dad8bc0fc7208 Mon Sep 17 00:00:00 2001 From: frederik-uni <147479464+frederik-uni@users.noreply.github.com> Date: Sat, 19 Oct 2024 01:43:06 +0200 Subject: [PATCH 2/8] fix action --- serde/src/private/de.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index c30cc7373..881b1a5b4 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -212,7 +212,7 @@ mod content { use crate::de::value::{MapDeserializer, SeqDeserializer}; use crate::de::{ self, size_hint, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, - IgnoredAny, MapAccess, SeqAccess, Unexpected, Visitor, + IgnoredAny, MapAccess, SeqAccess, Unexpected, VariantAccess, Visitor, }; /// Used from generated code to buffer the contents of the Deserializer when @@ -529,12 +529,14 @@ mod content { where V: EnumAccess<'de>, { - use crate::de::VariantAccess; let (key, data) = tri!(visitor.variant::()); - Ok(Content::Map(vec![( - Content::String(key), - tri!(data.newtype_variant::()), - )])) + Ok(Content::Map( + [( + Content::String(key), + tri!(data.newtype_variant::()), + )] + .into(), + )) } } From 546797ee765bb851f1bb800929065fadccc5cae3 Mon Sep 17 00:00:00 2001 From: frederik Date: Wed, 26 Feb 2025 21:37:44 +0100 Subject: [PATCH 3/8] type hint --- serde/src/de/mod.rs | 13 +++++++++++++ serde/src/private/de.rs | 20 +++++++++++--------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 540632f4a..f03bb0bcc 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -2010,6 +2010,14 @@ pub trait EnumAccess<'de>: Sized { } } +/// VariantHint for VariantAccess +pub enum VariantHint { + Unit, + Newtype, + Tuple(usize), + Struct(&'static [&'static str]), +} + /// `VariantAccess` is a visitor that is created by the `Deserializer` and /// passed to the `Deserialize` to deserialize the content of a particular enum /// variant. @@ -2127,6 +2135,11 @@ pub trait VariantAccess<'de>: Sized { self.newtype_variant_seed(PhantomData) } + /// Variant type hint + fn hint(&self) -> Option { + None + } + /// Called when deserializing a tuple-like variant. /// /// The `len` is the number of fields expected in the tuple variant. diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 881b1a5b4..274c8feae 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -529,14 +529,17 @@ mod content { where V: EnumAccess<'de>, { - let (key, data) = tri!(visitor.variant::()); - Ok(Content::Map( - [( - Content::String(key), - tri!(data.newtype_variant::()), - )] - .into(), - )) + let (key, data) = tri!(visitor.variant::()); + let variant_hint = tri!(data.hint().ok_or(de::Error::custom( + "untagged and internally tagged enums do not support enum input", + ))); + let data = match variant_hint { + de::VariantHint::Unit => Content::Unit, + de::VariantHint::Newtype => tri!(data.newtype_variant::()), + de::VariantHint::Tuple(len) => tri!(data.tuple_variant(len, self)), + de::VariantHint::Struct(fields) => tri!(data.struct_variant(fields, self)), + }; + Ok(Content::Map([(key, data)].into())) } } @@ -2066,7 +2069,6 @@ mod content { )); } }; - visitor.visit_enum(EnumRefDeserializer { variant, value, From 2b522db7f01c5c0f9593caaa7f0d7fceed09e7fe Mon Sep 17 00:00:00 2001 From: frederik Date: Wed, 26 Feb 2025 21:45:58 +0100 Subject: [PATCH 4/8] docs --- serde/src/de/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index f03bb0bcc..6f40cc57d 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -2010,11 +2010,15 @@ pub trait EnumAccess<'de>: Sized { } } -/// VariantHint for VariantAccess +/// Variant Hint for VariantAccess pub enum VariantHint { + /// variant with no values Unit, + /// variant with a single value Newtype, + /// vuple-like variant with the length of the tuple Tuple(usize), + /// struct-like variant. with names of the fields of the struct variant Struct(&'static [&'static str]), } From 1c652fd02a7a9da9c329e0c01eb1c8206f938f2f Mon Sep 17 00:00:00 2001 From: frederik Date: Thu, 27 Feb 2025 11:50:00 +0100 Subject: [PATCH 5/8] requested changes --- serde/src/de/mod.rs | 8 ++++++++ serde/src/private/de.rs | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 6f40cc57d..668b133dd 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -2011,6 +2011,14 @@ pub trait EnumAccess<'de>: Sized { } /// Variant Hint for VariantAccess +/// ```edition2021 +/// let (key, data) = tri!(visitor.variant()); +/// let variant_hint = data.hint().unwrap() +/// let data = match variant_hint { +/// de::VariantHint::Unit => Content::Unit, +/// de::VariantHint::Newtype => tri!(data.newtype_variant()), +/// _ => unreachable!(), +/// }; pub enum VariantHint { /// variant with no values Unit, diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 274c8feae..f4b7bf67c 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -535,7 +535,7 @@ mod content { ))); let data = match variant_hint { de::VariantHint::Unit => Content::Unit, - de::VariantHint::Newtype => tri!(data.newtype_variant::()), + de::VariantHint::Newtype => tri!(data.newtype_variant()), de::VariantHint::Tuple(len) => tri!(data.tuple_variant(len, self)), de::VariantHint::Struct(fields) => tri!(data.struct_variant(fields, self)), }; @@ -2069,6 +2069,7 @@ mod content { )); } }; + visitor.visit_enum(EnumRefDeserializer { variant, value, From c8fb96fed9a4024f5e4d437a915b74c19061858d Mon Sep 17 00:00:00 2001 From: frederik Date: Thu, 27 Feb 2025 12:14:57 +0100 Subject: [PATCH 6/8] code example --- serde/src/de/mod.rs | 46 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 668b133dd..4e68c580f 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -2011,14 +2011,6 @@ pub trait EnumAccess<'de>: Sized { } /// Variant Hint for VariantAccess -/// ```edition2021 -/// let (key, data) = tri!(visitor.variant()); -/// let variant_hint = data.hint().unwrap() -/// let data = match variant_hint { -/// de::VariantHint::Unit => Content::Unit, -/// de::VariantHint::Newtype => tri!(data.newtype_variant()), -/// _ => unreachable!(), -/// }; pub enum VariantHint { /// variant with no values Unit, @@ -2148,6 +2140,44 @@ pub trait VariantAccess<'de>: Sized { } /// Variant type hint + /// ```edition2021 + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; + /// # + /// # enum X { + /// # Unit, + /// # Newtype, + /// # } + /// # + /// # impl<'de> VariantAccess<'de> for X { + /// # type Error = value::Error; + /// # + /// # fn unit_variant(self) -> Result<(), Self::Error> { + /// # unimplemented!() + /// # } + /// # + /// fn hint(&self) -> Option { + /// Some(match self { + /// Self::Unit => VariantHint::Unit, + /// Self::Newtype => VariantHint::Newtype, + /// }) + /// } + /// # + /// # fn newtype_variant_seed(self, _seed: T) -> Result + /// # where + /// # T: DeserializeSeed<'de>, + /// # { unimplemented!() } + /// # + /// # fn tuple_variant(self, _: usize, _: V) -> Result + /// # where + /// # V: Visitor<'de>, + /// # { unimplemented!() } + /// # + /// # fn struct_variant(self, _: &[&str], _: V) -> Result + /// # where + /// # V: Visitor<'de>, + /// # { unimplemented!() } + /// # } + /// ``` fn hint(&self) -> Option { None } From 92332738475b4e787d245c513cf975599420dc53 Mon Sep 17 00:00:00 2001 From: frederik Date: Thu, 27 Feb 2025 12:17:51 +0100 Subject: [PATCH 7/8] forgot import --- serde/src/de/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 4e68c580f..68ab61ca6 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -2051,7 +2051,7 @@ pub trait VariantAccess<'de>: Sized { /// `invalid_type` error should be constructed: /// /// ```edition2021 - /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, VariantHint, Unexpected}; /// # /// # struct X; /// # From a992e76ee48ad2afdaf71708acfbd679436fb262 Mon Sep 17 00:00:00 2001 From: frederik Date: Thu, 27 Feb 2025 12:27:36 +0100 Subject: [PATCH 8/8] fix import --- serde/src/de/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 68ab61ca6..d253a1711 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -2051,7 +2051,7 @@ pub trait VariantAccess<'de>: Sized { /// `invalid_type` error should be constructed: /// /// ```edition2021 - /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, VariantHint, Unexpected}; + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; /// # /// # struct X; /// # @@ -2141,7 +2141,7 @@ pub trait VariantAccess<'de>: Sized { /// Variant type hint /// ```edition2021 - /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, VariantHint, Unexpected}; /// # /// # enum X { /// # Unit, @@ -2155,7 +2155,7 @@ pub trait VariantAccess<'de>: Sized { /// # unimplemented!() /// # } /// # - /// fn hint(&self) -> Option { + /// fn hint(&self) -> Option { /// Some(match self { /// Self::Unit => VariantHint::Unit, /// Self::Newtype => VariantHint::Newtype,