paperclip_core/v3/models/
schema.rs1use crate::v2::models::Either;
2
3use super::{invalid_referenceor, v2};
4use std::ops::Deref;
5
6impl From<v2::DefaultSchemaRaw> for openapiv3::ReferenceOr<Box<openapiv3::Schema>> {
7 fn from(v2: v2::DefaultSchemaRaw) -> Self {
8 let x: openapiv3::ReferenceOr<openapiv3::Schema> = v2.into();
9 match x {
10 openapiv3::ReferenceOr::Reference { reference } => {
11 openapiv3::ReferenceOr::Reference { reference }
12 }
13 openapiv3::ReferenceOr::Item(item) => openapiv3::ReferenceOr::Item(Box::new(item)),
14 }
15 }
16}
17
18impl From<v2::DefaultSchemaRaw> for openapiv3::ReferenceOr<openapiv3::Schema> {
19 fn from(v2: v2::DefaultSchemaRaw) -> Self {
20 match v2.reference.clone() {
21 Some(reference) => v2::Reference { reference }.into(),
22 None => {
23 let item = openapiv3::Schema {
24 schema_data: openapiv3::SchemaData {
25 nullable: false,
26 read_only: false,
27 write_only: false,
28 deprecated: false,
29 external_docs: None,
30 example: v2.example,
31 title: v2.title,
32 description: v2.description,
33 discriminator: None,
34 default: None,
35 extensions: Default::default(),
36 },
37 schema_kind: {
38 if let Some(data_type) = v2.data_type {
39 v2_data_type_to_v3(
40 &data_type,
41 &v2.format,
42 &v2.enum_,
43 &v2.items,
44 &v2.properties,
45 &v2.extra_props,
46 &v2.required,
47 )
48 } else {
49 openapiv3::SchemaKind::Type(openapiv3::Type::Object(
50 openapiv3::ObjectType::default(),
51 ))
52 }
53 },
54 };
55 openapiv3::ReferenceOr::Item(item)
56 }
57 }
58 }
59}
60
61fn v2_data_type_to_v3(
64 data_type: &v2::DataType,
65 format: &Option<v2::DataTypeFormat>,
66 enum_: &[serde_json::Value],
67 items: &Option<Box<v2::DefaultSchemaRaw>>,
68 properties: &std::collections::BTreeMap<String, Box<v2::DefaultSchemaRaw>>,
69 extra_properties: &Option<Either<bool, Box<v2::DefaultSchemaRaw>>>,
70 required: &std::collections::BTreeSet<String>,
71) -> openapiv3::SchemaKind {
72 match data_type {
73 v2::DataType::Integer => {
74 openapiv3::SchemaKind::Type(openapiv3::Type::Integer(openapiv3::IntegerType {
75 format: match format {
76 None => openapiv3::VariantOrUnknownOrEmpty::Empty,
77 Some(format) => match format {
78 v2::DataTypeFormat::Int32 => openapiv3::VariantOrUnknownOrEmpty::Item(
79 openapiv3::IntegerFormat::Int32,
80 ),
81 v2::DataTypeFormat::Int64 => openapiv3::VariantOrUnknownOrEmpty::Item(
82 openapiv3::IntegerFormat::Int64,
83 ),
84 other => {
85 debug_assert!(false, "Invalid data type format: {:?}", other);
86 openapiv3::VariantOrUnknownOrEmpty::Empty
87 }
88 },
89 },
90 multiple_of: None,
91 exclusive_minimum: false,
92 exclusive_maximum: false,
93 minimum: None,
94 maximum: None,
95 enumeration: enum_
96 .iter()
97 .cloned()
98 .map(|v| serde_json::from_value(v).unwrap_or_default())
99 .collect(),
100 }))
101 }
102 v2::DataType::Number => {
103 openapiv3::SchemaKind::Type(openapiv3::Type::Number(openapiv3::NumberType {
104 format: match format {
105 None => openapiv3::VariantOrUnknownOrEmpty::Empty,
106 Some(format) => match format {
107 v2::DataTypeFormat::Float => openapiv3::VariantOrUnknownOrEmpty::Item(
108 openapiv3::NumberFormat::Float {},
109 ),
110 v2::DataTypeFormat::Double => openapiv3::VariantOrUnknownOrEmpty::Item(
111 openapiv3::NumberFormat::Double {},
112 ),
113 other => {
114 debug_assert!(false, "Invalid data type format: {:?}", other);
115 openapiv3::VariantOrUnknownOrEmpty::Empty
116 }
117 },
118 },
119 multiple_of: None,
120 exclusive_minimum: false,
121 exclusive_maximum: false,
122 minimum: None,
123 maximum: None,
124 enumeration: enum_
125 .iter()
126 .cloned()
127 .map(|v| serde_json::from_value(v).unwrap_or_default())
128 .collect(),
129 }))
130 }
131 v2::DataType::String => {
132 openapiv3::SchemaKind::Type(openapiv3::Type::String(openapiv3::StringType {
133 format: match format {
134 None => openapiv3::VariantOrUnknownOrEmpty::Empty,
135 Some(format) => match format {
136 v2::DataTypeFormat::Byte => {
137 openapiv3::VariantOrUnknownOrEmpty::Item(openapiv3::StringFormat::Byte)
138 }
139 v2::DataTypeFormat::Binary => openapiv3::VariantOrUnknownOrEmpty::Item(
140 openapiv3::StringFormat::Binary,
141 ),
142 v2::DataTypeFormat::Date => {
143 openapiv3::VariantOrUnknownOrEmpty::Item(openapiv3::StringFormat::Date)
144 }
145 v2::DataTypeFormat::DateTime => openapiv3::VariantOrUnknownOrEmpty::Item(
146 openapiv3::StringFormat::DateTime,
147 ),
148 v2::DataTypeFormat::Password => openapiv3::VariantOrUnknownOrEmpty::Item(
149 openapiv3::StringFormat::Password,
150 ),
151 v2::DataTypeFormat::Other => {
152 debug_assert!(false, "Invalid data type format: other");
153 openapiv3::VariantOrUnknownOrEmpty::Unknown(
154 v2::DataTypeFormat::Other.to_string(),
155 )
156 }
157 others => openapiv3::VariantOrUnknownOrEmpty::Unknown(others.to_string()),
158 },
159 },
160 pattern: None,
161 enumeration: enum_
162 .iter()
163 .cloned()
164 .map(|v| serde_json::from_value(v).unwrap_or_default())
165 .collect(),
166 min_length: None,
167 max_length: None,
168 }))
169 }
170 v2::DataType::Boolean => {
171 openapiv3::SchemaKind::Type(openapiv3::Type::Boolean(Default::default()))
172 }
173 v2::DataType::Array => {
174 openapiv3::SchemaKind::Type(openapiv3::Type::Array(openapiv3::ArrayType {
175 items: items.as_ref().map(|items| items.deref().clone().into()),
176 min_items: None,
177 max_items: None,
178 unique_items: false,
179 }))
180 }
181 v2::DataType::Object => {
182 openapiv3::SchemaKind::Type(openapiv3::Type::Object(openapiv3::ObjectType {
183 properties: {
184 properties.iter().fold(Default::default(), |mut i, b| {
185 i.insert(b.0.to_string(), b.1.deref().clone().into());
186 i
187 })
188 },
189 required: required.iter().cloned().collect::<Vec<_>>(),
190 additional_properties: extra_properties.as_ref().map(|e| match e {
191 Either::Right(box_schema) => openapiv3::AdditionalProperties::Schema(Box::new(
192 box_schema.deref().clone().into(),
193 )),
194 Either::Left(v) => openapiv3::AdditionalProperties::Any(*v),
195 }),
196 min_properties: None,
197 max_properties: None,
198 }))
199 }
200 v2::DataType::File => {
201 openapiv3::SchemaKind::Type(openapiv3::Type::String(openapiv3::StringType {
202 format: openapiv3::VariantOrUnknownOrEmpty::Item(openapiv3::StringFormat::Binary),
203 ..Default::default()
204 }))
205 }
206 }
207}
208
209impl From<v2::Items> for openapiv3::ReferenceOr<Box<openapiv3::Schema>> {
210 fn from(v2: v2::Items) -> Self {
211 let kind = match v2.data_type {
212 None => {
213 return invalid_referenceor("Invalid Item, should have a data type".into());
214 }
215 Some(data_type) => match data_type {
216 v2::DataType::Integer => {
217 openapiv3::SchemaKind::Type(openapiv3::Type::Integer(openapiv3::IntegerType {
218 format: match &v2.format {
219 None => openapiv3::VariantOrUnknownOrEmpty::Empty,
220 Some(format) => match format {
221 v2::DataTypeFormat::Int32 => {
222 openapiv3::VariantOrUnknownOrEmpty::Item(
223 openapiv3::IntegerFormat::Int32,
224 )
225 }
226 v2::DataTypeFormat::Int64 => {
227 openapiv3::VariantOrUnknownOrEmpty::Item(
228 openapiv3::IntegerFormat::Int64,
229 )
230 }
231 other => {
232 return invalid_referenceor(format!(
233 "Invalid data type format: {:?}",
234 other
235 ));
236 }
237 },
238 },
239 multiple_of: v2.multiple_of.map(|v| v as i64),
240 exclusive_minimum: v2.exclusive_minimum.unwrap_or_default(),
241 exclusive_maximum: v2.exclusive_maximum.unwrap_or_default(),
242 minimum: v2.minimum.map(|v| v as i64),
243 maximum: v2.maximum.map(|v| v as i64),
244 enumeration: v2
245 .enum_
246 .iter()
247 .cloned()
248 .map(|v| serde_json::from_value(v).unwrap_or_default())
249 .collect(),
250 }))
251 }
252 v2::DataType::Number => {
253 openapiv3::SchemaKind::Type(openapiv3::Type::Number(openapiv3::NumberType {
254 format: match &v2.format {
255 None => openapiv3::VariantOrUnknownOrEmpty::Empty,
256 Some(format) => match format {
257 v2::DataTypeFormat::Float => {
258 openapiv3::VariantOrUnknownOrEmpty::Item(
259 openapiv3::NumberFormat::Float {},
260 )
261 }
262 v2::DataTypeFormat::Double => {
263 openapiv3::VariantOrUnknownOrEmpty::Item(
264 openapiv3::NumberFormat::Double {},
265 )
266 }
267 other => {
268 return invalid_referenceor(format!(
269 "Invalid data type format: {:?}",
270 other
271 ));
272 }
273 },
274 },
275 multiple_of: v2.multiple_of.map(From::from),
276 exclusive_minimum: v2.exclusive_minimum.unwrap_or_default(),
277 exclusive_maximum: v2.exclusive_maximum.unwrap_or_default(),
278 minimum: v2.minimum.map(From::from),
279 maximum: v2.maximum.map(From::from),
280 enumeration: v2
281 .enum_
282 .iter()
283 .cloned()
284 .map(|v| serde_json::from_value(v).unwrap_or_default())
285 .collect(),
286 }))
287 }
288 v2::DataType::String => {
289 openapiv3::SchemaKind::Type(openapiv3::Type::String(openapiv3::StringType {
290 format: match &v2.format {
291 None => openapiv3::VariantOrUnknownOrEmpty::Empty,
292 Some(format) => match format {
293 v2::DataTypeFormat::Byte => {
294 openapiv3::VariantOrUnknownOrEmpty::Item(
295 openapiv3::StringFormat::Byte,
296 )
297 }
298 v2::DataTypeFormat::Binary => {
299 openapiv3::VariantOrUnknownOrEmpty::Item(
300 openapiv3::StringFormat::Binary,
301 )
302 }
303 v2::DataTypeFormat::Date => {
304 openapiv3::VariantOrUnknownOrEmpty::Item(
305 openapiv3::StringFormat::Date,
306 )
307 }
308 v2::DataTypeFormat::DateTime => {
309 openapiv3::VariantOrUnknownOrEmpty::Item(
310 openapiv3::StringFormat::DateTime,
311 )
312 }
313 v2::DataTypeFormat::Password => {
314 openapiv3::VariantOrUnknownOrEmpty::Item(
315 openapiv3::StringFormat::Password,
316 )
317 }
318 other => {
319 return invalid_referenceor(format!(
320 "Invalid data type format: {:?}",
321 other
322 ));
323 }
324 },
325 },
326 pattern: v2.pattern.clone(),
327 enumeration: v2
328 .enum_
329 .iter()
330 .cloned()
331 .map(|v| serde_json::from_value(v).unwrap_or_default())
332 .collect(),
333 min_length: v2.min_length.map(|v| v as usize),
334 max_length: v2.max_length.map(|v| v as usize),
335 }))
336 }
337 v2::DataType::Boolean => {
338 openapiv3::SchemaKind::Type(openapiv3::Type::Boolean(Default::default()))
339 }
340 v2::DataType::Array => {
341 openapiv3::SchemaKind::Type(openapiv3::Type::Array(openapiv3::ArrayType {
342 items: v2.items.map(|items| items.deref().clone().into()),
343 min_items: v2.min_items.map(|v| v as usize),
344 max_items: v2.max_items.map(|v| v as usize),
345 unique_items: v2.unique_items.unwrap_or_default(),
346 }))
347 }
348 invalid => {
349 return invalid_referenceor(format!("Invalid Item data_type: {:?}", invalid))
350 }
351 },
352 };
353
354 openapiv3::ReferenceOr::Item(Box::new(openapiv3::Schema {
355 schema_data: Default::default(),
356 schema_kind: kind,
357 }))
358 }
359}