api-macro: add #[updater(type = "...")]

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2021-11-30 17:21:20 +01:00
parent e461be1c9f
commit fc80f519f4
3 changed files with 24 additions and 19 deletions

View File

@ -1,13 +1,13 @@
use syn::{Meta, NestedMeta};
use crate::util::{self, default_false, set_bool};
use crate::util::{self, default_false, parse_str_value_to_option, set_bool};
#[derive(Default)]
pub struct UpdaterFieldAttributes {
/// Skip this field in the updater.
skip: Option<syn::LitBool>,
// /// Change the type for the updater.
// ty: Option<syn::Type>,
ty: Option<syn::TypePath>,
}
impl UpdaterFieldAttributes {
@ -31,9 +31,9 @@ impl UpdaterFieldAttributes {
Meta::Path(ref path) if path.is_ident("skip") => {
set_bool(&mut self.skip, path, true);
}
// Meta::NameValue(ref nv) if nv.path.is_ident("type") => {
// parse_str_value_to_option(&mut self.ty, nv)
// }
Meta::NameValue(ref nv) if nv.path.is_ident("type") => {
parse_str_value_to_option(&mut self.ty, nv)
}
Meta::NameValue(m) => bail!(&m => "invalid updater attribute: {:?}", m.path),
Meta::List(m) => bail!(&m => "invalid updater attribute: {:?}", m.path),
Meta::Path(m) => bail!(&m => "invalid updater attribute: {:?}", m),
@ -46,7 +46,7 @@ impl UpdaterFieldAttributes {
default_false(self.skip.as_ref())
}
//pub fn ty(&self) -> Option<&syn::Type> {
// self.ty.as_ref()
//}
pub fn ty(&self) -> Option<&syn::TypePath> {
self.ty.as_ref()
}
}

View File

@ -498,15 +498,20 @@ fn handle_updater_field(
let span = Span::call_site();
field_schema.optional = field.ty.clone().into();
let updater = syn::TypePath {
qself: Some(syn::QSelf {
lt_token: syn::token::Lt { spans: [span] },
ty: Box::new(field.ty.clone()),
position: 2, // 'Updater' is item index 2 in the 'segments' below
as_token: Some(syn::token::As { span }),
gt_token: syn::token::Gt { spans: [span] },
}),
path: util::make_path(span, true, &["proxmox_schema", "UpdaterType", "Updater"]),
let updater = match updater_attrs.ty() {
Some(ty) => ty.clone(),
None => {
syn::TypePath {
qself: Some(syn::QSelf {
lt_token: syn::token::Lt { spans: [span] },
ty: Box::new(field.ty.clone()),
position: 2, // 'Updater' is item index 2 in the 'segments' below
as_token: Some(syn::token::As { span }),
gt_token: syn::token::Gt { spans: [span] },
}),
path: util::make_path(span, true, &["proxmox_schema", "UpdaterType", "Updater"]),
}
}
};
// we also need to update the schema to point to the updater's schema for `type: Foo` entries

View File

@ -2,7 +2,7 @@ use std::borrow::Borrow;
use std::collections::HashMap;
use std::convert::TryFrom;
use proc_macro2::{Ident, Span, TokenStream};
use proc_macro2::{Ident, Span, TokenStream, TokenTree};
use quote::ToTokens;
use syn::parse::{Parse, ParseStream};
use syn::punctuated::Punctuated;
@ -872,7 +872,6 @@ pub fn default_false(o: Option<&syn::LitBool>) -> bool {
o.as_ref().map(|b| b.value).unwrap_or(false)
}
/*
/// Parse the contents of a `LitStr`, preserving its span.
pub fn parse_lit_str<T: Parse>(s: &syn::LitStr) -> syn::parse::Result<T> {
parse_str(&s.value(), s.span())
@ -918,6 +917,7 @@ pub fn parse_str_value_to_option<T: Parse>(target: &mut Option<T>, nv: &syn::Met
}
}
/*
pub fn parse_str_value<T: Parse>(nv: &syn::MetaNameValue) -> Result<T, syn::Error> {
match &nv.lit {
syn::Lit::Str(s) => super::parse_lit_str(s),