mod any_of;
mod array;
mod boolean;
mod enum_;
mod number;
mod object;
mod raw;
mod string;
pub use any_of::AnyOfSchema;
pub use array::ArraySchema;
pub use boolean::BooleanSchema;
pub use enum_::EnumSchema;
pub use number::NumberSchema;
pub use object::ObjectSchema;
pub use raw::RawSchema;
pub use string::StringSchema;
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Schema {
String(StringSchema),
Number(NumberSchema),
Boolean(BooleanSchema),
Array(ArraySchema),
Object(ObjectSchema),
Enum(EnumSchema),
AnyOf(AnyOfSchema),
Raw(RawSchema),
}
impl Schema {
pub fn name(&self) -> &str {
match self {
Schema::String(s) => &s.name,
Schema::Number(s) => &s.name,
Schema::Boolean(s) => &s.name,
Schema::Array(s) => &s.name,
Schema::Object(s) => &s.name,
Schema::Enum(s) => &s.name,
Schema::AnyOf(s) => &s.name,
Schema::Raw(s) => &s.name,
}
}
}
pub fn to_json_schema(schema: &Schema) -> Value {
match schema {
Schema::String(s) => with_description(json!({"type": "string"}), s.description.as_deref()),
Schema::Number(s) => with_description(json!({"type": "number"}), s.description.as_deref()),
Schema::Boolean(s) => {
with_description(json!({"type": "boolean"}), s.description.as_deref())
}
Schema::Array(s) => {
let mut value = with_description(json!({"type": "array"}), s.description.as_deref());
value["items"] = to_json_schema(&s.items);
value
}
Schema::Object(s) => {
let mut properties = serde_json::Map::new();
for prop in &s.properties {
properties.insert(prop.name().to_string(), to_json_schema(prop));
}
let mut value = with_description(
json!({
"type": "object",
"properties": properties,
"required": s.required,
}),
s.description.as_deref(),
);
value["additionalProperties"] = json!(s.allow_additional_properties);
value
}
Schema::Enum(s) => with_description(
json!({"type": "string", "enum": s.options}),
s.description.as_deref(),
),
Schema::AnyOf(s) => with_description(
json!({"anyOf": s.schemas.iter().map(to_json_schema).collect::<Vec<_>>()}),
s.description.as_deref(),
),
Schema::Raw(s) => s.json_schema.clone(),
}
}
fn with_description(mut value: Value, description: Option<&str>) -> Value {
if let Some(description) = description {
value["description"] = json!(description);
}
value
}