1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::{Discriminator, RefOr, Schema};
/// AllOf [Composite Object][allof] component holds
/// multiple components together where API endpoint will return a combination of all of them.
///
/// See [`Schema::AllOf`] for more details.
///
/// [allof]: https://spec.openapis.org/oas/latest.html#components-object
#[non_exhaustive]
#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq)]
pub struct AllOf {
/// Components of _AllOf_ component.
#[serde(rename = "allOf")]
pub items: Vec<RefOr<Schema>>,
/// Changes the [`AllOf`] title.
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
/// Description of the [`AllOf`]. Markdown syntax is supported.
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
/// Default value which is provided when user has not provided the input in Swagger UI.
#[serde(rename = "default", skip_serializing_if = "Option::is_none")]
pub default_value: Option<Value>,
/// Example shown in UI of the value for richer documentation.
#[serde(skip_serializing_if = "Option::is_none")]
pub example: Option<Value>,
/// Optional discriminator field can be used to aid deserialization, serialization and validation of a
/// specific schema.
#[serde(skip_serializing_if = "Option::is_none")]
pub discriminator: Option<Discriminator>,
/// Set `true` to allow `"null"` to be used as value for given type.
#[serde(default, skip_serializing_if = "super::is_false")]
pub nullable: bool,
}
impl AllOf {
/// Construct a new empty [`AllOf`]. This is effectively same as calling [`AllOf::default`].
pub fn new() -> Self {
Default::default()
}
/// Construct a new [`AllOf`] component with given capacity.
///
/// AllOf component is then able to contain number of components without
/// reallocating.
///
/// # Examples
///
/// Create [`AllOf`] component with initial capacity of 5.
/// ```
/// # use salvo_oapi::schema::AllOf;
/// let one_of = AllOf::with_capacity(5);
/// ```
pub fn with_capacity(capacity: usize) -> Self {
Self {
items: Vec::with_capacity(capacity),
..Default::default()
}
}
/// Adds a given [`Schema`] to [`AllOf`] [Composite Object][composite]
///
/// [composite]: https://spec.openapis.org/oas/latest.html#components-object
pub fn item<I: Into<RefOr<Schema>>>(mut self, component: I) -> Self {
self.items.push(component.into());
self
}
/// Add or change the title of the [`AllOf`].
pub fn title(mut self, title: impl Into<String>) -> Self {
self.title = Some(title.into());
self
}
/// Add or change optional description for `AllOf` component.
pub fn description(mut self, description: impl Into<String>) -> Self {
self.description = Some(description.into());
self
}
/// Add or change default value for the object which is provided when user has not provided the input in Swagger UI.
pub fn default_value(mut self, default: Value) -> Self {
self.default_value = Some(default);
self
}
/// Add or change example shown in UI of the value for richer documentation.
pub fn example(mut self, example: Value) -> Self {
self.example = Some(example);
self
}
/// Add or change discriminator field of the composite [`AllOf`] type.
pub fn discriminator(mut self, discriminator: Discriminator) -> Self {
self.discriminator = Some(discriminator);
self
}
/// Add or change nullable flag for [Object][crate::Object].
pub fn nullable(mut self, nullable: bool) -> Self {
self.nullable = nullable;
self
}
}
impl From<AllOf> for Schema {
fn from(one_of: AllOf) -> Self {
Self::AllOf(one_of)
}
}
impl From<AllOf> for RefOr<Schema> {
fn from(one_of: AllOf) -> Self {
Self::T(Schema::AllOf(one_of))
}
}
#[cfg(test)]
mod tests {
use assert_json_diff::assert_json_eq;
use serde_json::json;
use super::*;
#[test]
fn test_build_all_of() {
let all_of = AllOf::with_capacity(5)
.title("title")
.description("description")
.default_value(Value::String("default".to_string()))
.example(Value::String("example".to_string()))
.discriminator(Discriminator::new("discriminator".to_string()))
.nullable(true);
assert_eq!(all_of.items.len(), 0);
assert_eq!(all_of.items.capacity(), 5);
assert_json_eq!(
all_of,
json!({
"allOf": [],
"title": "title",
"description": "description",
"default": "default",
"example": "example",
"discriminator": {
"propertyName": "discriminator"
},
"nullable": true
})
)
}
#[test]
fn test_schema_from_all_of() {
let all_of = AllOf::new();
let schema = Schema::from(all_of);
assert_json_eq!(
schema,
json!({
"allOf": []
})
)
}
#[test]
fn test_refor_schema_from_all_of() {
let all_of = AllOf::new();
let ref_or: RefOr<Schema> = RefOr::from(all_of);
assert_json_eq!(
ref_or,
json!({
"allOf": []
})
)
}
}