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