salvo_oapi/openapi/
info.rs1use serde::{Deserialize, Serialize};
11
12use crate::PropMap;
13
14#[non_exhaustive]
28#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)]
29#[serde(rename_all = "camelCase")]
30pub struct Info {
31 pub title: String,
33
34 #[serde(skip_serializing_if = "Option::is_none")]
38 pub description: Option<String>,
39
40 #[serde(skip_serializing_if = "Option::is_none")]
42 pub terms_of_service: Option<String>,
43
44 #[serde(skip_serializing_if = "Option::is_none")]
48 pub contact: Option<Contact>,
49
50 #[serde(skip_serializing_if = "Option::is_none")]
54 pub license: Option<License>,
55
56 pub version: String,
58
59 #[serde(skip_serializing_if = "PropMap::is_empty", flatten)]
61 pub extensions: PropMap<String, serde_json::Value>,
62}
63
64impl Info {
65 #[must_use]
77 pub fn new(title: impl Into<String>, version: impl Into<String>) -> Self {
78 Self {
79 title: title.into(),
80 version: version.into(),
81 ..Default::default()
82 }
83 }
84 #[must_use]
86 pub fn title<I: Into<String>>(mut self, title: I) -> Self {
87 self.title = title.into();
88 self
89 }
90
91 #[must_use]
93 pub fn version<I: Into<String>>(mut self, version: I) -> Self {
94 self.version = version.into();
95 self
96 }
97
98 #[must_use]
100 pub fn description<S: Into<String>>(mut self, description: S) -> Self {
101 self.description = Some(description.into());
102 self
103 }
104
105 #[must_use]
107 pub fn terms_of_service<S: Into<String>>(mut self, terms_of_service: S) -> Self {
108 self.terms_of_service = Some(terms_of_service.into());
109 self
110 }
111
112 #[must_use]
114 pub fn contact(mut self, contact: Contact) -> Self {
115 self.contact = Some(contact);
116 self
117 }
118
119 #[must_use]
121 pub fn license(mut self, license: License) -> Self {
122 self.license = Some(license);
123 self
124 }
125}
126
127#[non_exhaustive]
133#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)]
134#[serde(rename_all = "camelCase")]
135pub struct Contact {
136 #[serde(skip_serializing_if = "Option::is_none")]
138 pub name: Option<String>,
139
140 #[serde(skip_serializing_if = "Option::is_none")]
142 pub url: Option<String>,
143
144 #[serde(skip_serializing_if = "Option::is_none")]
146 pub email: Option<String>,
147}
148
149impl Contact {
150 #[must_use]
152 pub fn new() -> Self {
153 Default::default()
154 }
155 #[must_use]
157 pub fn name<S: Into<String>>(mut self, name: S) -> Self {
158 self.name = Some(name.into());
159 self
160 }
161
162 #[must_use]
164 pub fn url<S: Into<String>>(mut self, url: S) -> Self {
165 self.url = Some(url.into());
166 self
167 }
168
169 #[must_use]
171 pub fn email<S: Into<String>>(mut self, email: S) -> Self {
172 self.email = Some(email.into());
173 self
174 }
175}
176
177#[non_exhaustive]
181#[derive(Serialize, Deserialize, Default, Clone, PartialEq, Eq, Debug)]
182#[serde(rename_all = "camelCase")]
183pub struct License {
184 pub name: String,
186
187 #[serde(skip_serializing_if = "Option::is_none")]
189 pub url: Option<String>,
190}
191
192impl License {
193 #[must_use]
197 pub fn new<S: Into<String>>(name: S) -> Self {
198 Self {
199 name: name.into(),
200 ..Default::default()
201 }
202 }
203 #[must_use]
205 pub fn name<S: Into<String>>(mut self, name: S) -> Self {
206 self.name = name.into();
207 self
208 }
209
210 #[must_use]
212 pub fn url<S: Into<String>>(mut self, url: S) -> Self {
213 self.url = Some(url.into());
214 self
215 }
216}
217
218#[cfg(test)]
219mod tests {
220 use assert_json_diff::assert_json_eq;
221 use serde_json::json;
222
223 use super::Contact;
224 use crate::License;
225
226 #[test]
227 fn build_contact() {
228 let contact = Contact::new();
229
230 assert!(contact.name.is_none());
231 assert!(contact.url.is_none());
232 assert!(contact.email.is_none());
233
234 let contact = contact
235 .name("salvo api")
236 .url("https://github.com/salvo-rs/salvo")
237 .email("salvo.rs@some.mail.com");
238 assert_json_eq!(
239 contact,
240 json!({
241 "name": "salvo api",
242 "url": "https://github.com/salvo-rs/salvo",
243 "email": "salvo.rs@some.mail.com"
244 })
245 );
246 }
247
248 #[test]
249 fn test_license_set_name() {
250 let license = License::default();
251 assert!(license.name.is_empty());
252
253 let license = license.name("MIT");
254 assert_json_eq!(license, json!({ "name": "MIT" }));
255 }
256}