#![cfg_attr(docsrs, feature(doc_cfg))]
#![doc(
html_logo_url = "https://github.com/specta-rs/specta/raw/main/.github/logo-128.png",
html_favicon_url = "https://github.com/specta-rs/specta/raw/main/.github/logo-128.png"
)]
#![allow(warnings)]
use openapiv3::{
ArrayType, BooleanType, NumberType, ReferenceOr, Schema, SchemaData, SchemaKind, StringType,
Type,
};
use specta::datatype::{DataType, Primitive};
macro_rules! primitive_def {
($($t:ident)+) => {
$(DataType::Primitive(Primitive::$t))|+
}
}
pub fn to_openapi(typ: &DataType) -> ReferenceOr<Schema> {
let mut schema_data = SchemaData {
nullable: false,
deprecated: false, example: None, title: None, description: None, default: None, ..Default::default()
};
match &typ {
primitive_def!(i8 i16 i32 isize u8 u16 u32 usize f16 f32 f64 f128) => {
ReferenceOr::Item(Schema {
schema_data,
schema_kind: SchemaKind::Type(Type::Number(NumberType::default())), })
}
primitive_def!(i64 u64 i128 u128) => ReferenceOr::Item(Schema {
schema_data,
schema_kind: SchemaKind::Type(Type::Number(NumberType::default())), }),
primitive_def!(str char) => ReferenceOr::Item(Schema {
schema_data,
schema_kind: SchemaKind::Type(Type::String(StringType::default())), }),
primitive_def!(bool) => ReferenceOr::Item(Schema {
schema_data,
schema_kind: SchemaKind::Type(Type::Boolean(BooleanType::default())),
}),
DataType::Nullable(def) => match to_openapi(def) {
ReferenceOr::Item(mut schema) => {
schema.schema_data.nullable = true;
ReferenceOr::Item(schema)
}
reference => reference,
},
DataType::List(def) => ReferenceOr::Item(Schema {
schema_data,
schema_kind: SchemaKind::Type(Type::Array(ArrayType {
items: Some(match to_openapi(&def.ty) {
ReferenceOr::Item(schema) => ReferenceOr::Item(Box::new(schema)),
ReferenceOr::Reference { reference } => ReferenceOr::Reference { reference },
}),
min_items: None,
max_items: None,
unique_items: false,
})),
}),
DataType::Tuple(tuple) => match tuple.elements.as_slice() {
[] => {
schema_data.nullable = true;
ReferenceOr::Item(Schema {
schema_data,
schema_kind: SchemaKind::Type(Type::Object(openapiv3::ObjectType::default())), })
}
[ty] => to_openapi(ty),
_tys => todo!(),
},
DataType::Struct(s) => {
let _fields = &s.fields;
todo!();
}
DataType::Enum(_e) => {
todo!();
}
DataType::Reference(_reference) => {
todo!();
}
x => {
println!("{:?} {:?}", x, typ);
todo!();
}
}
}