#![allow(dead_code)] use serde::{Deserialize, Serialize}; use proxmox_schema::{api, ApiType, Updater, UpdaterType}; // Helpers for type checks: struct AssertTypeEq(T); macro_rules! assert_type_eq { ($what:ident, $a:ty, $b:ty) => { #[allow(dead_code, unreachable_patterns)] fn $what(have: AssertTypeEq<$a>) { match have { AssertTypeEq::<$b>(_) => (), } } }; } #[api(min_length: 3, max_length: 64)] #[derive(UpdaterType)] /// Custom String. pub struct Custom(String); assert_type_eq!( custom_type, ::Updater, Option ); #[api] /// An example of a simple struct type. #[derive(Updater)] #[serde(rename_all = "kebab-case")] pub struct Simple { /// A test string. one_field: String, /// Another test value. #[serde(skip_serializing_if = "Option::is_empty")] opt: Option, } #[test] fn test_simple() { pub const TEST_SCHEMA: ::proxmox_schema::Schema = ::proxmox_schema::ObjectSchema::new( "An example of a simple struct type.", &[ ( "one-field", true, &::proxmox_schema::StringSchema::new("A test string.").schema(), ), ( "opt", true, &::proxmox_schema::StringSchema::new("Another test value.").schema(), ), ], ) .schema(); assert_eq!(TEST_SCHEMA, SimpleUpdater::API_SCHEMA); } #[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. extra: String, simple: 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, } #[test] fn test_super_complex() { pub const TEST_SCHEMA: ::proxmox_schema::Schema = ::proxmox_schema::ObjectSchema::new( "One of the baaaad cases.", &[ ("custom", true, & as ApiType>::API_SCHEMA), ( "extra", true, &::proxmox_schema::StringSchema::new("An extra field.").schema(), ), ( "simple", true, //&<::Updater as ApiType>::API_SCHEMA, &SimpleUpdater::API_SCHEMA, ), ], ) .schema(); assert_eq!(TEST_SCHEMA, SuperComplexUpdater::API_SCHEMA); } #[api] /// A simple string wrapper. #[derive(Default, Deserialize, Serialize, Updater)] struct MyType(String); impl proxmox_schema::UpdaterType for MyType { type Updater = Option; } impl MyType { fn should_skip(&self) -> bool { self.0 == "skipme" } } #[api( properties: { more: { type: MyType }, }, )] /// A struct where we replace serde attributes. #[derive(Deserialize, Serialize, Updater)] pub struct WithSerde { /// Simple string. data: String, #[serde(skip_serializing_if = "MyType::should_skip", default)] #[updater(serde(skip_serializing_if = "Option::is_none"))] more: MyType, }