forked from proxmox-mirrors/proxmox
put API_SCHEMA variable into ApiType trait
This way we can assign `API_SCHEMA` constants to `Option` types. Here's why: The api-macro generated code usese `T::API_SCHEMA` when building ObjectSchemas. For Updaters we replace `T` with `<T as Updatable>::Updater` This means for "simple" wrappers like our `Authid` or `Userid`, the ObjectSchema will try to refer to `<Authid as Updatable>::Updater::API_SCHEMA` which resolves to: `Option<Authid>::API_SCHEMA` which does not exist, for which we cannot add a normal `impl` block to add the schema variable, since `Option` is not "ours". But we now have a blanket implementation of `ApiType` for `Option<T> where T: ApiType` which just points to the original `T::API_SCHEMA`. Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
783cbcb499
commit
cb9d57b453
@ -76,8 +76,10 @@ pub fn handle_enum(
|
|||||||
|
|
||||||
Ok(quote_spanned! { name.span() =>
|
Ok(quote_spanned! { name.span() =>
|
||||||
#enum_ty
|
#enum_ty
|
||||||
impl #name {
|
|
||||||
pub const API_SCHEMA: ::proxmox::api::schema::Schema =
|
#[automatically_derived]
|
||||||
|
impl ::proxmox::api::schema::ApiType for #name {
|
||||||
|
const API_SCHEMA: ::proxmox::api::schema::Schema =
|
||||||
#schema
|
#schema
|
||||||
.format(&::proxmox::api::schema::ApiStringFormat::Enum(&[#variants]))
|
.format(&::proxmox::api::schema::ApiStringFormat::Enum(&[#variants]))
|
||||||
.schema();
|
.schema();
|
||||||
|
@ -148,7 +148,7 @@ impl Schema {
|
|||||||
fn to_schema_reference(&self) -> Option<TokenStream> {
|
fn to_schema_reference(&self) -> Option<TokenStream> {
|
||||||
match &self.item {
|
match &self.item {
|
||||||
SchemaItem::ExternType(path) => {
|
SchemaItem::ExternType(path) => {
|
||||||
Some(quote_spanned! { path.span() => &#path::API_SCHEMA })
|
Some(quote_spanned! { path.span() => &<#path as ::proxmox::api::schema::ApiType>::API_SCHEMA })
|
||||||
}
|
}
|
||||||
SchemaItem::ExternSchema(path) => Some(quote_spanned! { path.span() => &#path }),
|
SchemaItem::ExternSchema(path) => Some(quote_spanned! { path.span() => &#path }),
|
||||||
_ => None,
|
_ => None,
|
||||||
@ -375,7 +375,7 @@ impl SchemaItem {
|
|||||||
error!(description => "description not allowed on external type");
|
error!(description => "description not allowed on external type");
|
||||||
}
|
}
|
||||||
|
|
||||||
ts.extend(quote_spanned! { path.span() => #path::API_SCHEMA });
|
ts.extend(quote_spanned! { path.span() => <#path as ::proxmox::api::schema::ApiType>::API_SCHEMA });
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
SchemaItem::ExternSchema(path) => {
|
SchemaItem::ExternSchema(path) => {
|
||||||
|
@ -84,8 +84,10 @@ fn finish_schema(
|
|||||||
|
|
||||||
Ok(quote_spanned! { name.span() =>
|
Ok(quote_spanned! { name.span() =>
|
||||||
#stru
|
#stru
|
||||||
impl #name {
|
|
||||||
pub const API_SCHEMA: ::proxmox::api::schema::Schema = #schema;
|
#[automatically_derived]
|
||||||
|
impl ::proxmox::api::schema::ApiType for #name {
|
||||||
|
const API_SCHEMA: ::proxmox::api::schema::Schema = #schema;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -347,9 +349,14 @@ fn finish_all_of_struct(
|
|||||||
|
|
||||||
Ok(quote_spanned!(name.span() =>
|
Ok(quote_spanned!(name.span() =>
|
||||||
#stru
|
#stru
|
||||||
|
|
||||||
impl #name {
|
impl #name {
|
||||||
#inner_schema
|
#inner_schema
|
||||||
pub const API_SCHEMA: ::proxmox::api::schema::Schema =
|
}
|
||||||
|
|
||||||
|
#[automatically_derived]
|
||||||
|
impl ::proxmox::api::schema::ApiType for #name {
|
||||||
|
const API_SCHEMA: ::proxmox::api::schema::Schema =
|
||||||
::proxmox::api::schema::AllOfSchema::new(
|
::proxmox::api::schema::AllOfSchema::new(
|
||||||
#description,
|
#description,
|
||||||
&[
|
&[
|
||||||
@ -528,7 +535,7 @@ fn handle_updater_field(
|
|||||||
|
|
||||||
if field_schema.flatten_in_struct {
|
if field_schema.flatten_in_struct {
|
||||||
let updater_ty = &field.ty;
|
let updater_ty = &field.ty;
|
||||||
all_of_schemas.extend(quote::quote! {&#updater_ty::API_SCHEMA,});
|
all_of_schemas.extend(quote::quote! {&<#updater_ty as ::proxmox::api::schema::ApiType>::API_SCHEMA,});
|
||||||
}
|
}
|
||||||
|
|
||||||
if !is_empty_impl.is_empty() {
|
if !is_empty_impl.is_empty() {
|
||||||
|
@ -1,5 +1,15 @@
|
|||||||
use proxmox::api::api;
|
use proxmox::api::api;
|
||||||
use proxmox::api::schema::Updater;
|
use proxmox::api::schema::{Schema, StringSchema, Updatable, Updater};
|
||||||
|
|
||||||
|
#[derive(Updatable)]
|
||||||
|
pub struct Custom(String);
|
||||||
|
|
||||||
|
impl proxmox::api::schema::ApiType for Custom {
|
||||||
|
const API_SCHEMA: Schema = StringSchema::new("Custom String")
|
||||||
|
.min_length(3)
|
||||||
|
.max_length(64)
|
||||||
|
.schema();
|
||||||
|
}
|
||||||
|
|
||||||
#[api]
|
#[api]
|
||||||
/// An example of a simple struct type.
|
/// An example of a simple struct type.
|
||||||
@ -38,7 +48,7 @@ pub struct Complex {
|
|||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// One of the baaaad cases.
|
/// One of the baaaad cases.
|
||||||
#[derive(Default, Updater)]
|
#[derive(Updater)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
pub struct SuperComplex {
|
pub struct SuperComplex {
|
||||||
/// An extra field not part of the flattened struct.
|
/// An extra field not part of the flattened struct.
|
||||||
@ -50,4 +60,7 @@ pub struct SuperComplex {
|
|||||||
/// A field which should not appear in the updater.
|
/// A field which should not appear in the updater.
|
||||||
#[updater(skip)]
|
#[updater(skip)]
|
||||||
not_in_updater: String,
|
not_in_updater: String,
|
||||||
|
|
||||||
|
/// A custom type with an Updatable implementation.
|
||||||
|
custom: Custom,
|
||||||
}
|
}
|
||||||
|
@ -1560,6 +1560,14 @@ where
|
|||||||
const UPDATER_IS_OPTION: bool = true;
|
const UPDATER_IS_OPTION: bool = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ApiType {
|
||||||
|
const API_SCHEMA: Schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ApiType> ApiType for Option<T> {
|
||||||
|
const API_SCHEMA: Schema = T::API_SCHEMA;
|
||||||
|
}
|
||||||
|
|
||||||
/// A helper type for "Updater" structs. This trait is *not* implemented for an api "base" type
|
/// A helper type for "Updater" structs. This trait is *not* implemented for an api "base" type
|
||||||
/// when deriving an `Updater` for it, though the generated *updater* type does implement this
|
/// when deriving an `Updater` for it, though the generated *updater* type does implement this
|
||||||
/// trait!
|
/// trait!
|
||||||
|
Loading…
Reference in New Issue
Block a user