api-macro: add VariantAttrib

separated out of FieldAttrib without the `flatten` attribute, since we
don't support this on enum variants

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2023-12-06 13:53:48 +01:00
parent fa9a50a0b7
commit 89b29415a4
2 changed files with 53 additions and 2 deletions

View File

@ -57,7 +57,7 @@ pub fn handle_enum(
comment = "<missing description>".to_string(); comment = "<missing description>".to_string();
} }
let attrs = serde::FieldAttrib::try_from(&variant.attrs[..])?; let attrs = serde::VariantAttrib::try_from(&variant.attrs[..])?;
let variant_string = if let Some(renamed) = attrs.rename { let variant_string = if let Some(renamed) = attrs.rename {
renamed renamed
} else if let Some(rename_all) = container_attrs.rename_all { } else if let Some(rename_all) = container_attrs.rename_all {

View File

@ -166,7 +166,7 @@ impl TryFrom<&[syn::Attribute]> for ContainerAttrib {
} }
} }
/// `serde` field/variant attributes we support /// `serde` field attributes we support
#[derive(Default)] #[derive(Default)]
pub struct FieldAttrib { pub struct FieldAttrib {
pub rename: Option<syn::LitStr>, pub rename: Option<syn::LitStr>,
@ -220,3 +220,54 @@ impl TryFrom<&[syn::Attribute]> for FieldAttrib {
Ok(this) Ok(this)
} }
} }
/// `serde` variant attributes we support
#[derive(Default)]
pub struct VariantAttrib {
pub rename: Option<syn::LitStr>,
}
impl VariantAttrib {
pub fn parse_attribute(&mut self, attrib: &syn::Attribute) -> Result<(), syn::Error> {
let list = match &attrib.meta {
syn::Meta::List(list) if list.path.is_ident("serde") => list,
_ => return Ok(()),
};
let args = list.parse_args_with(Punctuated::<syn::Meta, Token![,]>::parse_terminated)?;
for arg in args {
let path = arg.path();
if path.is_ident("rename") {
match &arg.require_name_value()?.value {
syn::Expr::Lit(syn::ExprLit {
lit: syn::Lit::Str(rename),
..
}) => {
if self.rename.is_some() && self.rename.as_ref() != Some(rename) {
error!(&rename => "multiple conflicting 'rename' attributes");
}
self.rename = Some(rename.clone());
}
value => error!(value => "'rename' value must be a string literal"),
}
}
}
Ok(())
}
}
impl TryFrom<&[syn::Attribute]> for VariantAttrib {
type Error = syn::Error;
fn try_from(attributes: &[syn::Attribute]) -> Result<Self, syn::Error> {
let mut this: Self = Default::default();
for attrib in attributes {
this.parse_attribute(attrib)?;
}
Ok(this)
}
}