salvo_oapi/openapi/
info.rs1use serde::{Deserialize, Serialize};
11
12use crate::PropMap;
13
14#[non_exhaustive]
30#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)]
31#[serde(rename_all = "camelCase")]
32pub struct Info {
33 pub title: String,
35
36 #[serde(skip_serializing_if = "Option::is_none")]
40 pub description: Option<String>,
41
42 #[serde(skip_serializing_if = "Option::is_none")]
44 pub terms_of_service: Option<String>,
45
46 #[serde(skip_serializing_if = "Option::is_none")]
50 pub contact: Option<Contact>,
51
52 #[serde(skip_serializing_if = "Option::is_none")]
56 pub license: Option<License>,
57
58 pub version: String,
60
61 #[serde(skip_serializing_if = "PropMap::is_empty", flatten)]
63 pub extensions: PropMap<String, serde_json::Value>,
64}
65
66impl Info {
67 #[must_use]
79 pub fn new(title: impl Into<String>, version: impl Into<String>) -> Self {
80 Self {
81 title: title.into(),
82 version: version.into(),
83 ..Default::default()
84 }
85 }
86 #[must_use]
88 pub fn title<I: Into<String>>(mut self, title: I) -> Self {
89 self.title = title.into();
90 self
91 }
92
93 #[must_use]
95 pub fn version<I: Into<String>>(mut self, version: I) -> Self {
96 self.version = version.into();
97 self
98 }
99
100 #[must_use]
102 pub fn description<S: Into<String>>(mut self, description: S) -> Self {
103 self.description = Some(description.into());
104 self
105 }
106
107 #[must_use]
109 pub fn terms_of_service<S: Into<String>>(mut self, terms_of_service: S) -> Self {
110 self.terms_of_service = Some(terms_of_service.into());
111 self
112 }
113
114 #[must_use]
116 pub fn contact(mut self, contact: Contact) -> Self {
117 self.contact = Some(contact);
118 self
119 }
120
121 #[must_use]
123 pub fn license(mut self, license: License) -> Self {
124 self.license = Some(license);
125 self
126 }
127}
128
129#[non_exhaustive]
135#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)]
136#[serde(rename_all = "camelCase")]
137pub struct Contact {
138 #[serde(skip_serializing_if = "Option::is_none")]
140 pub name: Option<String>,
141
142 #[serde(skip_serializing_if = "Option::is_none")]
144 pub url: Option<String>,
145
146 #[serde(skip_serializing_if = "Option::is_none")]
148 pub email: Option<String>,
149}
150
151impl Contact {
152 #[must_use]
154 pub fn new() -> Self {
155 Default::default()
156 }
157 #[must_use]
159 pub fn name<S: Into<String>>(mut self, name: S) -> Self {
160 self.name = Some(name.into());
161 self
162 }
163
164 #[must_use]
166 pub fn url<S: Into<String>>(mut self, url: S) -> Self {
167 self.url = Some(url.into());
168 self
169 }
170
171 #[must_use]
173 pub fn email<S: Into<String>>(mut self, email: S) -> Self {
174 self.email = Some(email.into());
175 self
176 }
177}
178
179#[non_exhaustive]
183#[derive(Serialize, Deserialize, Default, Clone, PartialEq, Eq, Debug)]
184#[serde(rename_all = "camelCase")]
185pub struct License {
186 pub name: String,
188
189 #[serde(skip_serializing_if = "Option::is_none")]
191 pub url: Option<String>,
192}
193
194impl License {
195 #[must_use]
199 pub fn new<S: Into<String>>(name: S) -> Self {
200 Self {
201 name: name.into(),
202 ..Default::default()
203 }
204 }
205 #[must_use]
207 pub fn name<S: Into<String>>(mut self, name: S) -> Self {
208 self.name = name.into();
209 self
210 }
211
212 #[must_use]
214 pub fn url<S: Into<String>>(mut self, url: S) -> Self {
215 self.url = Some(url.into());
216 self
217 }
218}
219
220#[cfg(test)]
221mod tests {
222 use assert_json_diff::assert_json_eq;
223 use serde_json::json;
224
225 use crate::License;
226
227 use super::Contact;
228
229 #[test]
230 fn build_contact() {
231 let contact = Contact::new();
232
233 assert!(contact.name.is_none());
234 assert!(contact.url.is_none());
235 assert!(contact.email.is_none());
236
237 let contact = contact
238 .name("salvo api")
239 .url("https://github.com/salvo-rs/salvo")
240 .email("salvo.rs@some.mail.com");
241 assert_json_eq!(
242 contact,
243 json!({
244 "name": "salvo api",
245 "url": "https://github.com/salvo-rs/salvo",
246 "email": "salvo.rs@some.mail.com"
247 })
248 );
249 }
250
251 #[test]
252 fn test_license_set_name() {
253 let license = License::default();
254 assert!(license.name.is_empty());
255
256 let license = license.name("MIT");
257 assert_json_eq!(license, json!({ "name": "MIT" }));
258 }
259}