proxmox/proxmox-api-macro/tests/updater.rs
Wolfgang Bumiller cb9d57b453 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>
2021-08-12 10:15:13 +02:00

67 lines
1.4 KiB
Rust

use proxmox::api::api;
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]
/// An example of a simple struct type.
#[derive(Updater)]
#[serde(rename_all = "kebab-case")]
pub struct Simple {
/// A test string.
one_field: String,
/// An optional auto-derived value for testing:
#[serde(skip_serializing_if = "Option::is_empty")]
opt: Option<String>,
}
#[api(
properties: {
simple: { type: Simple },
},
)]
/// A second struct so we can test flattening.
#[derive(Updater)]
pub struct Complex {
/// An extra field not part of the flattened struct.
extra: String,
#[serde(flatten)]
simple: Simple,
}
#[api(
properties: {
simple: {
type: Simple,
optional: true,
},
},
)]
/// One of the baaaad cases.
#[derive(Updater)]
#[serde(rename_all = "kebab-case")]
pub struct SuperComplex {
/// An extra field not part of the flattened struct.
extra: String,
#[serde(skip_serializing_if = "Updater::is_empty")]
simple: Option<Simple>,
/// A field which should not appear in the updater.
#[updater(skip)]
not_in_updater: String,
/// A custom type with an Updatable implementation.
custom: Custom,
}