summaryrefslogtreecommitdiffstats
path: root/third_party/rust/serde_with/src/enum_map.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/serde_with/src/enum_map.rs')
-rw-r--r--third_party/rust/serde_with/src/enum_map.rs888
1 files changed, 888 insertions, 0 deletions
diff --git a/third_party/rust/serde_with/src/enum_map.rs b/third_party/rust/serde_with/src/enum_map.rs
new file mode 100644
index 0000000000..ef65f8985f
--- /dev/null
+++ b/third_party/rust/serde_with/src/enum_map.rs
@@ -0,0 +1,888 @@
+use crate::{
+ content::ser::{Content, ContentSerializer},
+ DeserializeAs, SerializeAs,
+};
+use alloc::{string::ToString, vec::Vec};
+use core::{fmt, marker::PhantomData};
+use serde::{
+ de::{DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor},
+ ser,
+ ser::{Impossible, SerializeMap, SerializeSeq, SerializeStructVariant, SerializeTupleVariant},
+ Deserialize, Deserializer, Serialize, Serializer,
+};
+
+/// Represent a list of enum values as a map.
+///
+/// This **only works** if the enum uses the default *externally tagged* representation.
+/// Other enum representations are not supported.
+///
+/// serde data formats often represent *externally tagged* enums as maps with a single key.
+/// The key is the enum variant name, and the value is the variant value.
+/// Sometimes a map with multiple keys should be treated like a list of enum values.
+///
+/// # Examples
+///
+/// ## JSON Map with multiple keys
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// use serde_with::EnumMap;
+///
+/// # #[derive(Debug, Clone, PartialEq, Eq)]
+/// #[derive(Serialize, Deserialize)]
+/// enum EnumValue {
+/// Int(i32),
+/// String(String),
+/// Unit,
+/// Tuple(i32, String, bool),
+/// Struct {
+/// a: i32,
+/// b: String,
+/// c: bool,
+/// },
+/// }
+///
+/// #[serde_with::serde_as]
+/// # #[derive(Debug, Clone, PartialEq, Eq)]
+/// #[derive(Serialize, Deserialize)]
+/// struct VecEnumValues (
+/// #[serde_as(as = "EnumMap")]
+/// Vec<EnumValue>,
+/// );
+///
+/// // ---
+///
+/// // This will serialize this list of values
+/// let values = VecEnumValues(vec![
+/// EnumValue::Int(123),
+/// EnumValue::String("FooBar".to_string()),
+/// EnumValue::Int(456),
+/// EnumValue::String("XXX".to_string()),
+/// EnumValue::Unit,
+/// EnumValue::Tuple(1, "Middle".to_string(), false),
+/// EnumValue::Struct {
+/// a: 666,
+/// b: "BBB".to_string(),
+/// c: true,
+/// },
+/// ]);
+///
+/// // into this JSON map
+/// // Duplicate keys are emitted for identical enum variants.
+/// let expected =
+/// r#"{
+/// "Int": 123,
+/// "String": "FooBar",
+/// "Int": 456,
+/// "String": "XXX",
+/// "Unit": null,
+/// "Tuple": [
+/// 1,
+/// "Middle",
+/// false
+/// ],
+/// "Struct": {
+/// "a": 666,
+/// "b": "BBB",
+/// "c": true
+/// }
+/// }"#;
+///
+/// // Both serialization and deserialization work flawlessly.
+/// let serialized = serde_json::to_string_pretty(&values).unwrap();
+/// assert_eq!(expected, serialized);
+/// let deserialized: VecEnumValues = serde_json::from_str(&serialized).unwrap();
+/// assert_eq!(values, deserialized);
+/// # }
+/// ```
+///
+/// ## XML structure with varying keys
+///
+/// With `serde_xml_rs` tuple and struct variants are not supported since they fail to roundtrip.
+/// The enum may have such variants as long as they are not serialized or deserialized.
+///
+/// ```
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// use serde_with::EnumMap;
+///
+/// # #[derive(Debug, Clone, PartialEq, Eq)]
+/// #[derive(Serialize, Deserialize)]
+/// enum EnumValue {
+/// Int(i32),
+/// String(String),
+/// Unit,
+/// }
+///
+/// #[serde_with::serde_as]
+/// # #[derive(Debug, Clone, PartialEq, Eq)]
+/// #[derive(Serialize, Deserialize)]
+/// struct VecEnumValues {
+/// #[serde_as(as = "EnumMap")]
+/// vec: Vec<EnumValue>,
+/// }
+///
+/// // ---
+///
+/// // This will serialize this list of values
+/// let values = VecEnumValues {
+/// vec: vec![
+/// EnumValue::Int(123),
+/// EnumValue::String("FooBar".to_string()),
+/// EnumValue::Int(456),
+/// EnumValue::String("XXX".to_string()),
+/// EnumValue::Unit,
+/// ],
+/// };
+///
+/// // into this XML document
+/// // Duplicate keys are emitted for identical enum variants.
+/// let expected = r#"
+/// <VecEnumValues>
+/// <vec>
+/// <Int>123</Int>
+/// <String>FooBar</String>
+/// <Int>456</Int>
+/// <String>XXX</String>
+/// <Unit></Unit>
+/// </vec>
+/// </VecEnumValues>"#
+/// // Remove whitespace
+/// .replace(' ', "")
+/// .replace('\n', "");
+///
+/// // Both serialization and deserialization work flawlessly.
+/// let serialized = serde_xml_rs::to_string(&values).unwrap();
+/// assert_eq!(expected, serialized);
+/// let deserialized: VecEnumValues = serde_xml_rs::from_str(&serialized).unwrap();
+/// assert_eq!(values, deserialized);
+/// # }
+/// ```
+#[derive(Debug, Copy, Clone)]
+pub struct EnumMap;
+
+impl<T> SerializeAs<Vec<T>> for EnumMap
+where
+ T: Serialize,
+{
+ fn serialize_as<S>(source: &Vec<T>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ source.serialize(SeqAsMapSerializer(serializer))
+ }
+}
+
+impl<'de, T> DeserializeAs<'de, Vec<T>> for EnumMap
+where
+ T: Deserialize<'de>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<Vec<T>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct EnumMapVisitor<T>(PhantomData<T>);
+
+ impl<'de, T> Visitor<'de> for EnumMapVisitor<T>
+ where
+ T: Deserialize<'de>,
+ {
+ type Value = Vec<T>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(formatter, "a map or enum values")
+ }
+
+ fn visit_map<A: MapAccess<'de>>(self, map: A) -> Result<Self::Value, A::Error> {
+ Vec::deserialize(SeqDeserializer(map))
+ }
+ }
+
+ deserializer.deserialize_map(EnumMapVisitor(PhantomData))
+ }
+}
+
+static END_OF_MAP_IDENTIFIER: &str = "__PRIVATE_END_OF_MAP_MARKER__";
+
+// Serialization code below here
+
+/// Convert a sequence to a map during serialization.
+///
+/// Only `serialize_seq` is implemented and forwarded to `serialize_map` on the inner `Serializer`.
+/// The elements are serialized with [`SerializeSeqElement`].
+struct SeqAsMapSerializer<S>(S);
+
+impl<S> Serializer for SeqAsMapSerializer<S>
+where
+ S: Serializer,
+{
+ type Ok = S::Ok;
+ type Error = S::Error;
+
+ type SerializeSeq = SerializeSeqElement<S::SerializeMap>;
+ type SerializeTuple = Impossible<S::Ok, S::Error>;
+ type SerializeTupleStruct = Impossible<S::Ok, S::Error>;
+ type SerializeTupleVariant = Impossible<S::Ok, S::Error>;
+ type SerializeMap = Impossible<S::Ok, S::Error>;
+ type SerializeStruct = Impossible<S::Ok, S::Error>;
+ type SerializeStructVariant = Impossible<S::Ok, S::Error>;
+
+ fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i128(self, _v: i128) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u128(self, _v: u128) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_str(self, _v: &str) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize,
+ {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ ) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_newtype_struct<T: ?Sized>(
+ self,
+ _name: &'static str,
+ _value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize,
+ {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_newtype_variant<T: ?Sized>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize,
+ {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
+ let is_human_readable = self.0.is_human_readable();
+ self.0
+ .serialize_map(len)
+ .map(|delegate| SerializeSeqElement {
+ delegate,
+ is_human_readable,
+ })
+ }
+
+ fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleStruct, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleVariant, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStruct, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStructVariant, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+}
+
+/// Serialize a single element but turn the sequence into a map logic.
+///
+/// It uses [`SerializeEnumAsMapElement`] for the map element serialization.
+///
+/// The [`Serializer`] implementation handles all the `serialize_*_variant` functions and defers to [`SerializeVariant`] for the more complicated tuple and struct variants.
+struct SerializeSeqElement<M> {
+ delegate: M,
+ is_human_readable: bool,
+}
+
+impl<M> SerializeSeq for SerializeSeqElement<M>
+where
+ M: SerializeMap,
+{
+ type Ok = M::Ok;
+ type Error = M::Error;
+
+ fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
+ where
+ T: Serialize,
+ {
+ value.serialize(EnumAsMapElementSerializer {
+ delegate: &mut self.delegate,
+ is_human_readable: self.is_human_readable,
+ })?;
+ Ok(())
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ self.delegate.end()
+ }
+}
+
+struct EnumAsMapElementSerializer<'a, M> {
+ delegate: &'a mut M,
+ is_human_readable: bool,
+}
+
+impl<'a, M> Serializer for EnumAsMapElementSerializer<'a, M>
+where
+ M: SerializeMap,
+{
+ type Ok = ();
+ type Error = M::Error;
+
+ type SerializeSeq = Impossible<Self::Ok, Self::Error>;
+ type SerializeTuple = Impossible<Self::Ok, Self::Error>;
+ type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
+ type SerializeTupleVariant = SerializeVariant<'a, M>;
+ type SerializeMap = Impossible<Self::Ok, Self::Error>;
+ type SerializeStruct = Impossible<Self::Ok, Self::Error>;
+ type SerializeStructVariant = SerializeVariant<'a, M>;
+
+ fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i128(self, _v: i128) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u128(self, _v: u128) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_str(self, _v: &str) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize,
+ {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ ) -> Result<Self::Ok, Self::Error> {
+ self.delegate.serialize_entry(variant, &())?;
+ Ok(())
+ }
+
+ fn serialize_newtype_struct<T: ?Sized>(
+ self,
+ _name: &'static str,
+ _value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize,
+ {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_newtype_variant<T: ?Sized>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize,
+ {
+ self.delegate.serialize_entry(variant, value)?;
+ Ok(())
+ }
+
+ fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleStruct, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleVariant, Self::Error> {
+ Ok(SerializeVariant {
+ delegate: self.delegate,
+ is_human_readable: self.is_human_readable,
+ variant,
+ content: Content::TupleStruct(name, Vec::with_capacity(len)),
+ })
+ }
+
+ fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStruct, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_struct_variant(
+ self,
+ name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStructVariant, Self::Error> {
+ Ok(SerializeVariant {
+ delegate: self.delegate,
+ is_human_readable: self.is_human_readable,
+ variant,
+ content: Content::Struct(name, Vec::with_capacity(len)),
+ })
+ }
+}
+
+/// Serialize a struct or tuple variant enum as a map element
+///
+/// [`SerializeStructVariant`] serializes a struct variant, and [`SerializeTupleVariant`] a tuple variant.
+struct SerializeVariant<'a, M> {
+ delegate: &'a mut M,
+ is_human_readable: bool,
+ variant: &'static str,
+ content: Content,
+}
+
+impl<'a, M> SerializeStructVariant for SerializeVariant<'a, M>
+where
+ M: SerializeMap,
+{
+ type Ok = ();
+
+ type Error = M::Error;
+
+ fn serialize_field<T: ?Sized>(
+ &mut self,
+ key: &'static str,
+ value: &T,
+ ) -> Result<(), Self::Error>
+ where
+ T: Serialize,
+ {
+ // Serialize to a Content type first
+ let value: Content = value.serialize(ContentSerializer::new(self.is_human_readable))?;
+ if let Content::Struct(_name, fields) = &mut self.content {
+ fields.push((key, value));
+ }
+ Ok(())
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ self.delegate.serialize_entry(&self.variant, &self.content)
+ }
+}
+
+impl<'a, M> SerializeTupleVariant for SerializeVariant<'a, M>
+where
+ M: SerializeMap,
+{
+ type Ok = ();
+
+ type Error = M::Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
+ where
+ T: Serialize,
+ {
+ // Serialize to a Content type first
+ let value: Content = value.serialize(ContentSerializer::new(self.is_human_readable))?;
+ if let Content::TupleStruct(_name, fields) = &mut self.content {
+ fields.push(value);
+ }
+ Ok(())
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ self.delegate.serialize_entry(&self.variant, &self.content)
+ }
+}
+
+// Below is deserialization code
+
+/// Deserialize the sequence of enum instances.
+///
+/// The main [`Deserializer`] implementation handles the outer sequence (e.g., `Vec`), while the [`SeqAccess`] implementation is responsible for the inner elements.
+struct SeqDeserializer<M>(M);
+
+impl<'de, M> Deserializer<'de> for SeqDeserializer<M>
+where
+ M: MapAccess<'de>,
+{
+ type Error = M::Error;
+
+ fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_seq(self)
+ }
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_seq(visitor)
+ }
+
+ serde::forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+}
+
+impl<'de, M> SeqAccess<'de> for SeqDeserializer<M>
+where
+ M: MapAccess<'de>,
+{
+ type Error = M::Error;
+
+ fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match seed.deserialize(EnumDeserializer(&mut self.0)) {
+ Ok(value) => Ok(Some(value)),
+ Err(err) => {
+ // Unfortunately we loose the optional aspect of MapAccess, so we need to special case an error value to mark the end of the map.
+ if err.to_string().contains(END_OF_MAP_IDENTIFIER) {
+ Ok(None)
+ } else {
+ Err(err)
+ }
+ }
+ }
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ self.0.size_hint()
+ }
+}
+
+/// Deserialize an enum from a map element
+///
+/// The [`Deserializer`] implementation is the starting point, which first calls the [`EnumAccess`] methods.
+/// The [`EnumAccess`] is used to deserialize the enum variant type of the enum.
+/// The [`VariantAccess`] is used to deserialize the value part of the enum.
+struct EnumDeserializer<M>(M);
+
+impl<'de, M> Deserializer<'de> for EnumDeserializer<M>
+where
+ M: MapAccess<'de>,
+{
+ type Error = M::Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_enum("", &[], visitor)
+ }
+
+ fn deserialize_enum<V>(
+ self,
+ _name: &'static str,
+ _variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_enum(self)
+ }
+
+ serde::forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct identifier ignored_any
+ }
+}
+
+impl<'de, M> EnumAccess<'de> for EnumDeserializer<M>
+where
+ M: MapAccess<'de>,
+{
+ type Error = M::Error;
+ type Variant = Self;
+
+ fn variant_seed<T>(mut self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.0.next_key_seed(seed)? {
+ Some(key) => Ok((key, self)),
+
+ // Unfortunately we loose the optional aspect of MapAccess, so we need to special case an error value to mark the end of the map.
+ None => Err(Error::custom(END_OF_MAP_IDENTIFIER)),
+ }
+ }
+}
+
+impl<'de, M> VariantAccess<'de> for EnumDeserializer<M>
+where
+ M: MapAccess<'de>,
+{
+ type Error = M::Error;
+
+ fn unit_variant(mut self) -> Result<(), Self::Error> {
+ self.0.next_value()
+ }
+
+ fn newtype_variant_seed<T>(mut self, seed: T) -> Result<T::Value, Self::Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ self.0.next_value_seed(seed)
+ }
+
+ fn tuple_variant<V>(mut self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.0.next_value_seed(SeedTupleVariant { len, visitor })
+ }
+
+ fn struct_variant<V>(
+ mut self,
+ _fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.0.next_value_seed(SeedStructVariant { visitor })
+ }
+}
+
+struct SeedTupleVariant<V> {
+ len: usize,
+ visitor: V,
+}
+
+impl<'de, V> DeserializeSeed<'de> for SeedTupleVariant<V>
+where
+ V: Visitor<'de>,
+{
+ type Value = V::Value;
+
+ fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_tuple(self.len, self.visitor)
+ }
+}
+
+struct SeedStructVariant<V> {
+ visitor: V,
+}
+
+impl<'de, V> DeserializeSeed<'de> for SeedStructVariant<V>
+where
+ V: Visitor<'de>,
+{
+ type Value = V::Value;
+
+ fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_map(self.visitor)
+ }
+}