api: support #[default] attribute
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
0719e1db1c
commit
38a60d3acb
@ -25,6 +25,8 @@ pub fn handle_enum(
|
||||
error!(fmt.span(), "illegal key 'format', will be autogenerated");
|
||||
}
|
||||
|
||||
let has_default_attrib = attribs.get("default").map(|def| def.span());
|
||||
|
||||
let schema = {
|
||||
let mut schema: Schema = attribs.try_into()?;
|
||||
|
||||
@ -39,6 +41,8 @@ pub fn handle_enum(
|
||||
};
|
||||
|
||||
let container_attrs = serde::ContainerAttrib::try_from(&enum_ty.attrs[..])?;
|
||||
let derives_default = util::derives_trait(&enum_ty.attrs, "Default");
|
||||
let mut default_value = None;
|
||||
|
||||
let mut variants = TokenStream::new();
|
||||
for variant in &mut enum_ty.variants {
|
||||
@ -64,6 +68,21 @@ pub fn handle_enum(
|
||||
syn::LitStr::new(&name.to_string(), name.span())
|
||||
};
|
||||
|
||||
if derives_default {
|
||||
if let Some(attr) = variant.attrs.iter().find(|a| a.path.is_ident("default")) {
|
||||
if let Some(default_value) = &default_value {
|
||||
error!(attr => "multiple default values defined");
|
||||
error!(default_value => "default previously defined here");
|
||||
} else {
|
||||
default_value = Some(variant_string.clone());
|
||||
if let Some(span) = has_default_attrib {
|
||||
error!(attr => "#[default] attribute in use with 'default' #[api] key");
|
||||
error!(span, "'default' also defined here");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variants.extend(quote_spanned! { variant.ident.span() =>
|
||||
::proxmox_schema::EnumEntry {
|
||||
value: #variant_string,
|
||||
@ -74,6 +93,11 @@ pub fn handle_enum(
|
||||
|
||||
let name = &enum_ty.ident;
|
||||
|
||||
let default_value = match default_value {
|
||||
Some(value) => quote_spanned!(value.span() => .default(#value)),
|
||||
None => TokenStream::new(),
|
||||
};
|
||||
|
||||
Ok(quote_spanned! { name.span() =>
|
||||
#enum_ty
|
||||
|
||||
@ -81,6 +105,7 @@ pub fn handle_enum(
|
||||
const API_SCHEMA: ::proxmox_schema::Schema =
|
||||
#schema
|
||||
.format(&::proxmox_schema::ApiStringFormat::Enum(&[#variants]))
|
||||
#default_value
|
||||
.schema();
|
||||
}
|
||||
|
||||
|
@ -404,7 +404,7 @@ fn derive_updater(
|
||||
let original_name = &original_struct.ident;
|
||||
stru.ident = Ident::new(&format!("{}Updater", stru.ident), stru.ident.span());
|
||||
|
||||
if !util::derived_items(&original_struct.attrs).any(|p| p.is_ident("Default")) {
|
||||
if !util::derives_trait(&original_struct.attrs, "Default") {
|
||||
stru.attrs.push(util::make_derive_attribute(
|
||||
Span::call_site(),
|
||||
quote::quote! { Default },
|
||||
|
@ -699,6 +699,11 @@ pub fn derived_items(attributes: &[syn::Attribute]) -> DerivedItems {
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper to check if a certain trait is being derived.
|
||||
pub fn derives_trait(attributes: &[syn::Attribute], ident: &str) -> bool {
|
||||
derived_items(&attributes).any(|p| p.is_ident(ident))
|
||||
}
|
||||
|
||||
/// Iterator over the types found in `#[derive(...)]` attributes.
|
||||
pub struct DerivedItems<'a> {
|
||||
current: Option<<Punctuated<syn::NestedMeta, Token![,]> as IntoIterator>::IntoIter>,
|
||||
|
@ -103,7 +103,7 @@ fn renamed_struct() {
|
||||
}
|
||||
|
||||
#[api]
|
||||
#[derive(Deserialize)]
|
||||
#[derive(Default, Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
/// A selection of either 'onekind', 'another-kind' or 'selection-number-three'.
|
||||
pub enum Selection {
|
||||
@ -111,6 +111,7 @@ pub enum Selection {
|
||||
#[serde(rename = "onekind")]
|
||||
OneKind,
|
||||
/// Some other kind.
|
||||
#[default]
|
||||
AnotherKind,
|
||||
/// And yet another.
|
||||
SelectionNumberThree,
|
||||
@ -126,6 +127,7 @@ fn selection_test() {
|
||||
EnumEntry::new("another-kind", "Some other kind."),
|
||||
EnumEntry::new("selection-number-three", "And yet another."),
|
||||
]))
|
||||
.default("another-kind")
|
||||
.schema();
|
||||
|
||||
assert_eq!(TEST_SCHEMA, Selection::API_SCHEMA);
|
||||
|
Loading…
Reference in New Issue
Block a user