1use serde::{Deserialize, Serialize};
2use std::fmt::Debug;
3
4use indexmap::IndexMap;
5use serde_json::Value;
6
7use crate::core::{Either, MayBeRefCore, ReferenceDescriptor};
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct Swagger2Ref {
11 #[serde(rename = "$ref")]
12 pub reference: String,
13}
14
15impl ReferenceDescriptor for Swagger2Ref {
16 fn reference(&self) -> &str {
17 &self.reference
18 }
19}
20
21pub type MayBeRef200<T> = MayBeRefCore<T, Swagger2Ref>;
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct ExternalDoc {
25 pub url: String,
26 pub description: Option<String>,
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize)]
30#[serde(rename_all = "camelCase")]
31pub struct Tag {
32 name: String,
33 description: Option<String>,
34 external_doc: Option<ExternalDoc>,
35}
36
37#[derive(Serialize, Deserialize, Debug, Clone, Default)]
38#[serde(rename_all = "camelCase")]
39pub struct Parameter {
40 pub name: String,
41 pub r#in: String,
42 pub description: Option<String>,
43 pub required: Option<bool>,
44
45 pub schema: Option<MayBeRef200<Schema>>,
46
47 pub r#type: Option<Either<String, Vec<String>>>,
48 pub format: Option<String>,
49 pub allow_empty_value: Option<bool>,
50 pub items: Option<MayBeRef200<Schema>>,
51 pub collection_format: Option<String>,
52 pub default: Option<Value>,
53 pub maximum: Option<f32>,
54 pub exclusive_maximum: Option<bool>,
55 pub minimum: Option<f32>,
56 pub exclusive_minimum: Option<bool>,
57 pub max_length: Option<usize>,
58 pub min_length: Option<usize>,
59 pub pattern: Option<String>,
60 pub max_items: Option<usize>,
61 pub min_items: Option<usize>,
62 pub unique_items: Option<bool>,
63 pub r#enum: Option<Vec<Value>>,
64 pub multiple_of: Option<f32>,
65
66 pub all_of: Option<Vec<MayBeRef200<Schema>>>,
68 pub any_of: Option<Vec<MayBeRef200<Schema>>>,
69 pub one_of: Option<Vec<MayBeRef200<Schema>>>,
70 pub not: Option<Vec<MayBeRef200<Schema>>>,
71
72 #[serde(flatten)]
73 pub custom_fields: IndexMap<String, Value>,
74}
75
76#[derive(Debug, Clone, Default, Serialize, Deserialize)]
77#[serde(rename_all = "camelCase")]
78pub struct Schema {
79 pub format: Option<String>,
80 pub title: Option<String>,
81 pub description: Option<String>,
82 pub default: Option<Value>,
83 pub multiple_of: Option<f32>,
84
85 pub maximum: Option<f32>,
86 pub exclusive_maximum: Option<bool>,
87 pub minimum: Option<f32>,
88 pub exclusive_minimum: Option<bool>,
89 pub max_length: Option<usize>,
90 pub min_length: Option<usize>,
91 pub pattern: Option<String>,
92 pub max_items: Option<usize>,
93 pub min_items: Option<usize>,
94 pub unique_items: Option<bool>,
95 pub max_properties: Option<usize>,
96 pub min_properties: Option<usize>,
97 pub required: Option<Vec<String>>,
98 pub r#enum: Option<Vec<Value>>,
99
100 pub r#type: Option<Either<String, Vec<String>>>,
101 pub items: Box<Option<MayBeRef200<Schema>>>,
102
103 pub all_of: Option<Vec<MayBeRef200<Schema>>>,
104
105 pub properties: Option<IndexMap<String, MayBeRef200<Schema>>>,
106 pub additional_properties: Option<Either<bool, MayBeRef200<Schema>>>,
107
108 pub discriminator: Option<String>,
109 pub read_only: Option<bool>,
110 pub external_docs: Option<ExternalDoc>,
112 pub example: Option<Value>,
113
114 pub one_of: Option<Vec<MayBeRef200<Schema>>>,
116 pub any_of: Option<Vec<MayBeRef200<Schema>>>,
117 pub not: Option<Vec<MayBeRef200<Schema>>>,
118
119 #[serde(flatten)]
120 pub custom_fields: IndexMap<String, Value>,
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize)]
124#[serde(rename_all = "camelCase")]
125pub struct Header {
126 pub description: Option<String>,
127 pub r#type: String,
128 pub format: Option<String>,
129 pub items: Option<MayBeRef200<Schema>>,
130
131 pub collection_format: Option<String>,
132 pub default: Option<Value>,
133 pub maximum: Option<f32>,
134 pub exclusive_maximum: Option<bool>,
135 pub minimum: Option<f32>,
136 pub exclusive_minimum: Option<bool>,
137 pub max_length: Option<usize>,
138 pub min_length: Option<usize>,
139 pub pattern: Option<String>,
140 pub max_items: Option<usize>,
141 pub min_items: Option<usize>,
142 pub unique_items: Option<bool>,
143 pub r#enum: Option<Vec<Value>>,
144 pub multiple_of: Option<f32>,
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize)]
148#[serde(rename_all = "camelCase")]
149pub struct MediaType {
150 content_type: String,
151 schema: MayBeRef200<Schema>,
152 example: Option<String>,
153 }
156
157#[derive(Debug, Clone, Serialize, Deserialize)]
158pub struct Response {
159 pub description: Option<String>,
160 pub schema: Option<MayBeRef200<Schema>>,
161 pub headers: Option<IndexMap<String, Header>>,
162 pub example: Option<Example>,
163}
164
165#[derive(Debug, Clone, Default, Serialize, Deserialize)]
166pub struct Example {
167 #[serde(flatten)]
168 pub examples: IndexMap<String, Value>,
169}
170
171#[derive(Debug, Clone, Default, Serialize, Deserialize)]
172#[serde(rename_all = "camelCase")]
173pub struct Operation {
174 pub tags: Vec<String>,
175 pub summary: Option<String>,
176 pub description: Option<String>,
177
178 pub external_docs: Option<ExternalDoc>,
179
180 pub operation_id: Option<String>,
181
182 pub consumes: Option<Vec<String>>,
183 pub produces: Option<Vec<String>>,
184
185 pub parameters: Option<Vec<MayBeRef200<Parameter>>>,
186 pub responses: IndexMap<String, MayBeRef200<Response>>,
187
188 pub schemes: Option<Vec<String>>,
189 pub deprecated: Option<bool>,
190 }
192
193#[derive(Debug, Clone, Default, Serialize, Deserialize)]
194pub struct Path {
195 pub get: Option<Operation>,
196 pub put: Option<Operation>,
197 pub post: Option<Operation>,
198 pub delete: Option<Operation>,
199 pub options: Option<Operation>,
200 pub head: Option<Operation>,
201 pub patch: Option<Operation>,
202 pub parameters: Option<Vec<MayBeRef200<Parameter>>>,
203}
204
205#[derive(Debug, Clone, Serialize, Deserialize)]
206pub struct Contact {
207 pub name: Option<String>,
208 pub url: Option<String>,
209 pub email: Option<String>,
210}
211
212#[derive(Debug, Clone, Serialize, Deserialize)]
213pub struct License {
214 pub name: Option<String>,
215 pub url: Option<String>,
216}
217
218#[derive(Debug, Clone, Serialize, Deserialize)]
219#[serde(rename_all = "camelCase")]
220pub struct Info {
221 pub title: Option<String>,
222 pub description: Option<String>,
223 pub terms_of_service: Option<String>,
224
225 pub contact: Option<Contact>,
226 pub license: Option<License>,
227
228 pub version: Option<String>,
229}
230
231#[derive(Debug, Clone, Serialize, Deserialize)]
232#[serde(rename_all = "camelCase")]
233pub struct SwaggerV2 {
234 pub swagger: String,
235 pub info: Option<Info>,
236
237 pub consumes: Option<Vec<String>>,
238 pub produces: Option<Vec<String>>,
239
240 pub paths: Option<IndexMap<String, Path>>,
241 pub definitions: Option<IndexMap<String, Schema>>,
242 pub parameters: Option<IndexMap<String, Parameter>>,
243 pub responses: Option<IndexMap<String, Response>>,
244}
245
246impl SwaggerV2 {
247 pub const fn id() -> &'static str {
248 "SwaggerV2"
249 }
250}
251
252#[cfg(test)]
253mod tests {
254 use crate::schema::Schema;
255
256 #[test]
257 fn test_schema_example_is_generic_value() {
258 let s = r#"
259 {
260 "example": {
261 "grant_type": "password",
262 "password": "admin",
263 "username": "admin"
264 }
265 }
266"#;
267
268 let _: Schema = serde_json::from_str(s).unwrap();
269 }
270}