diff --git a/proxmox-api-macro/src/api/enums.rs b/proxmox-api-macro/src/api/enums.rs index 1d3e34a0..e6c506b4 100644 --- a/proxmox-api-macro/src/api/enums.rs +++ b/proxmox-api-macro/src/api/enums.rs @@ -1,32 +1,16 @@ -use std::convert::TryInto; +use std::convert::{TryFrom, TryInto}; use failure::Error; use proc_macro2::{Ident, Span, TokenStream}; use quote::quote_spanned; -use syn::parse::{Parse, ParseStream}; use syn::punctuated::Punctuated; use syn::Token; use super::Schema; +use crate::serde::SerdeAttrib; use crate::util::{self, FieldName, JSONObject, JSONValue}; -/// `parse_macro_input!` expects a TokenStream_1 -struct AttrArgs { - _paren_token: syn::token::Paren, - args: Punctuated, -} - -impl Parse for AttrArgs { - fn parse(input: ParseStream) -> syn::Result { - let content; - Ok(Self { - _paren_token: syn::parenthesized!(content in input), - args: Punctuated::parse_terminated(&content)?, - }) - } -} - /// Enums, provided they're simple enums, simply get an enum string schema attached to them. pub fn handle_enum( mut attribs: JSONObject, @@ -65,27 +49,10 @@ pub fn handle_enum( _ => bail!(variant => "api macro does not support enums with fields"), } - let mut renamed = false; - for attrib in &variant.attrs { - if !attrib.path.is_ident("serde") { - continue; - } - - let args: AttrArgs = syn::parse2(attrib.tokens.clone())?; - for arg in args.args { - if let syn::NestedMeta::Meta(syn::Meta::NameValue(var)) = arg { - if var.path.is_ident("rename") { - match var.lit { - syn::Lit::Str(lit) => variants.push(lit), - _ => bail!(var.lit => "'rename' value must be a string literal"), - } - renamed = true; - } - } - } - } - - if !renamed { + let attrs = SerdeAttrib::try_from(&variant.attrs[..])?; + if let Some(renamed) = attrs.rename { + variants.push(renamed.into_lit_str()); + } else { let name = &variant.ident; variants.push(syn::LitStr::new(&name.to_string(), name.span())); } diff --git a/proxmox-api-macro/src/serde.rs b/proxmox-api-macro/src/serde.rs index 83709f6c..dbfaefe9 100644 --- a/proxmox-api-macro/src/serde.rs +++ b/proxmox-api-macro/src/serde.rs @@ -5,10 +5,6 @@ use std::convert::TryFrom; -use syn::parse::{Parse, ParseStream}; -use syn::punctuated::Punctuated; -use syn::Token; - use crate::util::{AttrArgs, FieldName}; /// Serde name types. @@ -127,7 +123,7 @@ impl RenameAll { /// `serde` container attributes we support #[derive(Default)] pub struct ContainerAttrib { - rename_all: Option, + pub rename_all: Option, } impl TryFrom<&[syn::Attribute]> for ContainerAttrib { @@ -162,7 +158,7 @@ impl TryFrom<&[syn::Attribute]> for ContainerAttrib { /// `serde` field/variant attributes we support #[derive(Default)] pub struct SerdeAttrib { - rename: Option, + pub rename: Option, } impl TryFrom<&[syn::Attribute]> for SerdeAttrib { diff --git a/proxmox-api-macro/src/util.rs b/proxmox-api-macro/src/util.rs index 9e420b16..0ff7535e 100644 --- a/proxmox-api-macro/src/util.rs +++ b/proxmox-api-macro/src/util.rs @@ -66,6 +66,10 @@ impl FieldName { pub fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.string.cmp(&other.string) } + + pub fn into_lit_str(self) -> syn::LitStr { + syn::LitStr::new(&self.string, self.ident.span()) + } } impl Eq for FieldName {}