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 pub fn new(title: impl Into<String>, version: impl Into<String>) -> Self {
79 Self {
80 title: title.into(),
81 version: version.into(),
82 ..Default::default()
83 }
84 }
85 pub fn title<I: Into<String>>(mut self, title: I) -> Self {
87 self.title = title.into();
88 self
89 }
90
91 pub fn version<I: Into<String>>(mut self, version: I) -> Self {
93 self.version = version.into();
94 self
95 }
96
97 pub fn description<S: Into<String>>(mut self, description: S) -> Self {
99 self.description = Some(description.into());
100 self
101 }
102
103 pub fn terms_of_service<S: Into<String>>(mut self, terms_of_service: S) -> Self {
105 self.terms_of_service = Some(terms_of_service.into());
106 self
107 }
108
109 pub fn contact(mut self, contact: Contact) -> Self {
111 self.contact = Some(contact);
112 self
113 }
114
115 pub fn license(mut self, license: License) -> Self {
117 self.license = Some(license);
118 self
119 }
120}
121
122#[non_exhaustive]
128#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)]
129#[serde(rename_all = "camelCase")]
130pub struct Contact {
131 #[serde(skip_serializing_if = "Option::is_none")]
133 pub name: Option<String>,
134
135 #[serde(skip_serializing_if = "Option::is_none")]
137 pub url: Option<String>,
138
139 #[serde(skip_serializing_if = "Option::is_none")]
141 pub email: Option<String>,
142}
143
144impl Contact {
145 pub fn new() -> Self {
147 Default::default()
148 }
149 pub fn name<S: Into<String>>(mut self, name: S) -> Self {
151 self.name = Some(name.into());
152 self
153 }
154
155 pub fn url<S: Into<String>>(mut self, url: S) -> Self {
157 self.url = Some(url.into());
158 self
159 }
160
161 pub fn email<S: Into<String>>(mut self, email: S) -> Self {
163 self.email = Some(email.into());
164 self
165 }
166}
167
168#[non_exhaustive]
172#[derive(Serialize, Deserialize, Default, Clone, PartialEq, Eq, Debug)]
173#[serde(rename_all = "camelCase")]
174pub struct License {
175 pub name: String,
177
178 #[serde(skip_serializing_if = "Option::is_none")]
180 pub url: Option<String>,
181}
182
183impl License {
184 pub fn new<S: Into<String>>(name: S) -> Self {
188 Self {
189 name: name.into(),
190 ..Default::default()
191 }
192 }
193 pub fn name<S: Into<String>>(mut self, name: S) -> Self {
195 self.name = name.into();
196 self
197 }
198
199 pub fn url<S: Into<String>>(mut self, url: S) -> Self {
201 self.url = Some(url.into());
202 self
203 }
204}
205
206#[cfg(test)]
207mod tests {
208 use assert_json_diff::assert_json_eq;
209 use serde_json::json;
210
211 use crate::License;
212
213 use super::Contact;
214
215 #[test]
216 fn build_contact() {
217 let contact = Contact::new();
218
219 assert!(contact.name.is_none());
220 assert!(contact.url.is_none());
221 assert!(contact.email.is_none());
222
223 let contact = contact
224 .name("salvo api")
225 .url("https://github.com/salvo-rs/salvo")
226 .email("salvo.rs@some.mail.com");
227 assert_json_eq!(
228 contact,
229 json!({
230 "name": "salvo api",
231 "url": "https://github.com/salvo-rs/salvo",
232 "email": "salvo.rs@some.mail.com"
233 })
234 );
235 }
236
237 #[test]
238 fn test_license_set_name() {
239 let license = License::default();
240 assert!(license.name.is_empty());
241
242 let license = license.name("MIT");
243 assert_json_eq!(license, json!({ "name": "MIT" }));
244 }
245}