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
+15 -3
View File
@@ -1510,6 +1510,14 @@ fn deserialize_adjacently_tagged_enum(
}
};
let variant_seed = quote! {
_serde::__private::de::AdjacentlyTaggedEnumVariantSeed::<__Field> {
tag: #tag,
variants: &VARIANTS,
fields_enum: _serde::__private::PhantomData
}
};
let mut missing_content = quote! {
_serde::__private::Err(<__A::Error as _serde::de::Error>::missing_field(#content))
};
@@ -1557,6 +1565,10 @@ fn deserialize_adjacently_tagged_enum(
_serde::de::MapAccess::next_key_seed(&mut __map, #tag_or_content)?
};
let variant_from_map = quote! {
_serde::de::MapAccess::next_value_seed(&mut __map, #variant_seed)?
};
// When allowing unknown fields, we want to transparently step through keys
// we don't care about until we find `tag`, `content`, or run out of keys.
let next_relevant_key = if deny_unknown_fields {
@@ -1602,11 +1614,11 @@ fn deserialize_adjacently_tagged_enum(
let finish_content_then_tag = if variant_arms.is_empty() {
quote! {
match _serde::de::MapAccess::next_value::<__Field>(&mut __map)? {}
match #variant_from_map {}
}
} else {
quote! {
let __ret = match _serde::de::MapAccess::next_value(&mut __map)? {
let __ret = match #variant_from_map {
// Deserialize the buffered content now that we know the variant.
#(#variant_arms)*
}?;
@@ -1662,7 +1674,7 @@ fn deserialize_adjacently_tagged_enum(
// First key is the tag.
_serde::__private::Some(_serde::__private::de::TagOrContentField::Tag) => {
// Parse the tag.
let __field = _serde::de::MapAccess::next_value(&mut __map)?;
let __field = #variant_from_map;
// Visit the second key.
match #next_relevant_key {
// Second key is a duplicate of the tag.
+13 -4
View File
@@ -478,7 +478,14 @@ fn serialize_variant(
serialize_internally_tagged_variant(params, variant, cattrs, tag)
}
(attr::TagType::Adjacent { tag, content }, false) => {
serialize_adjacently_tagged_variant(params, variant, cattrs, tag, content)
serialize_adjacently_tagged_variant(
params,
variant,
cattrs,
variant_index,
tag,
content,
)
}
(attr::TagType::None, _) | (_, true) => {
serialize_untagged_variant(params, variant, cattrs)
@@ -634,12 +641,14 @@ fn serialize_adjacently_tagged_variant(
params: &Parameters,
variant: &Variant,
cattrs: &attr::Container,
variant_index: u32,
tag: &str,
content: &str,
) -> Fragment {
let this_type = &params.this_type;
let type_name = cattrs.name().serialize_name();
let variant_name = variant.attrs.name().serialize_name();
let variant_serializer = quote!(&_serde::__private::ser::AdjacentlyTaggedEnumVariantSerializer::new(#tag, #variant_index, #variant_name));
let inner = Stmts(if let Some(path) = variant.attrs.serialize_with() {
let ser = wrap_serialize_variant_with(params, path, variant);
@@ -653,7 +662,7 @@ fn serialize_adjacently_tagged_variant(
let mut __struct = _serde::Serializer::serialize_struct(
__serializer, #type_name, 1)?;
_serde::ser::SerializeStruct::serialize_field(
&mut __struct, #tag, #variant_name)?;
&mut __struct, #tag, #variant_serializer)?;
_serde::ser::SerializeStruct::end(__struct)
};
}
@@ -670,7 +679,7 @@ fn serialize_adjacently_tagged_variant(
let mut __struct = _serde::Serializer::serialize_struct(
__serializer, #type_name, 2)?;
_serde::ser::SerializeStruct::serialize_field(
&mut __struct, #tag, #variant_name)?;
&mut __struct, #tag, #variant_serializer)?;
#func(
&mut __struct, #content, #field_expr)?;
_serde::ser::SerializeStruct::end(__struct)
@@ -735,7 +744,7 @@ fn serialize_adjacently_tagged_variant(
let mut __struct = _serde::Serializer::serialize_struct(
__serializer, #type_name, 2)?;
_serde::ser::SerializeStruct::serialize_field(
&mut __struct, #tag, #variant_name)?;
&mut __struct, #tag, #variant_serializer)?;
_serde::ser::SerializeStruct::serialize_field(
&mut __struct, #content, &__AdjacentlyTagged {
data: (#(#fields_ident,)*),