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]
33 pub fn new() -> Self {
34 Default::default()
35 }
36 #[must_use]
38 pub fn description<S: Into<String>>(mut self, description: S) -> Self {
39 self.description = Some(description.into());
40 self
41 }
42
43 #[must_use]
45 pub fn required(mut self, required: Required) -> Self {
46 self.required = Some(required);
47 self
48 }
49
50 #[must_use]
52 pub fn add_content<S: Into<String>, C: Into<Content>>(mut self, kind: S, content: C) -> Self {
53 self.contents.insert(kind.into(), content.into());
54 self
55 }
56
57 pub fn merge(&mut self, other: Self) {
59 let Self {
60 description,
61 contents,
62 required,
63 } = other;
64 if let Some(description) = description
65 && !description.is_empty()
66 {
67 self.description = Some(description);
68 }
69 self.contents.extend(contents);
70 if let Some(required) = required {
71 self.required = Some(required);
72 }
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use assert_json_diff::assert_json_eq;
79 use serde_json::json;
80
81 use super::{Content, RequestBody, Required};
82
83 #[test]
84 fn request_body_new() {
85 let request_body = RequestBody::new();
86
87 assert!(request_body.contents.is_empty());
88 assert_eq!(request_body.description, None);
89 assert!(request_body.required.is_none());
90 }
91
92 #[test]
93 fn request_body_builder() -> Result<(), serde_json::Error> {
94 let request_body = RequestBody::new()
95 .description("A sample requestBody")
96 .required(Required::True)
97 .add_content(
98 "application/json",
99 Content::new(crate::Ref::from_schema_name("EmailPayload")),
100 );
101
102 assert_json_eq!(
103 request_body,
104 json!({
105 "description": "A sample requestBody",
106 "content": {
107 "application/json": {
108 "schema": {
109 "$ref": "#/components/schemas/EmailPayload"
110 }
111 }
112 },
113 "required": true
114 })
115 );
116 Ok(())
117 }
118
119 #[test]
120 fn request_body_merge() {
121 let mut request_body = RequestBody::new();
122 let other_request_body = RequestBody::new()
123 .description("Merged requestBody")
124 .required(Required::True)
125 .add_content(
126 "application/json",
127 Content::new(crate::Ref::from_schema_name("EmailPayload")),
128 );
129
130 request_body.merge(other_request_body);
131 assert_json_eq!(
132 request_body,
133 json!({
134 "description": "Merged requestBody",
135 "content": {
136 "application/json": {
137 "schema": {
138 "$ref": "#/components/schemas/EmailPayload"
139 }
140 }
141 },
142 "required": true
143 })
144 );
145 }
146}