api-macro: start using serde attribute helpers

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2020-01-07 15:23:52 +01:00
parent 799c993d63
commit dd5cd3f311
3 changed files with 12 additions and 45 deletions

View File

@ -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<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.
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()));
}

View File

@ -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<RenameAll>,
pub rename_all: Option<RenameAll>,
}
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<FieldName>,
pub rename: Option<FieldName>,
}
impl TryFrom<&[syn::Attribute]> for SerdeAttrib {

View File

@ -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 {}