use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[non_exhaustive]
#[derive(Serialize, Deserialize, Default, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "debug", derive(Debug))]
#[serde(rename_all = "camelCase")]
pub struct Info {
pub title: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub terms_of_service: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub contact: Option<Contact>,
#[serde(skip_serializing_if = "Option::is_none")]
pub license: Option<License>,
pub version: String,
#[serde(skip_serializing_if = "Option::is_none", flatten)]
pub extensions: Option<HashMap<String, serde_json::Value>>,
}
impl Info {
pub fn new(title: impl Into<String>, version: impl Into<String>) -> Self {
Self {
title: title.into(),
version: version.into(),
..Default::default()
}
}
pub fn title<I: Into<String>>(mut self, title: I) -> Self {
self.title = title.into();
self
}
pub fn version<I: Into<String>>(mut self, version: I) -> Self {
self.version = version.into();
self
}
pub fn description<S: Into<String>>(mut self, description: S) -> Self {
self.description = Some(description.into());
self
}
pub fn terms_of_service<S: Into<String>>(mut self, terms_of_service: S) -> Self {
self.terms_of_service = Some(terms_of_service.into());
self
}
pub fn contact(mut self, contact: Contact) -> Self {
self.contact = Some(contact);
self
}
pub fn license(mut self, license: License) -> Self {
self.license = Some(license);
self
}
}
#[non_exhaustive]
#[derive(Serialize, Deserialize, Default, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "debug", derive(Debug))]
#[serde(rename_all = "camelCase")]
pub struct Contact {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
}
impl Contact {
pub fn new() -> Self {
Default::default()
}
pub fn name<S: Into<String>>(mut self, name: S) -> Self {
self.name = Some(name.into());
self
}
pub fn url<S: Into<String>>(mut self, url: S) -> Self {
self.url = Some(url.into());
self
}
pub fn email<S: Into<String>>(mut self, email: S) -> Self {
self.email = Some(email.into());
self
}
}
#[non_exhaustive]
#[derive(Serialize, Deserialize, Default, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "debug", derive(Debug))]
#[serde(rename_all = "camelCase")]
pub struct License {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
}
impl License {
pub fn new<S: Into<String>>(name: S) -> Self {
Self {
name: name.into(),
..Default::default()
}
}
pub fn name<S: Into<String>>(mut self, name: S) -> Self {
self.name = name.into();
self
}
pub fn url<S: Into<String>>(mut self, url: S) -> Self {
self.url = Some(url.into());
self
}
}
#[cfg(test)]
mod tests {
use super::{Contact, License};
use assert_json_diff::assert_json_eq;
use serde_json::json;
#[test]
fn build_contact() {
let contact = Contact::new();
assert!(contact.name.is_none());
assert!(contact.url.is_none());
assert!(contact.email.is_none());
let contact = contact
.name("salvo api")
.url("https://github.com/salvo-rs/salvo")
.email("salvo.rs@some.mail.com");
assert_json_eq!(
contact,
json!({
"name": "salvo api",
"url": "https://github.com/salvo-rs/salvo",
"email": "salvo.rs@some.mail.com"
})
);
}
#[test]
fn test_license_set_name() {
let license = License::default();
assert!(license.name.is_empty());
let license = license.name("MIT");
assert_json_eq!(license, json!({ "name": "MIT" }));
}
}