salvo_oapi/openapi/
content.rs1use serde::{Deserialize, Serialize};
3
4use serde_json::Value;
5
6use super::PropMap;
7use super::example::Example;
8use super::{RefOr, Schema, encoding::Encoding};
9
10#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq)]
12#[non_exhaustive]
13pub struct Content {
14 pub schema: RefOr<Schema>,
16
17 #[serde(skip_serializing_if = "Option::is_none")]
19 pub example: Option<Value>,
20
21 #[serde(skip_serializing_if = "PropMap::is_empty")]
26 pub examples: PropMap<String, RefOr<Example>>,
27
28 #[serde(skip_serializing_if = "PropMap::is_empty", default)]
37 pub encoding: PropMap<String, Encoding>,
38}
39
40impl Content {
41 #[must_use]
43 pub fn new<I: Into<RefOr<Schema>>>(schema: I) -> Self {
44 Self {
45 schema: schema.into(),
46 ..Self::default()
47 }
48 }
49
50 #[must_use]
52 pub fn schema<I: Into<RefOr<Schema>>>(mut self, component: I) -> Self {
53 self.schema = component.into();
54 self
55 }
56
57 #[must_use]
59 pub fn example(mut self, example: Value) -> Self {
60 self.example = Some(example);
61 self
62 }
63
64 #[must_use]
72 pub fn extend_examples<
73 E: IntoIterator<Item = (N, V)>,
74 N: Into<String>,
75 V: Into<RefOr<Example>>,
76 >(
77 mut self,
78 examples: E,
79 ) -> Self {
80 self.examples.extend(
81 examples
82 .into_iter()
83 .map(|(name, example)| (name.into(), example.into())),
84 );
85
86 self
87 }
88
89 #[must_use]
98 pub fn encoding<S: Into<String>, E: Into<Encoding>>(
99 mut self,
100 property_name: S,
101 encoding: E,
102 ) -> Self {
103 self.encoding.insert(property_name.into(), encoding.into());
104 self
105 }
106}
107
108impl From<RefOr<Schema>> for Content {
109 fn from(schema: RefOr<Schema>) -> Self {
110 Self {
111 schema,
112 ..Self::default()
113 }
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use assert_json_diff::assert_json_eq;
120 use serde_json::{Map, json};
121
122 use super::*;
123
124 #[test]
125 fn test_build_content() {
126 let content = Content::new(RefOr::Ref(crate::Ref::from_schema_name("MySchema")))
127 .example(Value::Object(Map::from_iter([(
128 "schema".into(),
129 Value::String("MySchema".to_owned()),
130 )])))
131 .encoding(
132 "schema".to_owned(),
133 Encoding::default().content_type("text/plain"),
134 );
135 assert_json_eq!(
136 content,
137 json!({
138 "schema": {
139 "$ref": "#/components/schemas/MySchema"
140 },
141 "example": {
142 "schema": "MySchema"
143 },
144 "encoding": {
145 "schema": {
146 "contentType": "text/plain"
147 }
148 }
149 })
150 );
151
152 let content = content
153 .schema(RefOr::Ref(crate::Ref::from_schema_name("NewSchema")))
154 .extend_examples([(
155 "example1".to_owned(),
156 Example::new().value(Value::Object(Map::from_iter([(
157 "schema".into(),
158 Value::String("MySchema".to_owned()),
159 )]))),
160 )]);
161 assert_json_eq!(
162 content,
163 json!({
164 "schema": {
165 "$ref": "#/components/schemas/NewSchema"
166 },
167 "example": {
168 "schema": "MySchema"
169 },
170 "examples": {
171 "example1": {
172 "value": {
173 "schema": "MySchema"
174 }
175 }
176 },
177 "encoding": {
178 "schema": {
179 "contentType": "text/plain"
180 }
181 }
182 })
183 );
184 }
185}