restify_openapi/models/
mod.rs1#![allow(clippy::derive_partial_eq_without_eq)]
7
8use crate::models::components::Components;
9use crate::models::info::Info;
10use crate::models::paths::{ExternalDocumentation, Paths};
11use crate::models::security::SecurityRequirement;
12use crate::models::server::Server;
13use crate::models::tag::Tag;
14use indexmap::IndexMap;
15use serde::Serialize;
16use serde_json::Value;
17
18pub mod components;
19pub mod info;
20pub mod paths;
21pub mod reference_or;
22pub mod security;
23pub mod server;
24pub mod tag;
25
26pub use schemars::schema::*;
27
28#[derive(Serialize, Clone, Debug)]
29#[cfg_attr(
30 any(test, feature = "deserialize"),
31 derive(serde::Deserialize, PartialEq)
32)]
33pub enum OpenApiVersion {
34 #[serde(rename = "3.0.3")]
35 OAS3_0,
36}
37
38impl Default for OpenApiVersion {
39 fn default() -> Self {
40 Self::OAS3_0
41 }
42}
43
44#[derive(Serialize, Clone, Debug, Default)]
46#[cfg_attr(
47 any(test, feature = "deserialize"),
48 derive(serde::Deserialize, PartialEq)
49)]
50#[serde(rename_all = "camelCase")]
51pub struct OpenApi {
52 pub openapi: OpenApiVersion,
54 pub info: Info,
56 pub servers: Vec<Server>,
58 pub paths: Paths,
60 #[serde(skip_serializing_if = "Option::is_none")]
62 pub components: Option<Components>,
63 #[serde(skip_serializing_if = "Vec::is_empty", default)]
65 pub security: Vec<SecurityRequirement>,
66 #[serde(skip_serializing_if = "Vec::is_empty", default)]
68 pub tags: Vec<Tag>,
69 #[serde(skip_serializing_if = "Option::is_none")]
71 pub external_docs: Option<ExternalDocumentation>,
72 #[serde(
74 flatten,
75 skip_serializing_if = "IndexMap::is_empty",
76 skip_deserializing
77 )]
78 pub extensions: IndexMap<String, Value>,
79}
80
81#[cfg(test)]
82mod test {
83 #![allow(clippy::expect_used)]
84
85 use crate::models::info::Info;
86 use crate::models::paths::{Operation, OperationType, PathItem, Paths, Response, Responses};
87 use crate::models::reference_or::ReferenceOr;
88 use crate::models::server::Server;
89 use crate::models::tag::Tag;
90 use crate::models::{OpenApi, OpenApiVersion};
91 use indexmap::IndexMap;
92 use std::collections::BTreeMap;
93
94 #[test]
95 fn empty_openapi_properly_generated() {
96 let oas = OpenApi {
97 openapi: OpenApiVersion::OAS3_0,
98 info: Info {
99 title: "Test".to_string(),
100 description: Some("Description".to_string()),
101 version: "1.0.0".to_string(),
102 ..Default::default()
103 },
104 paths: Paths::default(),
105 ..Default::default()
106 };
107
108 let oas_json = serde_json::to_string_pretty(&oas).expect("Error generating json for oas");
109 assert_eq!(
110 oas_json,
111 include_str!("../../test-assets/empty-openapi.json")
112 );
113 }
114
115 #[test]
116 fn openapi_properly_generated() {
117 let oas = OpenApi {
118 openapi: OpenApiVersion::OAS3_0,
119 info: Info {
120 title: "Test".to_string(),
121 description: Some("Description".to_string()),
122 version: "1.0.0".to_string(),
123 ..Default::default()
124 },
125 servers: vec![Server {
126 url: "https://google.com".to_string(),
127 description: Some("A big search server".to_string()),
128 ..Default::default()
129 }],
130 paths: Paths {
131 paths: IndexMap::from_iter(vec![(
132 "/search".to_string(),
133 PathItem {
134 operations: IndexMap::from_iter(vec![(
135 OperationType::Get,
136 Operation {
137 tags: vec!["Search".to_string()],
138 summary: Some("I don't know what this do".to_string()),
139 operation_id: Some("get_search".to_string()),
140 responses: Responses {
141 responses: BTreeMap::from_iter(vec![(
142 "200".to_string(),
143 ReferenceOr::Object(Response {
144 description: "A search thingy".to_string(),
145 ..Default::default()
146 }),
147 )]),
148 ..Default::default()
149 },
150 ..Default::default()
151 },
152 )]),
153 ..Default::default()
154 },
155 )]),
156 ..Default::default()
157 },
158 tags: vec![Tag {
159 name: "Search".to_string(),
160 ..Default::default()
161 }],
162 ..Default::default()
163 };
164
165 let oas_json = serde_json::to_string_pretty(&oas).expect("Error generating json for oas");
166 assert_eq!(oas_json, include_str!("../../test-assets/openapi.json"));
167 }
168}