use super::resolver::{Resolvable, Resolver};
use super::{NestedSchema, ResolvedAdditionalProperties};
use crate::ResolveError;
use indexmap::IndexMap;
use openapiv3::{
AnySchema, ArrayType, BooleanType, IntegerType, NumberType, ObjectType, StringType, Type,
};
#[derive(Debug, PartialEq)]
pub enum ResolvedType {
String(StringType),
Number(NumberType),
Integer(IntegerType),
Object(ResolvedObjectType),
Array(ResolvedArrayType),
Boolean(BooleanType),
}
#[derive(Debug, PartialEq)]
pub struct ResolvedObjectType {
pub properties: IndexMap<String, NestedSchema>,
pub required: Vec<String>,
pub additional_properties: Option<ResolvedAdditionalProperties>,
pub min_properties: Option<usize>,
pub max_properties: Option<usize>,
}
#[derive(Debug, PartialEq)]
pub struct ResolvedArrayType {
pub items: Option<NestedSchema>,
pub min_items: Option<usize>,
pub max_items: Option<usize>,
pub unique_items: bool,
}
#[derive(Debug, PartialEq)]
pub struct ResolvedAnySchema {
pub typ: Option<String>,
pub pattern: Option<String>,
pub multiple_of: Option<f64>,
pub exclusive_minimum: Option<bool>,
pub exclusive_maximum: Option<bool>,
pub minimum: Option<f64>,
pub maximum: Option<f64>,
pub properties: IndexMap<String, NestedSchema>,
pub required: Vec<String>,
pub additional_properties: Option<ResolvedAdditionalProperties>,
pub min_properties: Option<usize>,
pub max_properties: Option<usize>,
pub items: Option<NestedSchema>,
pub min_items: Option<usize>,
pub max_items: Option<usize>,
pub unique_items: Option<bool>,
pub enumeration: Vec<serde_json::Value>,
pub format: Option<String>,
pub min_length: Option<usize>,
pub max_length: Option<usize>,
pub one_of: Vec<NestedSchema>,
pub all_of: Vec<NestedSchema>,
pub any_of: Vec<NestedSchema>,
pub not: Option<NestedSchema>,
}
impl Resolvable for Type {
type Resolved = ResolvedType;
fn resolve_inline(&self, cx: &mut Resolver<'_>) -> Result<Self::Resolved, ResolveError> {
Ok(match self {
Self::String(string) => ResolvedType::String(string.clone()),
Self::Number(number) => ResolvedType::Number(number.clone()),
Self::Integer(integer) => ResolvedType::Integer(integer.clone()),
Self::Object(object) => ResolvedType::Object(object.resolve_inline(cx)?),
Self::Array(array) => ResolvedType::Array(array.resolve_inline(cx)?),
Self::Boolean(boolean) => ResolvedType::Boolean(boolean.clone()),
})
}
}
impl Resolvable for ObjectType {
type Resolved = ResolvedObjectType;
fn resolve_inline(&self, cx: &mut Resolver<'_>) -> Result<Self::Resolved, ResolveError> {
Ok(ResolvedObjectType {
properties: cx.nested_map(&self.properties)?,
required: self.required.clone(),
additional_properties: self
.additional_properties
.as_ref()
.map(|additional| additional.resolve_inline(cx))
.transpose()?,
min_properties: self.min_properties,
max_properties: self.max_properties,
})
}
}
impl Resolvable for ArrayType {
type Resolved = ResolvedArrayType;
fn resolve_inline(&self, cx: &mut Resolver<'_>) -> Result<Self::Resolved, ResolveError> {
Ok(ResolvedArrayType {
items: self
.items
.as_ref()
.map(|items| cx.nested(items))
.transpose()?,
min_items: self.min_items,
max_items: self.max_items,
unique_items: self.unique_items,
})
}
}
impl Resolvable for AnySchema {
type Resolved = ResolvedAnySchema;
fn resolve_inline(&self, cx: &mut Resolver<'_>) -> Result<Self::Resolved, ResolveError> {
Ok(ResolvedAnySchema {
typ: self.typ.clone(),
pattern: self.pattern.clone(),
multiple_of: self.multiple_of,
exclusive_minimum: self.exclusive_minimum,
exclusive_maximum: self.exclusive_maximum,
minimum: self.minimum,
maximum: self.maximum,
properties: cx.nested_map(&self.properties)?,
required: self.required.clone(),
additional_properties: self
.additional_properties
.as_ref()
.map(|additional| additional.resolve_inline(cx))
.transpose()?,
min_properties: self.min_properties,
max_properties: self.max_properties,
items: self
.items
.as_ref()
.map(|items| cx.nested(items))
.transpose()?,
min_items: self.min_items,
max_items: self.max_items,
unique_items: self.unique_items,
enumeration: self.enumeration.clone(),
format: self.format.clone(),
min_length: self.min_length,
max_length: self.max_length,
one_of: cx.nested_vec(&self.one_of)?,
all_of: cx.nested_vec(&self.all_of)?,
any_of: cx.nested_vec(&self.any_of)?,
not: self.not.as_ref().map(|not| cx.nested(not)).transpose()?,
})
}
}