From f340968773a021e1fe8f81894de6d2ffe0e5534a Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Thu, 18 Jul 2019 14:52:25 +0200 Subject: [PATCH] macro: ability to rename enum variants via an attribute In PVE we have multiple different enum types: hyphenated, all-caps, underscores. By default our api-macro enums will convert CamelCase to underscores, so we need a way to represent the rest: enum AnEnum { CaseOne, // becomes "case_one", #[api(rename = "case-two")] CaseTwo, // "case-two", #[api(rename = "CASE_THREE")] CaseThree, } Signed-off-by: Wolfgang Bumiller --- proxmox-api-macro/src/api_macro.rs | 21 +++++++++++++++ proxmox-api-macro/src/types.rs | 4 --- proxmox-api-macro/src/util.rs | 43 +++++++++++++++++++++++++++++- 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/proxmox-api-macro/src/api_macro.rs b/proxmox-api-macro/src/api_macro.rs index c5529c10..327308eb 100644 --- a/proxmox-api-macro/src/api_macro.rs +++ b/proxmox-api-macro/src/api_macro.rs @@ -1,3 +1,5 @@ +use std::mem; + use proc_macro2::{Delimiter, Ident, Span, TokenStream, TokenTree}; use failure::{bail, format_err, Error}; @@ -596,6 +598,25 @@ fn handle_enum(mut definition: Object, item: &mut syn::ItemEnum) -> Result underscore_name = to, + //other => c_bail!(other.span(), "unsupported attribute on enum variant"), + } + } + } else { + variant.attrs.push(attr); + } + } display_entries.extend(quote_spanned! { span => #enum_ident::#variant_ident => write!(f, #underscore_name), diff --git a/proxmox-api-macro/src/types.rs b/proxmox-api-macro/src/types.rs index 2476d2a6..d404eab9 100644 --- a/proxmox-api-macro/src/types.rs +++ b/proxmox-api-macro/src/types.rs @@ -28,10 +28,6 @@ impl Name { &self.0 } - pub fn to_string(&self) -> String { - self.0.clone() - } - pub fn span(&self) -> Span { self.1.clone() } diff --git a/proxmox-api-macro/src/util.rs b/proxmox-api-macro/src/util.rs index 74857dc4..6ce00ed3 100644 --- a/proxmox-api-macro/src/util.rs +++ b/proxmox-api-macro/src/util.rs @@ -1,6 +1,6 @@ use proc_macro2::Ident; -use syn::Token; +use syn::{parenthesized, Token}; use syn::parse::{Parse, ParseStream}; use syn::punctuated::Punctuated; @@ -52,3 +52,44 @@ pub fn to_underscore_case(text: &str) -> String { out } + +pub struct ApiAttr { + pub paren_token: syn::token::Paren, + pub items: Punctuated, +} + +impl Parse for ApiAttr { + fn parse(input: ParseStream) -> syn::Result { + let content; + Ok(ApiAttr { + paren_token: parenthesized!(content in input), + items: content.parse_terminated(ApiItem::parse)?, + }) + } +} + +pub enum ApiItem { + Rename(syn::LitStr), +} + +impl Parse for ApiItem { + fn parse(input: ParseStream) -> syn::Result { + let what: Ident = input.parse()?; + let what_str = what.to_string(); + match what_str.as_str() { + "rename" => { + let _: Token![=] = input.parse()?; + Ok(ApiItem::Rename(input.parse()?)) + } + _ => c_bail!(what => "unrecognized api attribute: {}", what_str), + } + } +} + +//impl ApiItem { +// pub fn span(&self) -> Span { +// match self { +// ApiItem::Rename(x) => x.span(), +// } +// } +//}