use crate::SchemaGenerator;
use crate::_alloc_prelude::*;
use crate::{json_schema, JsonSchema, Schema};
use alloc::borrow::Cow;
use core::ops::{Bound, Range, RangeInclusive};
use serde_jsonc2::Value;
impl<T: JsonSchema> JsonSchema for Option<T> {
always_inline!();
fn schema_name() -> Cow<'static, str> {
format!("Nullable_{}", T::schema_name()).into()
}
fn schema_id() -> Cow<'static, str> {
format!("Option<{}>", T::schema_id()).into()
}
fn json_schema(generator: &mut SchemaGenerator) -> Schema {
let mut schema = generator.subschema_for::<T>();
if generator.settings().option_add_null_type {
schema = match schema.try_to_object() {
Ok(mut obj) => {
let instance_type = obj.get_mut("type");
match instance_type {
Some(Value::Array(array)) => {
let null = Value::from("null");
if !array.contains(&null) {
array.push(null);
}
obj.into()
}
Some(Value::String(string)) => {
if string != "null" {
*instance_type.unwrap() = Value::Array(vec![
core::mem::take(string).into(),
"null".into(),
]);
}
obj.into()
}
_ => json_schema!({
"anyOf": [
obj,
<()>::json_schema(generator)
]
}),
}
}
Err(true) => true.into(),
Err(false) => <()>::json_schema(generator),
}
}
if generator.settings().option_nullable {
schema
.ensure_object()
.insert("nullable".into(), true.into());
};
schema
}
fn _schema_jsonrs_private_non_optional_json_schema(generator: &mut SchemaGenerator) -> Schema {
T::_schema_jsonrs_private_non_optional_json_schema(generator)
}
fn _schema_jsonrs_private_is_option() -> bool {
true
}
}
impl<T: JsonSchema, E: JsonSchema> JsonSchema for Result<T, E> {
fn schema_name() -> Cow<'static, str> {
format!("Result_of_{}_or_{}", T::schema_name(), E::schema_name()).into()
}
fn schema_id() -> Cow<'static, str> {
format!("Result<{}, {}>", T::schema_id(), E::schema_id()).into()
}
fn json_schema(generator: &mut SchemaGenerator) -> Schema {
json_schema!({
"oneOf": [
{
"type": "object",
"properties": {
"Ok": generator.subschema_for::<T>()
},
"required": ["Ok"]
},
{
"type": "object",
"properties": {
"Err": generator.subschema_for::<E>()
},
"required": ["Err"]
}
]
})
}
}
impl<T: JsonSchema> JsonSchema for Bound<T> {
fn schema_name() -> Cow<'static, str> {
format!("Bound_of_{}", T::schema_name()).into()
}
fn schema_id() -> Cow<'static, str> {
format!("Bound<{}>", T::schema_id()).into()
}
fn json_schema(generator: &mut SchemaGenerator) -> Schema {
json_schema!({
"oneOf": [
{
"type": "object",
"properties": {
"Included": generator.subschema_for::<T>()
},
"required": ["Included"]
},
{
"type": "object",
"properties": {
"Excluded": generator.subschema_for::<T>()
},
"required": ["Excluded"]
},
{
"type": "string",
"const": "Unbounded"
}
]
})
}
}
impl<T: JsonSchema> JsonSchema for Range<T> {
fn schema_name() -> Cow<'static, str> {
format!("Range_of_{}", T::schema_name()).into()
}
fn schema_id() -> Cow<'static, str> {
format!("Range<{}>", T::schema_id()).into()
}
fn json_schema(generator: &mut SchemaGenerator) -> Schema {
let subschema = generator.subschema_for::<T>();
json_schema!({
"type": "object",
"properties": {
"start": subschema,
"end": subschema
},
"required": ["start", "end"]
})
}
}
forward_impl!((<T: JsonSchema> JsonSchema for RangeInclusive<T>) => Range<T>);
forward_impl!((<T: ?Sized> JsonSchema for core::marker::PhantomData<T>) => ());
forward_impl!((<'a> JsonSchema for core::fmt::Arguments<'a>) => String);