forked from proxmox-mirrors/proxmox
api-macro: parse serde(rename) on enums
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
30a1c0b9ae
commit
7d6fac0fa5
@ -1,16 +1,32 @@
|
|||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::mem;
|
|
||||||
|
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
|
|
||||||
use proc_macro2::{Ident, Span, TokenStream};
|
use proc_macro2::{Ident, Span, TokenStream};
|
||||||
use quote::{quote, quote_spanned};
|
use quote::quote_spanned;
|
||||||
|
use syn::parse::{Parse, ParseStream};
|
||||||
use syn::punctuated::Punctuated;
|
use syn::punctuated::Punctuated;
|
||||||
use syn::Token;
|
use syn::Token;
|
||||||
|
|
||||||
use super::Schema;
|
use super::Schema;
|
||||||
use crate::util::{JSONObject, JSONValue, SimpleIdent};
|
use crate::util::{JSONObject, JSONValue, SimpleIdent};
|
||||||
|
|
||||||
|
/// `parse_macro_input!` expects a TokenStream_1
|
||||||
|
struct AttrArgs {
|
||||||
|
paren_token: syn::token::Paren,
|
||||||
|
args: Punctuated<syn::NestedMeta, Token![,]>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parse for AttrArgs {
|
||||||
|
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||||
|
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.
|
/// Enums, provided they're simple enums, simply get an enum string schema attached to them.
|
||||||
pub fn handle_enum(
|
pub fn handle_enum(
|
||||||
mut attribs: JSONObject,
|
mut attribs: JSONObject,
|
||||||
@ -45,30 +61,24 @@ pub fn handle_enum(
|
|||||||
|
|
||||||
let mut renamed = false;
|
let mut renamed = false;
|
||||||
for attrib in &mut variant.attrs {
|
for attrib in &mut variant.attrs {
|
||||||
if !attrib.path.is_ident("api") {
|
if !attrib.path.is_ident("serde") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
attrib.path = syn::parse2(quote! { serde })?;
|
let args: AttrArgs = syn::parse2(attrib.tokens.clone())?;
|
||||||
|
for arg in args.args {
|
||||||
let mut obj: JSONObject =
|
match arg {
|
||||||
syn::parse2(mem::replace(&mut attrib.tokens, TokenStream::new()))?;
|
syn::NestedMeta::Meta(syn::Meta::NameValue(var)) => {
|
||||||
match obj.remove("rename") {
|
if var.path.is_ident("rename") {
|
||||||
Some(JSONValue::Expr(syn::Expr::Lit(lit))) => {
|
match var.lit {
|
||||||
if let syn::Lit::Str(lit) = lit.lit {
|
syn::Lit::Str(lit) => variants.push(lit),
|
||||||
attrib.tokens.extend(quote! { rename = #lit });
|
_ => bail!(var.lit => "'rename' value must be a string literal"),
|
||||||
variants.push(lit);
|
}
|
||||||
renamed = true;
|
renamed = true;
|
||||||
} else {
|
}
|
||||||
bail!(attrib => "'rename' must be a literal string");
|
|
||||||
}
|
}
|
||||||
|
_ => (), // ignore
|
||||||
}
|
}
|
||||||
Some(_) => bail!(attrib => "'rename' must be a literal string"),
|
|
||||||
None => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
if !obj.is_empty() {
|
|
||||||
bail!(attrib => "unknown fields in attribute");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ use proxmox::api::schema;
|
|||||||
use proxmox_api_macro::api;
|
use proxmox_api_macro::api;
|
||||||
|
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
//use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
#[api(
|
#[api(
|
||||||
@ -24,7 +24,9 @@ impl OkString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[api(description: "A selection of either A, B or C")]
|
#[api(description: "A selection of either A, B or C")]
|
||||||
|
#[derive(Deserialize)]
|
||||||
pub enum Selection {
|
pub enum Selection {
|
||||||
|
#[serde(rename = "a")]
|
||||||
A,
|
A,
|
||||||
B,
|
B,
|
||||||
C,
|
C,
|
||||||
|
Loading…
Reference in New Issue
Block a user