diff --git a/proxmox-api-macro/src/api/enums.rs b/proxmox-api-macro/src/api/enums.rs index 946dc6c3..6a673fa5 100644 --- a/proxmox-api-macro/src/api/enums.rs +++ b/proxmox-api-macro/src/api/enums.rs @@ -8,7 +8,7 @@ use syn::punctuated::Punctuated; use syn::Token; use super::Schema; -use crate::serde::{self, SerdeAttrib}; +use crate::serde; use crate::util::{self, FieldName, JSONObject, JSONValue}; /// Enums, provided they're simple enums, simply get an enum string schema attached to them. @@ -51,7 +51,7 @@ pub fn handle_enum( _ => bail!(variant => "api macro does not support enums with fields"), } - let attrs = SerdeAttrib::try_from(&variant.attrs[..])?; + let attrs = serde::SerdeAttrib::try_from(&variant.attrs[..])?; if let Some(renamed) = attrs.rename { variants.push(renamed.into_lit_str()); } else if let Some(rename_all) = container_attrs.rename_all { diff --git a/proxmox-api-macro/src/api/structs.rs b/proxmox-api-macro/src/api/structs.rs index 84533a26..254ca93b 100644 --- a/proxmox-api-macro/src/api/structs.rs +++ b/proxmox-api-macro/src/api/structs.rs @@ -1,5 +1,5 @@ use std::collections::HashMap; -use std::convert::TryInto; +use std::convert::{TryFrom, TryInto}; use failure::Error; @@ -8,6 +8,7 @@ use quote::quote_spanned; use super::Schema; use crate::api; +use crate::serde; use crate::util::{self, FieldName, JSONObject}; pub fn handle_struct(attribs: JSONObject, mut stru: syn::ItemStruct) -> Result { @@ -77,22 +78,35 @@ fn handle_regular_struct( let mut new_fields: Vec<(FieldName, bool, Schema)> = Vec::new(); + let container_attrs = serde::ContainerAttrib::try_from(&stru.attrs[..])?; + if let syn::Fields::Named(ref fields) = &stru.fields { for field in &fields.named { - let ident: &Ident = field - .ident - .as_ref() - .ok_or_else(|| format_err!(field => "field without name?"))?; + let attrs = serde::SerdeAttrib::try_from(&field.attrs[..])?; - let ident_name: String = ident.to_string(); + let (name, span) = { + let ident: &Ident = field + .ident + .as_ref() + .ok_or_else(|| format_err!(field => "field without name?"))?; - match schema_fields.remove(&ident_name) { + if let Some(renamed) = attrs.rename { + (renamed.into_str(), ident.span()) + } else if let Some(rename_all) = container_attrs.rename_all { + let name = rename_all.apply_to_field(&ident.to_string()); + (name, ident.span()) + } else { + (ident.to_string(), ident.span()) + } + }; + + match schema_fields.remove(&name) { Some(field_def) => handle_regular_field(field_def, field, false)?, None => { let mut field_def = ( - FieldName::new(ident_name.clone(), ident.span()), + FieldName::new(name.clone(), span), false, - Schema::blank(ident.span()), + Schema::blank(span), ); handle_regular_field(&mut field_def, field, true)?; new_fields.push(field_def); diff --git a/proxmox-api-macro/src/util.rs b/proxmox-api-macro/src/util.rs index 0ff7535e..a73f297e 100644 --- a/proxmox-api-macro/src/util.rs +++ b/proxmox-api-macro/src/util.rs @@ -70,6 +70,10 @@ impl FieldName { pub fn into_lit_str(self) -> syn::LitStr { syn::LitStr::new(&self.string, self.ident.span()) } + + pub fn into_str(self) -> String { + self.string + } } impl Eq for FieldName {}