paperclip_core/v3/models/
schema.rsuse crate::v2::models::Either;
use super::{invalid_referenceor, v2};
use std::ops::Deref;
impl From<v2::DefaultSchemaRaw> for openapiv3::ReferenceOr<Box<openapiv3::Schema>> {
fn from(v2: v2::DefaultSchemaRaw) -> Self {
let x: openapiv3::ReferenceOr<openapiv3::Schema> = v2.into();
match x {
openapiv3::ReferenceOr::Reference { reference } => {
openapiv3::ReferenceOr::Reference { reference }
}
openapiv3::ReferenceOr::Item(item) => openapiv3::ReferenceOr::Item(Box::new(item)),
}
}
}
impl From<v2::DefaultSchemaRaw> for openapiv3::ReferenceOr<openapiv3::Schema> {
fn from(v2: v2::DefaultSchemaRaw) -> Self {
match v2.reference.clone() {
Some(reference) => v2::Reference { reference }.into(),
None => {
let item = openapiv3::Schema {
schema_data: openapiv3::SchemaData {
nullable: false,
read_only: false,
write_only: false,
deprecated: false,
external_docs: None,
example: v2.example,
title: v2.title,
description: v2.description,
discriminator: None,
default: None,
extensions: Default::default(),
},
schema_kind: {
if let Some(data_type) = v2.data_type {
v2_data_type_to_v3(
&data_type,
&v2.format,
&v2.enum_,
&v2.items,
&v2.properties,
&v2.extra_props,
&v2.required,
)
} else {
openapiv3::SchemaKind::Type(openapiv3::Type::Object(
openapiv3::ObjectType::default(),
))
}
},
};
openapiv3::ReferenceOr::Item(item)
}
}
}
}
fn v2_data_type_to_v3(
data_type: &v2::DataType,
format: &Option<v2::DataTypeFormat>,
enum_: &[serde_json::Value],
items: &Option<Box<v2::DefaultSchemaRaw>>,
properties: &std::collections::BTreeMap<String, Box<v2::DefaultSchemaRaw>>,
extra_properties: &Option<Either<bool, Box<v2::DefaultSchemaRaw>>>,
required: &std::collections::BTreeSet<String>,
) -> openapiv3::SchemaKind {
match data_type {
v2::DataType::Integer => {
openapiv3::SchemaKind::Type(openapiv3::Type::Integer(openapiv3::IntegerType {
format: match format {
None => openapiv3::VariantOrUnknownOrEmpty::Empty,
Some(format) => match format {
v2::DataTypeFormat::Int32 => openapiv3::VariantOrUnknownOrEmpty::Item(
openapiv3::IntegerFormat::Int32,
),
v2::DataTypeFormat::Int64 => openapiv3::VariantOrUnknownOrEmpty::Item(
openapiv3::IntegerFormat::Int64,
),
other => {
debug_assert!(false, "Invalid data type format: {:?}", other);
openapiv3::VariantOrUnknownOrEmpty::Empty
}
},
},
multiple_of: None,
exclusive_minimum: false,
exclusive_maximum: false,
minimum: None,
maximum: None,
enumeration: enum_
.iter()
.cloned()
.map(|v| serde_json::from_value(v).unwrap_or_default())
.collect(),
}))
}
v2::DataType::Number => {
openapiv3::SchemaKind::Type(openapiv3::Type::Number(openapiv3::NumberType {
format: match format {
None => openapiv3::VariantOrUnknownOrEmpty::Empty,
Some(format) => match format {
v2::DataTypeFormat::Float => openapiv3::VariantOrUnknownOrEmpty::Item(
openapiv3::NumberFormat::Float {},
),
v2::DataTypeFormat::Double => openapiv3::VariantOrUnknownOrEmpty::Item(
openapiv3::NumberFormat::Double {},
),
other => {
debug_assert!(false, "Invalid data type format: {:?}", other);
openapiv3::VariantOrUnknownOrEmpty::Empty
}
},
},
multiple_of: None,
exclusive_minimum: false,
exclusive_maximum: false,
minimum: None,
maximum: None,
enumeration: enum_
.iter()
.cloned()
.map(|v| serde_json::from_value(v).unwrap_or_default())
.collect(),
}))
}
v2::DataType::String => {
openapiv3::SchemaKind::Type(openapiv3::Type::String(openapiv3::StringType {
format: match format {
None => openapiv3::VariantOrUnknownOrEmpty::Empty,
Some(format) => match format {
v2::DataTypeFormat::Byte => {
openapiv3::VariantOrUnknownOrEmpty::Item(openapiv3::StringFormat::Byte)
}
v2::DataTypeFormat::Binary => openapiv3::VariantOrUnknownOrEmpty::Item(
openapiv3::StringFormat::Binary,
),
v2::DataTypeFormat::Date => {
openapiv3::VariantOrUnknownOrEmpty::Item(openapiv3::StringFormat::Date)
}
v2::DataTypeFormat::DateTime => openapiv3::VariantOrUnknownOrEmpty::Item(
openapiv3::StringFormat::DateTime,
),
v2::DataTypeFormat::Password => openapiv3::VariantOrUnknownOrEmpty::Item(
openapiv3::StringFormat::Password,
),
v2::DataTypeFormat::Other => {
debug_assert!(false, "Invalid data type format: other");
openapiv3::VariantOrUnknownOrEmpty::Unknown(
v2::DataTypeFormat::Other.to_string(),
)
}
others => openapiv3::VariantOrUnknownOrEmpty::Unknown(others.to_string()),
},
},
pattern: None,
enumeration: enum_
.iter()
.cloned()
.map(|v| serde_json::from_value(v).unwrap_or_default())
.collect(),
min_length: None,
max_length: None,
}))
}
v2::DataType::Boolean => {
openapiv3::SchemaKind::Type(openapiv3::Type::Boolean(Default::default()))
}
v2::DataType::Array => {
openapiv3::SchemaKind::Type(openapiv3::Type::Array(openapiv3::ArrayType {
items: items.as_ref().map(|items| items.deref().clone().into()),
min_items: None,
max_items: None,
unique_items: false,
}))
}
v2::DataType::Object => {
openapiv3::SchemaKind::Type(openapiv3::Type::Object(openapiv3::ObjectType {
properties: {
properties.iter().fold(Default::default(), |mut i, b| {
i.insert(b.0.to_string(), b.1.deref().clone().into());
i
})
},
required: required.iter().cloned().collect::<Vec<_>>(),
additional_properties: extra_properties.as_ref().map(|e| match e {
Either::Right(box_schema) => openapiv3::AdditionalProperties::Schema(Box::new(
box_schema.deref().clone().into(),
)),
Either::Left(v) => openapiv3::AdditionalProperties::Any(*v),
}),
min_properties: None,
max_properties: None,
}))
}
v2::DataType::File => {
openapiv3::SchemaKind::Type(openapiv3::Type::String(openapiv3::StringType {
format: openapiv3::VariantOrUnknownOrEmpty::Item(openapiv3::StringFormat::Binary),
..Default::default()
}))
}
}
}
impl From<v2::Items> for openapiv3::ReferenceOr<Box<openapiv3::Schema>> {
fn from(v2: v2::Items) -> Self {
let kind = match v2.data_type {
None => {
return invalid_referenceor("Invalid Item, should have a data type".into());
}
Some(data_type) => match data_type {
v2::DataType::Integer => {
openapiv3::SchemaKind::Type(openapiv3::Type::Integer(openapiv3::IntegerType {
format: match &v2.format {
None => openapiv3::VariantOrUnknownOrEmpty::Empty,
Some(format) => match format {
v2::DataTypeFormat::Int32 => {
openapiv3::VariantOrUnknownOrEmpty::Item(
openapiv3::IntegerFormat::Int32,
)
}
v2::DataTypeFormat::Int64 => {
openapiv3::VariantOrUnknownOrEmpty::Item(
openapiv3::IntegerFormat::Int64,
)
}
other => {
return invalid_referenceor(format!(
"Invalid data type format: {:?}",
other
));
}
},
},
multiple_of: v2.multiple_of.map(|v| v as i64),
exclusive_minimum: v2.exclusive_minimum.unwrap_or_default(),
exclusive_maximum: v2.exclusive_maximum.unwrap_or_default(),
minimum: v2.minimum.map(|v| v as i64),
maximum: v2.maximum.map(|v| v as i64),
enumeration: v2
.enum_
.iter()
.cloned()
.map(|v| serde_json::from_value(v).unwrap_or_default())
.collect(),
}))
}
v2::DataType::Number => {
openapiv3::SchemaKind::Type(openapiv3::Type::Number(openapiv3::NumberType {
format: match &v2.format {
None => openapiv3::VariantOrUnknownOrEmpty::Empty,
Some(format) => match format {
v2::DataTypeFormat::Float => {
openapiv3::VariantOrUnknownOrEmpty::Item(
openapiv3::NumberFormat::Float {},
)
}
v2::DataTypeFormat::Double => {
openapiv3::VariantOrUnknownOrEmpty::Item(
openapiv3::NumberFormat::Double {},
)
}
other => {
return invalid_referenceor(format!(
"Invalid data type format: {:?}",
other
));
}
},
},
multiple_of: v2.multiple_of.map(From::from),
exclusive_minimum: v2.exclusive_minimum.unwrap_or_default(),
exclusive_maximum: v2.exclusive_maximum.unwrap_or_default(),
minimum: v2.minimum.map(From::from),
maximum: v2.maximum.map(From::from),
enumeration: v2
.enum_
.iter()
.cloned()
.map(|v| serde_json::from_value(v).unwrap_or_default())
.collect(),
}))
}
v2::DataType::String => {
openapiv3::SchemaKind::Type(openapiv3::Type::String(openapiv3::StringType {
format: match &v2.format {
None => openapiv3::VariantOrUnknownOrEmpty::Empty,
Some(format) => match format {
v2::DataTypeFormat::Byte => {
openapiv3::VariantOrUnknownOrEmpty::Item(
openapiv3::StringFormat::Byte,
)
}
v2::DataTypeFormat::Binary => {
openapiv3::VariantOrUnknownOrEmpty::Item(
openapiv3::StringFormat::Binary,
)
}
v2::DataTypeFormat::Date => {
openapiv3::VariantOrUnknownOrEmpty::Item(
openapiv3::StringFormat::Date,
)
}
v2::DataTypeFormat::DateTime => {
openapiv3::VariantOrUnknownOrEmpty::Item(
openapiv3::StringFormat::DateTime,
)
}
v2::DataTypeFormat::Password => {
openapiv3::VariantOrUnknownOrEmpty::Item(
openapiv3::StringFormat::Password,
)
}
other => {
return invalid_referenceor(format!(
"Invalid data type format: {:?}",
other
));
}
},
},
pattern: v2.pattern.clone(),
enumeration: v2
.enum_
.iter()
.cloned()
.map(|v| serde_json::from_value(v).unwrap_or_default())
.collect(),
min_length: v2.min_length.map(|v| v as usize),
max_length: v2.max_length.map(|v| v as usize),
}))
}
v2::DataType::Boolean => {
openapiv3::SchemaKind::Type(openapiv3::Type::Boolean(Default::default()))
}
v2::DataType::Array => {
openapiv3::SchemaKind::Type(openapiv3::Type::Array(openapiv3::ArrayType {
items: v2.items.map(|items| items.deref().clone().into()),
min_items: v2.min_items.map(|v| v as usize),
max_items: v2.max_items.map(|v| v as usize),
unique_items: v2.unique_items.unwrap_or_default(),
}))
}
invalid => {
return invalid_referenceor(format!("Invalid Item data_type: {:?}", invalid))
}
},
};
openapiv3::ReferenceOr::Item(Box::new(openapiv3::Schema {
schema_data: Default::default(),
schema_kind: kind,
}))
}
}