Skip to main content

openapiv3_resolve/resolved/
schema_type.rs

1use super::resolver::{Resolvable, Resolver};
2use super::{NestedSchema, ResolvedAdditionalProperties};
3use crate::ResolveError;
4use indexmap::IndexMap;
5use openapiv3::{
6    AnySchema, ArrayType, BooleanType, IntegerType, NumberType, ObjectType, StringType, Type,
7};
8
9/// [`Type`] with every `$ref` replaced by the schema it named.
10#[derive(Debug, PartialEq)]
11pub enum ResolvedType {
12    /// See [`Type::String`].
13    String(StringType),
14    /// See [`Type::Number`].
15    Number(NumberType),
16    /// See [`Type::Integer`].
17    Integer(IntegerType),
18    /// See [`Type::Object`].
19    Object(ResolvedObjectType),
20    /// See [`Type::Array`].
21    Array(ResolvedArrayType),
22    /// See [`Type::Boolean`].
23    Boolean(BooleanType),
24}
25
26/// [`ObjectType`] with every `$ref` replaced by the schema it named.
27#[derive(Debug, PartialEq)]
28pub struct ResolvedObjectType {
29    /// See [`ObjectType::properties`].
30    pub properties: IndexMap<String, NestedSchema>,
31    /// See [`ObjectType::required`].
32    pub required: Vec<String>,
33    /// See [`ObjectType::additional_properties`].
34    pub additional_properties: Option<ResolvedAdditionalProperties>,
35    /// See [`ObjectType::min_properties`].
36    pub min_properties: Option<usize>,
37    /// See [`ObjectType::max_properties`].
38    pub max_properties: Option<usize>,
39}
40
41/// [`ArrayType`] with a `$ref` in `items` replaced by the schema it named.
42#[derive(Debug, PartialEq)]
43pub struct ResolvedArrayType {
44    /// See [`ArrayType::items`].
45    pub items: Option<NestedSchema>,
46    /// See [`ArrayType::min_items`].
47    pub min_items: Option<usize>,
48    /// See [`ArrayType::max_items`].
49    pub max_items: Option<usize>,
50    /// See [`ArrayType::unique_items`].
51    pub unique_items: bool,
52}
53
54/// [`AnySchema`] with every `$ref` replaced by the schema it named.
55#[derive(Debug, PartialEq)]
56pub struct ResolvedAnySchema {
57    /// See [`AnySchema::typ`].
58    pub typ: Option<String>,
59    /// See [`AnySchema::pattern`].
60    pub pattern: Option<String>,
61    /// See [`AnySchema::multiple_of`].
62    pub multiple_of: Option<f64>,
63    /// See [`AnySchema::exclusive_minimum`].
64    pub exclusive_minimum: Option<bool>,
65    /// See [`AnySchema::exclusive_maximum`].
66    pub exclusive_maximum: Option<bool>,
67    /// See [`AnySchema::minimum`].
68    pub minimum: Option<f64>,
69    /// See [`AnySchema::maximum`].
70    pub maximum: Option<f64>,
71    /// See [`AnySchema::properties`].
72    pub properties: IndexMap<String, NestedSchema>,
73    /// See [`AnySchema::required`].
74    pub required: Vec<String>,
75    /// See [`AnySchema::additional_properties`].
76    pub additional_properties: Option<ResolvedAdditionalProperties>,
77    /// See [`AnySchema::min_properties`].
78    pub min_properties: Option<usize>,
79    /// See [`AnySchema::max_properties`].
80    pub max_properties: Option<usize>,
81    /// See [`AnySchema::items`].
82    pub items: Option<NestedSchema>,
83    /// See [`AnySchema::min_items`].
84    pub min_items: Option<usize>,
85    /// See [`AnySchema::max_items`].
86    pub max_items: Option<usize>,
87    /// See [`AnySchema::unique_items`].
88    pub unique_items: Option<bool>,
89    /// See [`AnySchema::enumeration`].
90    pub enumeration: Vec<serde_json::Value>,
91    /// See [`AnySchema::format`].
92    pub format: Option<String>,
93    /// See [`AnySchema::min_length`].
94    pub min_length: Option<usize>,
95    /// See [`AnySchema::max_length`].
96    pub max_length: Option<usize>,
97    /// See [`AnySchema::one_of`].
98    pub one_of: Vec<NestedSchema>,
99    /// See [`AnySchema::all_of`].
100    pub all_of: Vec<NestedSchema>,
101    /// See [`AnySchema::any_of`].
102    pub any_of: Vec<NestedSchema>,
103    /// See [`AnySchema::not`].
104    pub not: Option<NestedSchema>,
105}
106
107impl Resolvable for Type {
108    type Resolved = ResolvedType;
109
110    fn resolve_inline(&self, cx: &mut Resolver<'_>) -> Result<Self::Resolved, ResolveError> {
111        Ok(match self {
112            Self::String(string) => ResolvedType::String(string.clone()),
113            Self::Number(number) => ResolvedType::Number(number.clone()),
114            Self::Integer(integer) => ResolvedType::Integer(integer.clone()),
115            Self::Object(object) => ResolvedType::Object(object.resolve_inline(cx)?),
116            Self::Array(array) => ResolvedType::Array(array.resolve_inline(cx)?),
117            Self::Boolean(boolean) => ResolvedType::Boolean(boolean.clone()),
118        })
119    }
120}
121
122impl Resolvable for ObjectType {
123    type Resolved = ResolvedObjectType;
124
125    fn resolve_inline(&self, cx: &mut Resolver<'_>) -> Result<Self::Resolved, ResolveError> {
126        Ok(ResolvedObjectType {
127            properties: cx.nested_map(&self.properties)?,
128            required: self.required.clone(),
129            additional_properties: self
130                .additional_properties
131                .as_ref()
132                .map(|additional| additional.resolve_inline(cx))
133                .transpose()?,
134            min_properties: self.min_properties,
135            max_properties: self.max_properties,
136        })
137    }
138}
139
140impl Resolvable for ArrayType {
141    type Resolved = ResolvedArrayType;
142
143    fn resolve_inline(&self, cx: &mut Resolver<'_>) -> Result<Self::Resolved, ResolveError> {
144        Ok(ResolvedArrayType {
145            items: self
146                .items
147                .as_ref()
148                .map(|items| cx.nested(items))
149                .transpose()?,
150            min_items: self.min_items,
151            max_items: self.max_items,
152            unique_items: self.unique_items,
153        })
154    }
155}
156
157impl Resolvable for AnySchema {
158    type Resolved = ResolvedAnySchema;
159
160    fn resolve_inline(&self, cx: &mut Resolver<'_>) -> Result<Self::Resolved, ResolveError> {
161        Ok(ResolvedAnySchema {
162            typ: self.typ.clone(),
163            pattern: self.pattern.clone(),
164            multiple_of: self.multiple_of,
165            exclusive_minimum: self.exclusive_minimum,
166            exclusive_maximum: self.exclusive_maximum,
167            minimum: self.minimum,
168            maximum: self.maximum,
169            properties: cx.nested_map(&self.properties)?,
170            required: self.required.clone(),
171            additional_properties: self
172                .additional_properties
173                .as_ref()
174                .map(|additional| additional.resolve_inline(cx))
175                .transpose()?,
176            min_properties: self.min_properties,
177            max_properties: self.max_properties,
178            items: self
179                .items
180                .as_ref()
181                .map(|items| cx.nested(items))
182                .transpose()?,
183            min_items: self.min_items,
184            max_items: self.max_items,
185            unique_items: self.unique_items,
186            enumeration: self.enumeration.clone(),
187            format: self.format.clone(),
188            min_length: self.min_length,
189            max_length: self.max_length,
190            one_of: cx.nested_vec(&self.one_of)?,
191            all_of: cx.nested_vec(&self.all_of)?,
192            any_of: cx.nested_vec(&self.any_of)?,
193            not: self.not.as_ref().map(|not| cx.nested(not)).transpose()?,
194        })
195    }
196}