1use serde_derive::{Deserialize, Serialize};
6
7use super::extensions::Extensions;
8
9#[non_exhaustive]
16#[derive(Serialize, Deserialize, Default, Clone, PartialEq, Eq, bon::Builder)]
17#[cfg_attr(feature = "debug", derive(Debug))]
18#[serde(rename_all = "camelCase")]
19#[builder(on(_, into))]
20pub struct Info {
21 pub title: String,
23
24 #[serde(skip_serializing_if = "Option::is_none", default)]
28 pub description: Option<String>,
29
30 #[serde(skip_serializing_if = "Option::is_none", default)]
32 pub terms_of_service: Option<String>,
33
34 #[serde(skip_serializing_if = "Option::is_none", default)]
38 pub contact: Option<Contact>,
39
40 #[serde(skip_serializing_if = "Option::is_none", default)]
44 pub license: Option<License>,
45
46 pub version: String,
48
49 #[serde(skip_serializing_if = "Option::is_none", default, flatten)]
51 pub extensions: Option<Extensions>,
52}
53
54impl<S: info_builder::IsComplete> From<InfoBuilder<S>> for Info {
55 fn from(builder: InfoBuilder<S>) -> Self {
56 builder.build()
57 }
58}
59
60impl Info {
61 pub fn new<S: Into<String>>(title: S, version: S) -> Self {
73 Self {
74 title: title.into(),
75 version: version.into(),
76 ..Default::default()
77 }
78 }
79}
80
81#[non_exhaustive]
88#[derive(Serialize, Deserialize, Default, Clone, PartialEq, Eq, bon::Builder)]
89#[cfg_attr(feature = "debug", derive(Debug))]
90#[serde(rename_all = "camelCase")]
91#[builder(on(_, into))]
92pub struct Contact {
93 #[serde(skip_serializing_if = "Option::is_none", default)]
95 pub name: Option<String>,
96
97 #[serde(skip_serializing_if = "Option::is_none", default)]
99 pub url: Option<String>,
100
101 #[serde(skip_serializing_if = "Option::is_none", default)]
103 pub email: Option<String>,
104
105 #[serde(skip_serializing_if = "Option::is_none", default, flatten)]
107 pub extensions: Option<Extensions>,
108}
109
110impl Contact {
111 pub fn new() -> Self {
113 Default::default()
114 }
115}
116
117impl<S: contact_builder::IsComplete> From<ContactBuilder<S>> for Contact {
118 fn from(builder: ContactBuilder<S>) -> Self {
119 builder.build()
120 }
121}
122
123#[non_exhaustive]
127#[derive(Serialize, Deserialize, Default, Clone, PartialEq, Eq, bon::Builder)]
128#[cfg_attr(feature = "debug", derive(Debug))]
129#[serde(rename_all = "camelCase")]
130#[builder(on(_, into))]
131pub struct License {
132 pub name: String,
134
135 #[serde(skip_serializing_if = "Option::is_none", default)]
137 pub url: Option<String>,
138
139 #[serde(skip_serializing_if = "Option::is_none", default)]
144 pub identifier: Option<String>,
145
146 #[serde(skip_serializing_if = "Option::is_none", default, flatten)]
148 pub extensions: Option<Extensions>,
149}
150
151impl License {
152 pub fn new<S: Into<String>>(name: S) -> Self {
156 Self {
157 name: name.into(),
158 ..Default::default()
159 }
160 }
161}
162
163impl<S: license_builder::IsComplete> From<LicenseBuilder<S>> for License {
164 fn from(builder: LicenseBuilder<S>) -> Self {
165 builder.build()
166 }
167}
168
169#[cfg(test)]
170#[cfg_attr(coverage_nightly, coverage(off))]
171mod tests {
172 use super::Contact;
173
174 #[test]
175 fn contact_new() {
176 let contact = Contact::new();
177
178 assert!(contact.name.is_none());
179 assert!(contact.url.is_none());
180 assert!(contact.email.is_none());
181 }
182}