use syn::Attribute;
use crate::serde_attrs::model::{SerdeContainerAttrs, SerdeVariantAttrs};
use crate::syntax::{consume_unused_meta, parse_string_value, unraw};
use super::rename_meta::parse_rename_meta;
pub(crate) fn parse_serde_variant_attrs(
attributes: &[Attribute],
variant_ident: &syn::Ident,
container_attrs: &SerdeContainerAttrs,
) -> syn::Result<SerdeVariantAttrs> {
let base_name = unraw(variant_ident);
let mut rename_serialize = None;
let mut rename_deserialize = None;
let mut aliases = Vec::new();
let mut skip_metadata = false;
for attribute in attributes {
if !attribute.path().is_ident("serde") {
continue;
}
attribute.parse_nested_meta(|meta| {
if meta.path.is_ident("rename") {
parse_rename_meta(meta, &mut rename_serialize, &mut rename_deserialize)?;
return Ok(());
}
if meta.path.is_ident("alias") {
aliases.push(parse_string_value(meta)?);
return Ok(());
}
if meta.path.is_ident("skip")
|| meta.path.is_ident("skip_deserializing")
|| meta.path.is_ident("other")
{
skip_metadata = true;
consume_unused_meta(meta)?;
return Ok(());
}
consume_unused_meta(meta)?;
Ok(())
})?;
}
let canonical_name = rename_serialize
.or_else(|| {
container_attrs
.rename_all_serialize
.map(|rule| rule.apply_to_variant(&base_name))
})
.unwrap_or_else(|| base_name.clone());
let deserialize_name = rename_deserialize
.or_else(|| {
container_attrs
.rename_all_deserialize
.map(|rule| rule.apply_to_variant(&base_name))
})
.unwrap_or_else(|| base_name.clone());
if deserialize_name != canonical_name {
aliases.push(deserialize_name);
}
aliases.retain(|alias| alias != &canonical_name);
aliases.sort();
aliases.dedup();
Ok(SerdeVariantAttrs {
canonical_name,
aliases,
skip_metadata,
})
}