use alloc::{
boxed::Box,
string::{String, ToString},
};
use schemars::schema::{
ArrayValidation, InstanceType, Metadata, ObjectValidation, Schema,
SchemaObject, SingleOrVec,
};
pub(crate) static IDDQD_CRATE_NAME: &str = "iddqd";
pub(crate) static IDDQD_CRATE_VERSION: &str = "*";
pub(crate) fn array_validation<T>(
generator: &mut schemars::gen::SchemaGenerator,
) -> Box<schemars::schema::ArrayValidation>
where
T: schemars::JsonSchema,
{
Box::new(ArrayValidation {
items: Some(SingleOrVec::Single(Box::new(
generator.subschema_for::<T>(),
))),
unique_items: Some(true),
..Default::default()
})
}
pub(crate) fn make_extension_table<T>(
path: &'static str,
generator: &mut schemars::gen::SchemaGenerator,
) -> schemars::Map<String, serde_json::Value>
where
T: schemars::JsonSchema,
{
[(
"x-rust-type".to_string(),
serde_json::json!({
"crate": IDDQD_CRATE_NAME,
"version": IDDQD_CRATE_VERSION,
"path": path,
"parameters": [generator.subschema_for::<T>()]
}),
)]
.into_iter()
.collect()
}
pub(crate) fn create_map_schema<T>(
title: &str,
rust_type_path: &'static str,
generator: &mut schemars::gen::SchemaGenerator,
) -> schemars::schema::Schema
where
T: schemars::JsonSchema,
{
Schema::Object(SchemaObject {
instance_type: Some(InstanceType::Array.into()),
array: Some(array_validation::<T>(generator)),
metadata: Some(Box::new(Metadata {
title: Some(title.to_string()),
..Default::default()
})),
extensions: make_extension_table::<T>(rust_type_path, generator),
..Default::default()
})
}
pub(crate) fn object_validation<V>(
generator: &mut schemars::gen::SchemaGenerator,
) -> Box<schemars::schema::ObjectValidation>
where
V: schemars::JsonSchema,
{
Box::new(ObjectValidation {
additional_properties: Some(Box::new(generator.subschema_for::<V>())),
..Default::default()
})
}
pub(crate) fn create_object_schema<V>(
title: &str,
rust_type_path: &'static str,
generator: &mut schemars::gen::SchemaGenerator,
) -> schemars::schema::Schema
where
V: schemars::JsonSchema,
{
Schema::Object(SchemaObject {
instance_type: Some(InstanceType::Object.into()),
object: Some(object_validation::<V>(generator)),
metadata: Some(Box::new(Metadata {
title: Some(title.to_string()),
..Default::default()
})),
extensions: make_extension_table::<V>(rust_type_path, generator),
..Default::default()
})
}