salvo_oapi/extract/
payload.rs1pub use salvo_core::extract::{FormBody, FormFile, FormFiles, JsonBody};
4use serde::Deserialize;
5
6use crate::endpoint::EndpointArgRegister;
7use crate::{
8 Array, BasicType, Components, Content, KnownFormat, Object, Operation, RequestBody, Schema,
9 SchemaFormat, ToRequestBody, ToSchema,
10};
11
12impl EndpointArgRegister for FormFile {
13 fn register(_components: &mut Components, operation: &mut Operation, arg: &str) {
14 let schema = Schema::from(
15 Object::new().property(
16 arg,
17 Object::with_type(BasicType::String)
18 .format(SchemaFormat::KnownFormat(KnownFormat::Binary)),
19 ),
20 );
21
22 if let Some(request_body) = &mut operation.request_body {
23 request_body
24 .contents
25 .insert("multipart/form-data".into(), Content::new(schema));
26 } else {
27 let request_body = RequestBody::new()
28 .description("Upload a file.")
29 .add_content("multipart/form-data", Content::new(schema));
30 operation.request_body = Some(request_body);
31 }
32 }
33}
34
35impl EndpointArgRegister for FormFiles {
36 fn register(_components: &mut Components, operation: &mut Operation, arg: &str) {
37 let schema = Schema::from(
38 Object::new().property(
39 arg,
40 Array::new().items(Schema::from(
41 Object::with_type(BasicType::String)
42 .format(SchemaFormat::KnownFormat(KnownFormat::Binary)),
43 )),
44 ),
45 );
46 if let Some(request_body) = &mut operation.request_body {
47 request_body
48 .contents
49 .insert("multipart/form-data".into(), Content::new(schema));
50 } else {
51 let request_body = RequestBody::new()
52 .description("Upload files.")
53 .add_content("multipart/form-data", Content::new(schema));
54 operation.request_body = Some(request_body);
55 }
56 }
57}
58
59impl<'de, T> ToRequestBody for FormBody<T>
60where
61 T: Deserialize<'de> + ToSchema,
62{
63 fn to_request_body(components: &mut Components) -> RequestBody {
64 let schema = T::to_schema(components);
65 RequestBody::new()
66 .description("Extract form format data from request.")
67 .add_content(
68 "application/x-www-form-urlencoded",
69 Content::new(schema.clone()),
70 )
71 .add_content("multipart/*", Content::new(schema))
74 }
75}
76
77impl<'de, T> EndpointArgRegister for FormBody<T>
78where
79 T: Deserialize<'de> + ToSchema,
80{
81 fn register(components: &mut Components, operation: &mut Operation, _arg: &str) {
82 operation.request_body = Some(Self::to_request_body(components));
83 }
84}
85
86impl<'de, T> ToRequestBody for JsonBody<T>
87where
88 T: Deserialize<'de> + ToSchema,
89{
90 fn to_request_body(components: &mut Components) -> RequestBody {
91 RequestBody::new()
92 .description("Extract json format data from request.")
93 .add_content("application/json", Content::new(T::to_schema(components)))
94 }
95}
96
97impl<'de, T> EndpointArgRegister for JsonBody<T>
98where
99 T: Deserialize<'de> + ToSchema,
100{
101 fn register(components: &mut Components, operation: &mut Operation, _arg: &str) {
102 let request_body = Self::to_request_body(components);
103 let _ = <T as ToSchema>::to_schema(components);
104 operation.request_body = Some(request_body);
105 }
106}
107
108#[cfg(test)]
109mod tests {
110 use assert_json_diff::assert_json_eq;
111 use serde_json::json;
112
113 use super::*;
114
115 #[test]
116 fn test_form_body_to_request_body() {
117 let mut components = Components::default();
118 let request_body = FormBody::<String>::to_request_body(&mut components);
119 assert_json_eq!(
120 request_body,
121 json!({
122 "description": "Extract form format data from request.",
123 "content": {
124 "application/x-www-form-urlencoded": {
125 "schema": { "type": "string" }
126 },
127 "multipart/*": {
128 "schema": { "type": "string" }
129 }
130 }
131 })
132 );
133 }
134
135 #[test]
136 fn test_form_body_register() {
137 let mut components = Components::new();
138 let mut operation = Operation::new();
139 FormBody::<String>::register(&mut components, &mut operation, "arg");
140
141 assert_json_eq!(
142 operation,
143 json!({
144 "requestBody": {
145 "content": {
146 "application/x-www-form-urlencoded": {
147 "schema": { "type": "string" }
148 },
149 "multipart/*": {
150 "schema": { "type": "string" }
151 }
152 },
153 "description": "Extract form format data from request."
154 },
155 "responses": {}
156 })
157 );
158 }
159
160 #[test]
161 fn test_json_body_to_request_body() {
162 let mut components = Components::default();
163 let request_body = JsonBody::<String>::to_request_body(&mut components);
164 assert_json_eq!(
165 request_body,
166 json!({
167 "description": "Extract json format data from request.",
168 "content": {
169 "application/json": {
170 "schema": { "type": "string" }
171 }
172 }
173 })
174 );
175 }
176
177 #[test]
178 fn test_json_body_register() {
179 let mut components = Components::new();
180 let mut operation = Operation::new();
181 JsonBody::<String>::register(&mut components, &mut operation, "arg");
182
183 assert_json_eq!(
184 operation,
185 json!({
186 "requestBody": {
187 "content": {
188 "application/json": {
189 "schema": { "type": "string" }
190 }
191 },
192 "description": "Extract json format data from request."
193 },
194 "responses": {}
195 })
196 );
197 }
198}