salvo_oapi/openapi/
request_body.rs1use indexmap::IndexMap;
5use serde::{Deserialize, Serialize};
6
7use super::{Content, Required};
8
9#[non_exhaustive]
13#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq)]
14#[serde(rename_all = "camelCase")]
15pub struct RequestBody {
16 #[serde(skip_serializing_if = "Option::is_none")]
18 pub description: Option<String>,
19
20 #[serde(rename = "content")]
22 pub contents: IndexMap<String, Content>,
23
24 #[serde(skip_serializing_if = "Option::is_none")]
26 pub required: Option<Required>,
27}
28
29impl RequestBody {
30 #[must_use]
32 pub fn new() -> Self {
33 Default::default()
34 }
35 #[must_use]
37 pub fn description<S: Into<String>>(mut self, description: S) -> Self {
38 self.description = Some(description.into());
39 self
40 }
41
42 #[must_use]
44 pub fn required(mut self, required: Required) -> Self {
45 self.required = Some(required);
46 self
47 }
48
49 #[must_use]
51 pub fn add_content<S: Into<String>, C: Into<Content>>(mut self, kind: S, content: C) -> Self {
52 self.contents.insert(kind.into(), content.into());
53 self
54 }
55
56 pub fn merge(&mut self, other: Self) {
58 let Self {
59 description,
60 contents,
61 required,
62 } = other;
63 if let Some(description) = description {
64 if !description.is_empty() {
65 self.description = Some(description);
66 }
67 }
68 self.contents.extend(contents);
69 if let Some(required) = required {
70 self.required = Some(required);
71 }
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use assert_json_diff::assert_json_eq;
78 use serde_json::json;
79
80 use super::{Content, RequestBody, Required};
81
82 #[test]
83 fn request_body_new() {
84 let request_body = RequestBody::new();
85
86 assert!(request_body.contents.is_empty());
87 assert_eq!(request_body.description, None);
88 assert!(request_body.required.is_none());
89 }
90
91 #[test]
92 fn request_body_builder() -> Result<(), serde_json::Error> {
93 let request_body = RequestBody::new()
94 .description("A sample requestBody")
95 .required(Required::True)
96 .add_content(
97 "application/json",
98 Content::new(crate::Ref::from_schema_name("EmailPayload")),
99 );
100
101 assert_json_eq!(
102 request_body,
103 json!({
104 "description": "A sample requestBody",
105 "content": {
106 "application/json": {
107 "schema": {
108 "$ref": "#/components/schemas/EmailPayload"
109 }
110 }
111 },
112 "required": true
113 })
114 );
115 Ok(())
116 }
117
118 #[test]
119 fn request_body_merge() {
120 let mut request_body = RequestBody::new();
121 let other_request_body = RequestBody::new()
122 .description("Merged requestBody")
123 .required(Required::True)
124 .add_content(
125 "application/json",
126 Content::new(crate::Ref::from_schema_name("EmailPayload")),
127 );
128
129 request_body.merge(other_request_body);
130 assert_json_eq!(
131 request_body,
132 json!({
133 "description": "Merged requestBody",
134 "content": {
135 "application/json": {
136 "schema": {
137 "$ref": "#/components/schemas/EmailPayload"
138 }
139 }
140 },
141 "required": true
142 })
143 );
144 }
145}