From: Wolfgang Bumiller Date: Wed, 6 Dec 2023 12:53:48 +0000 (+0100) Subject: api-macro: add VariantAttrib X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;ds=sidebyside;h=89b29415a44069f27e24b532c7b8fcfd89371179;p=proxmox.git 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 --- diff --git a/proxmox-api-macro/src/api/enums.rs b/proxmox-api-macro/src/api/enums.rs index 16dbbe7b..2ad7ac82 100644 --- a/proxmox-api-macro/src/api/enums.rs +++ b/proxmox-api-macro/src/api/enums.rs @@ -57,7 +57,7 @@ pub fn handle_enum( comment = "".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 { renamed } else if let Some(rename_all) = container_attrs.rename_all { diff --git a/proxmox-api-macro/src/serde.rs b/proxmox-api-macro/src/serde.rs index 4cb21ce7..d378405b 100644 --- a/proxmox-api-macro/src/serde.rs +++ b/proxmox-api-macro/src/serde.rs @@ -166,7 +166,7 @@ impl TryFrom<&[syn::Attribute]> for ContainerAttrib { } } -/// `serde` field/variant attributes we support +/// `serde` field attributes we support #[derive(Default)] pub struct FieldAttrib { pub rename: Option, @@ -220,3 +220,54 @@ impl TryFrom<&[syn::Attribute]> for FieldAttrib { Ok(this) } } + +/// `serde` variant attributes we support +#[derive(Default)] +pub struct VariantAttrib { + pub rename: Option, +} + +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::::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 { + let mut this: Self = Default::default(); + + for attrib in attributes { + this.parse_attribute(attrib)?; + } + + Ok(this) + } +}