Revisit of the representation of adjacently tagged enums tag

This commit is contained in:
Baptiste de Montangon
2023-07-31 20:53:02 +02:00
parent fe4e3fd3b0
commit 957ef206d1
6 changed files with 212 additions and 34 deletions
+62 -2
View File
@@ -1,10 +1,13 @@
use crate::lib::*;
use crate::de::value::{BorrowedBytesDeserializer, BytesDeserializer};
use crate::de::{Deserialize, Deserializer, Error, IntoDeserializer, Visitor};
use crate::de::{
Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error, IntoDeserializer, VariantAccess,
Visitor,
};
#[cfg(any(feature = "std", feature = "alloc"))]
use crate::de::{DeserializeSeed, MapAccess, Unexpected};
use crate::de::{MapAccess, Unexpected};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use self::content::{
@@ -2836,3 +2839,60 @@ fn flat_map_take_entry<'de>(
None
}
}
pub struct AdjacentlyTaggedEnumVariantSeed<F> {
pub tag: &'static str,
pub variants: &'static [&'static str],
pub fields_enum: PhantomData<F>,
}
pub struct AdjacentlyTaggedEnumVariantVisitor<F> {
tag: &'static str,
fields_enum: PhantomData<F>,
}
impl<'de, F> Visitor<'de> for AdjacentlyTaggedEnumVariantVisitor<F>
where
F: Deserialize<'de>,
{
type Value = F;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "enum {}", self.tag)
}
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
where
A: EnumAccess<'de>,
{
let (variant, variant_access) = match data.variant() {
Ok(values) => values,
Err(err) => return Err(err),
};
if let Err(err) = variant_access.unit_variant() {
return Err(err);
}
Ok(variant)
}
}
impl<'de, F> DeserializeSeed<'de> for AdjacentlyTaggedEnumVariantSeed<F>
where
F: Deserialize<'de>,
{
type Value = F;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_enum(
self.tag,
self.variants,
AdjacentlyTaggedEnumVariantVisitor {
tag: self.tag,
fields_enum: PhantomData,
},
)
}
}
+25
View File
@@ -1355,3 +1355,28 @@ where
Ok(())
}
}
pub struct AdjacentlyTaggedEnumVariantSerializer {
tag: &'static str,
variant_index: u32,
variant_name: &'static str,
}
impl AdjacentlyTaggedEnumVariantSerializer {
pub fn new(tag: &'static str, variant_index: u32, variant_name: &'static str) -> Self {
AdjacentlyTaggedEnumVariantSerializer {
tag,
variant_index,
variant_name,
}
}
}
impl Serialize for AdjacentlyTaggedEnumVariantSerializer {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_unit_variant(self.tag, self.variant_index, self.variant_name)
}
}