use proc_macro2::TokenStream;
use quote::format_ident;
use quote::quote;
use syn::Ident;
use syn::Path;
use crate::attributes::SerdeContainerAttributes;
use crate::model::VariantData;
#[must_use]
#[inline(always)]
pub(super) fn serialized_variant_name(
variant: &VariantData<'_>,
container_attributes: &SerdeContainerAttributes,
) -> String {
let default_name = container_attributes.rename_variant(&variant.variant().ident.to_string());
variant.serde_attributes().rename_variant(default_name)
}
#[must_use]
pub(super) fn named_content_proxy(
variant_name: &Ident,
runtime: &Path,
serde: &Path,
names: &[String],
carriers: &[Ident],
) -> (TokenStream, TokenStream) {
let proxy = format_ident!("__QubitRedactAdjacent{variant_name}Content");
if carriers.is_empty() {
let definition = quote! {
struct #proxy;
impl #serde::Serialize for #proxy {
fn serialize<__Serializer>(
&self,
serializer: __Serializer,
) -> ::core::result::Result<
__Serializer::Ok,
__Serializer::Error,
>
where
__Serializer: #serde::Serializer,
{
#runtime::domain::internal::serialize_content(serializer, |serializer| {
let state = #serde::Serializer::serialize_struct(
serializer,
stringify!(#variant_name),
0,
)?;
#serde::ser::SerializeStruct::end(state)
})
}
}
};
return (definition, quote!(#proxy));
}
let value_types = (0..carriers.len())
.map(|index| format_ident!("__Value{index}"))
.collect::<Vec<_>>();
let value_fields = (0..carriers.len())
.map(|index| format_ident!("value_{index}"))
.collect::<Vec<_>>();
let count_fields = &value_fields;
let calls = names.iter().zip(&value_fields).map(|(name, value)| {
quote! {
if let ::core::option::Option::Some(value) = self.#value.as_ref() {
#serde::ser::SerializeStruct::serialize_field(
&mut state,
#name,
value,
)?;
}
}
});
let definition = quote! {
struct #proxy<#(#value_types),*> {
#(#value_fields: ::core::option::Option<#value_types>,)*
}
impl<#(#value_types),*> #serde::Serialize for #proxy<#(#value_types),*>
where
#(#value_types: #serde::Serialize,)*
{
fn serialize<__Serializer>(
&self,
serializer: __Serializer,
) -> ::core::result::Result<
__Serializer::Ok,
__Serializer::Error,
>
where
__Serializer: #serde::Serializer,
{
#runtime::domain::internal::serialize_content(serializer, |serializer| {
let mut field_count = 0usize;
#(
if self.#count_fields.is_some() {
field_count += 1;
}
)*
#runtime::domain::internal::admit_serializer_items(&serializer, field_count)?;
let mut state = #serde::Serializer::serialize_struct(
serializer,
stringify!(#variant_name),
field_count,
)?;
#(#calls)*
#serde::ser::SerializeStruct::end(state)
})
}
}
};
let value = quote! {
#proxy {
#(#value_fields: #carriers,)*
}
};
(definition, value)
}
#[must_use]
pub(super) fn tuple_content_proxy(
variant_name: &Ident,
runtime: &Path,
serde: &Path,
carriers: &[Ident],
) -> (TokenStream, TokenStream) {
let proxy = format_ident!("__QubitRedactAdjacent{variant_name}Content");
if carriers.is_empty() {
let definition = quote! {
struct #proxy;
impl #serde::Serialize for #proxy {
fn serialize<__Serializer>(
&self,
serializer: __Serializer,
) -> ::core::result::Result<
__Serializer::Ok,
__Serializer::Error,
>
where
__Serializer: #serde::Serializer,
{
#runtime::domain::internal::serialize_content(serializer, |serializer| {
let state = #serde::Serializer::serialize_tuple(serializer, 0)?;
#serde::ser::SerializeTuple::end(state)
})
}
}
};
return (definition, quote!(#proxy));
}
let value_types = (0..carriers.len())
.map(|index| format_ident!("__Value{index}"))
.collect::<Vec<_>>();
let value_fields = (0..carriers.len())
.map(|index| format_ident!("value_{index}"))
.collect::<Vec<_>>();
let count_fields = &value_fields;
let calls = value_fields.iter().map(|value| {
quote! {
if let ::core::option::Option::Some(value) = self.#value.as_ref() {
#serde::ser::SerializeTuple::serialize_element(
&mut state,
value,
)?;
}
}
});
let definition = quote! {
struct #proxy<#(#value_types),*> {
#(#value_fields: ::core::option::Option<#value_types>,)*
}
impl<#(#value_types),*> #serde::Serialize for #proxy<#(#value_types),*>
where
#(#value_types: #serde::Serialize,)*
{
fn serialize<__Serializer>(
&self,
serializer: __Serializer,
) -> ::core::result::Result<
__Serializer::Ok,
__Serializer::Error,
>
where
__Serializer: #serde::Serializer,
{
#runtime::domain::internal::serialize_content(serializer, |serializer| {
let mut field_count = 0usize;
#(
if self.#count_fields.is_some() {
field_count += 1;
}
)*
#runtime::domain::internal::admit_serializer_items(&serializer, field_count)?;
let mut state = #serde::Serializer::serialize_tuple(
serializer,
field_count,
)?;
#(#calls)*
#serde::ser::SerializeTuple::end(state)
})
}
}
};
let value = quote! {
#proxy {
#(#value_fields: #carriers,)*
}
};
(definition, value)
}