openapiv3_resolve/resolved/
schema.rs1use super::discriminator::resolve_discriminator;
2use super::resolver::{Resolvable, Resolver};
3use super::{NestedSchema, ResolvedAnySchema, ResolvedDiscriminator, ResolvedType};
4use crate::ResolveError;
5use indexmap::IndexMap;
6use openapiv3::{AdditionalProperties, ExternalDocumentation, Schema, SchemaData, SchemaKind};
7
8#[derive(Debug, PartialEq)]
10pub struct ResolvedSchema {
11 pub schema_data: ResolvedSchemaData,
13 pub schema_kind: ResolvedSchemaKind,
15}
16
17#[derive(Debug, Default, PartialEq)]
22pub struct ResolvedSchemaData {
23 pub nullable: bool,
25 pub read_only: bool,
31 pub write_only: bool,
33 pub deprecated: bool,
35 pub external_docs: Option<ExternalDocumentation>,
37 pub example: Option<serde_json::Value>,
39 pub title: Option<String>,
41 pub description: Option<String>,
43 pub discriminator: Option<ResolvedDiscriminator>,
45 pub default: Option<serde_json::Value>,
47 pub extensions: IndexMap<String, serde_json::Value>,
49}
50
51#[derive(Debug, PartialEq)]
53pub enum ResolvedSchemaKind {
54 Type(ResolvedType),
56 OneOf {
58 one_of: Vec<NestedSchema>,
60 },
61 AllOf {
63 all_of: Vec<NestedSchema>,
65 },
66 AnyOf {
68 any_of: Vec<NestedSchema>,
70 },
71 Not {
73 not: NestedSchema,
75 },
76 Any(Box<ResolvedAnySchema>),
78}
79
80#[derive(Debug, PartialEq)]
82pub enum ResolvedAdditionalProperties {
83 Any(bool),
85 Schema(NestedSchema),
87}
88
89impl Resolvable for Schema {
90 type Resolved = ResolvedSchema;
91
92 fn resolve_inline(&self, cx: &mut Resolver<'_>) -> Result<Self::Resolved, ResolveError> {
93 let schema_kind = self.schema_kind.resolve_inline(cx)?;
98 let discriminator = self
99 .schema_data
100 .discriminator
101 .as_ref()
102 .map(|discriminator| {
103 resolve_discriminator(cx, discriminator, &self.schema_kind, &schema_kind)
104 })
105 .transpose()?;
106 Ok(ResolvedSchema {
107 schema_data: resolve_schema_data(&self.schema_data, discriminator),
108 schema_kind,
109 })
110 }
111}
112
113impl Resolvable for SchemaKind {
114 type Resolved = ResolvedSchemaKind;
115
116 fn resolve_inline(&self, cx: &mut Resolver<'_>) -> Result<Self::Resolved, ResolveError> {
117 Ok(match self {
118 Self::Type(kind) => ResolvedSchemaKind::Type(kind.resolve_inline(cx)?),
119 Self::OneOf { one_of } => ResolvedSchemaKind::OneOf {
120 one_of: cx.nested_vec(one_of)?,
121 },
122 Self::AllOf { all_of } => ResolvedSchemaKind::AllOf {
123 all_of: cx.nested_vec(all_of)?,
124 },
125 Self::AnyOf { any_of } => ResolvedSchemaKind::AnyOf {
126 any_of: cx.nested_vec(any_of)?,
127 },
128 Self::Not { not } => ResolvedSchemaKind::Not {
129 not: cx.nested(not)?,
130 },
131 Self::Any(any) => ResolvedSchemaKind::Any(Box::new(any.resolve_inline(cx)?)),
132 })
133 }
134}
135
136impl Resolvable for AdditionalProperties {
137 type Resolved = ResolvedAdditionalProperties;
138
139 fn resolve_inline(&self, cx: &mut Resolver<'_>) -> Result<Self::Resolved, ResolveError> {
140 Ok(match self {
141 Self::Any(allowed) => ResolvedAdditionalProperties::Any(*allowed),
142 Self::Schema(schema) => ResolvedAdditionalProperties::Schema(cx.nested(schema)?),
143 })
144 }
145}
146
147fn resolve_schema_data(
149 data: &SchemaData,
150 discriminator: Option<ResolvedDiscriminator>,
151) -> ResolvedSchemaData {
152 let SchemaData {
157 nullable,
158 read_only,
159 write_only,
160 deprecated,
161 external_docs,
162 example,
163 title,
164 description,
165 discriminator: _,
166 default,
167 extensions,
168 } = data;
169 ResolvedSchemaData {
170 nullable: *nullable,
171 read_only: *read_only,
172 write_only: *write_only,
173 deprecated: *deprecated,
174 external_docs: external_docs.clone(),
175 example: example.clone(),
176 title: title.clone(),
177 description: description.clone(),
178 discriminator,
179 default: default.clone(),
180 extensions: extensions.clone(),
181 }
182}