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

View File

@ -498,15 +498,20 @@ fn handle_updater_field(
let span = Span::call_site(); let span = Span::call_site();
field_schema.optional = field.ty.clone().into(); field_schema.optional = field.ty.clone().into();
let updater = syn::TypePath { let updater = match updater_attrs.ty() {
qself: Some(syn::QSelf { Some(ty) => ty.clone(),
lt_token: syn::token::Lt { spans: [span] }, None => {
ty: Box::new(field.ty.clone()), syn::TypePath {
position: 2, // 'Updater' is item index 2 in the 'segments' below qself: Some(syn::QSelf {
as_token: Some(syn::token::As { span }), lt_token: syn::token::Lt { spans: [span] },
gt_token: syn::token::Gt { spans: [span] }, ty: Box::new(field.ty.clone()),
}), position: 2, // 'Updater' is item index 2 in the 'segments' below
path: util::make_path(span, true, &["proxmox_schema", "UpdaterType", "Updater"]), 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 // 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::collections::HashMap;
use std::convert::TryFrom; use std::convert::TryFrom;
use proc_macro2::{Ident, Span, TokenStream}; use proc_macro2::{Ident, Span, TokenStream, TokenTree};
use quote::ToTokens; use quote::ToTokens;
use syn::parse::{Parse, ParseStream}; use syn::parse::{Parse, ParseStream};
use syn::punctuated::Punctuated; 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) o.as_ref().map(|b| b.value).unwrap_or(false)
} }
/*
/// Parse the contents of a `LitStr`, preserving its span. /// Parse the contents of a `LitStr`, preserving its span.
pub fn parse_lit_str<T: Parse>(s: &syn::LitStr) -> syn::parse::Result<T> { pub fn parse_lit_str<T: Parse>(s: &syn::LitStr) -> syn::parse::Result<T> {
parse_str(&s.value(), s.span()) 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> { pub fn parse_str_value<T: Parse>(nv: &syn::MetaNameValue) -> Result<T, syn::Error> {
match &nv.lit { match &nv.lit {
syn::Lit::Str(s) => super::parse_lit_str(s), syn::Lit::Str(s) => super::parse_lit_str(s),