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