schemadoc_diff/schemas/swagger2/
schema.rs

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    // Not in schema
67    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    // xml: Option<Xml>,
111    pub external_docs: Option<ExternalDoc>,
112    pub example: Option<Value>,
113
114    // Not in schema
115    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    // examples
154    // encoding: Vec<>
155}
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    // pub security: Option<Security>,
191}
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}