1use std::{borrow::Cow, convert::Infallible, rc::Rc, sync::Arc};
2
3use crate::{
4 openapi::{MediaType, Operation, RequestBody, Response},
5 operation::set_body,
6 util::no_content_response,
7 OperationInput,
8};
9use indexmap::IndexMap;
10
11use crate::operation::OperationOutput;
12
13#[cfg(feature = "bytes")]
14mod bytes;
15
16#[cfg(feature = "http")]
17mod http;
18
19#[cfg(feature = "serde_qs")]
20mod serde_qs;
21
22impl<T, E> OperationInput for Result<T, E>
23where
24 T: OperationInput,
25{
26 fn operation_input(ctx: &mut crate::generate::GenContext, operation: &mut Operation) {
27 T::operation_input(ctx, operation);
28 }
29
30 fn inferred_early_responses(
31 ctx: &mut crate::generate::GenContext,
32 operation: &mut Operation,
33 ) -> Vec<(Option<u16>, Response)> {
34 T::inferred_early_responses(ctx, operation)
35 }
36}
37
38impl<T, E> OperationOutput for Result<T, E>
39where
40 T: OperationOutput,
41 E: OperationOutput,
42{
43 type Inner = T;
44
45 fn operation_response(
46 ctx: &mut crate::generate::GenContext,
47 operation: &mut Operation,
48 ) -> Option<Response> {
49 T::operation_response(ctx, operation)
50 }
51
52 fn inferred_responses(
53 ctx: &mut crate::generate::GenContext,
54 operation: &mut Operation,
55 ) -> Vec<(Option<u16>, Response)> {
56 let mut responses = T::inferred_responses(ctx, operation);
57 responses.extend(E::inferred_responses(ctx, operation));
58 responses
59 }
60}
61
62impl<T> OperationInput for Option<T>
63where
64 T: OperationInput,
65{
66 fn operation_input(ctx: &mut crate::generate::GenContext, operation: &mut Operation) {
67 let mut temp_op = Operation::default();
70 T::operation_input(ctx, &mut temp_op);
71 T::operation_input(ctx, operation);
72
73 if temp_op.parameters.is_empty() {
74 return;
75 }
76
77 for param in &mut operation.parameters {
78 if let Some(param) = param.as_item_mut() {
79 let new_param = temp_op.parameters.iter().any(|p| {
80 let p = match p.as_item() {
81 Some(p) => p,
82 None => return false,
83 };
84
85 p.parameter_data_ref().name == param.parameter_data_ref().name
86 });
87
88 if new_param {
89 param.parameter_data_mut().required = false;
90 }
91 }
92 }
93 }
94}
95
96impl<T> OperationOutput for Option<T>
97where
98 T: OperationOutput,
99{
100 type Inner = <T as OperationOutput>::Inner;
101
102 fn operation_response(
103 ctx: &mut crate::generate::GenContext,
104 operation: &mut Operation,
105 ) -> Option<Response> {
106 T::operation_response(ctx, operation)
107 }
108
109 fn inferred_responses(
110 ctx: &mut crate::generate::GenContext,
111 operation: &mut Operation,
112 ) -> Vec<(Option<u16>, Response)> {
113 T::inferred_responses(ctx, operation)
114 }
115}
116
117impl<T> OperationInput for Box<T>
118where
119 T: OperationInput,
120{
121 fn operation_input(ctx: &mut crate::generate::GenContext, operation: &mut Operation) {
122 T::operation_input(ctx, operation);
123 }
124}
125
126impl<T> OperationOutput for Box<T>
127where
128 T: OperationOutput,
129{
130 type Inner = <T as OperationOutput>::Inner;
131
132 fn operation_response(
133 ctx: &mut crate::generate::GenContext,
134 operation: &mut Operation,
135 ) -> Option<Response> {
136 T::operation_response(ctx, operation)
137 }
138
139 fn inferred_responses(
140 ctx: &mut crate::generate::GenContext,
141 operation: &mut Operation,
142 ) -> Vec<(Option<u16>, Response)> {
143 T::inferred_responses(ctx, operation)
144 }
145}
146
147impl<T> OperationInput for Rc<T>
148where
149 T: OperationInput,
150{
151 fn operation_input(ctx: &mut crate::generate::GenContext, operation: &mut Operation) {
152 T::operation_input(ctx, operation);
153 }
154}
155
156impl<T> OperationOutput for Rc<T>
157where
158 T: OperationOutput,
159{
160 type Inner = <T as OperationOutput>::Inner;
161
162 fn operation_response(
163 ctx: &mut crate::generate::GenContext,
164 operation: &mut Operation,
165 ) -> Option<Response> {
166 T::operation_response(ctx, operation)
167 }
168
169 fn inferred_responses(
170 ctx: &mut crate::generate::GenContext,
171 operation: &mut Operation,
172 ) -> Vec<(Option<u16>, Response)> {
173 T::inferred_responses(ctx, operation)
174 }
175}
176
177impl<T> OperationInput for Arc<T>
178where
179 T: OperationInput,
180{
181 fn operation_input(ctx: &mut crate::generate::GenContext, operation: &mut Operation) {
182 T::operation_input(ctx, operation);
183 }
184}
185
186impl<T> OperationOutput for Arc<T>
187where
188 T: OperationOutput,
189{
190 type Inner = <T as OperationOutput>::Inner;
191
192 fn operation_response(
193 ctx: &mut crate::generate::GenContext,
194 operation: &mut Operation,
195 ) -> Option<Response> {
196 T::operation_response(ctx, operation)
197 }
198
199 fn inferred_responses(
200 ctx: &mut crate::generate::GenContext,
201 operation: &mut Operation,
202 ) -> Vec<(Option<u16>, Response)> {
203 T::inferred_responses(ctx, operation)
204 }
205}
206
207impl OperationInput for String {
208 fn operation_input(ctx: &mut crate::generate::GenContext, operation: &mut Operation) {
209 set_body(
210 ctx,
211 operation,
212 RequestBody {
213 description: None,
214 content: IndexMap::from_iter([(
215 "text/plain; charset=utf-8".into(),
216 MediaType::default(),
217 )]),
218 required: true,
219 extensions: IndexMap::default(),
220 },
221 );
222 }
223}
224
225impl OperationOutput for String {
226 type Inner = Self;
227
228 fn operation_response(
229 _ctx: &mut crate::generate::GenContext,
230 _operation: &mut Operation,
231 ) -> Option<crate::openapi::Response> {
232 Some(Response {
233 description: "plain text".into(),
234 content: IndexMap::from_iter([(
235 "text/plain; charset=utf-8".into(),
236 MediaType::default(),
237 )]),
238 ..Default::default()
239 })
240 }
241
242 fn inferred_responses(
243 ctx: &mut crate::generate::GenContext,
244 operation: &mut Operation,
245 ) -> Vec<(Option<u16>, Response)> {
246 if let Some(res) = Self::operation_response(ctx, operation) {
247 Vec::from([(Some(200), res)])
248 } else {
249 Vec::new()
250 }
251 }
252}
253
254impl OperationOutput for &str {
255 type Inner = Self;
256
257 fn operation_response(
258 ctx: &mut crate::generate::GenContext,
259 operation: &mut Operation,
260 ) -> Option<crate::openapi::Response> {
261 String::operation_response(ctx, operation)
262 }
263
264 fn inferred_responses(
265 ctx: &mut crate::generate::GenContext,
266 operation: &mut Operation,
267 ) -> Vec<(Option<u16>, Response)> {
268 String::inferred_responses(ctx, operation)
269 }
270}
271
272impl OperationOutput for Cow<'_, str> {
273 type Inner = Self;
274
275 fn operation_response(
276 ctx: &mut crate::generate::GenContext,
277 operation: &mut Operation,
278 ) -> Option<crate::openapi::Response> {
279 String::operation_response(ctx, operation)
280 }
281
282 fn inferred_responses(
283 ctx: &mut crate::generate::GenContext,
284 operation: &mut Operation,
285 ) -> Vec<(Option<u16>, Response)> {
286 String::inferred_responses(ctx, operation)
287 }
288}
289
290impl OperationOutput for () {
291 type Inner = Self;
292
293 fn operation_response(
294 _ctx: &mut crate::generate::GenContext,
295 _operation: &mut Operation,
296 ) -> Option<crate::openapi::Response> {
297 Some(no_content_response())
298 }
299
300 fn inferred_responses(
301 ctx: &mut crate::generate::GenContext,
302 operation: &mut Operation,
303 ) -> Vec<(Option<u16>, Response)> {
304 if let Some(res) = Self::operation_response(ctx, operation) {
305 Vec::from([(Some(ctx.no_content_status), res)])
306 } else {
307 Vec::new()
308 }
309 }
310}
311
312impl OperationInput for Vec<u8> {
313 fn operation_input(
314 ctx: &mut crate::generate::GenContext,
315 operation: &mut crate::openapi::Operation,
316 ) {
317 set_body(
318 ctx,
319 operation,
320 RequestBody {
321 description: None,
322 content: IndexMap::from_iter([(
323 "application/octet-stream".into(),
324 MediaType::default(),
325 )]),
326 required: true,
327 extensions: IndexMap::default(),
328 },
329 );
330 }
331}
332
333impl OperationOutput for Vec<u8> {
334 type Inner = Self;
335
336 fn operation_response(
337 _ctx: &mut crate::generate::GenContext,
338 _operation: &mut Operation,
339 ) -> Option<crate::openapi::Response> {
340 Some(Response {
341 description: "byte stream".into(),
342 content: IndexMap::from_iter([(
343 "application/octet-stream".into(),
344 MediaType::default(),
345 )]),
346 ..Default::default()
347 })
348 }
349
350 fn inferred_responses(
351 ctx: &mut crate::generate::GenContext,
352 operation: &mut Operation,
353 ) -> Vec<(Option<u16>, Response)> {
354 if let Some(res) = Self::operation_response(ctx, operation) {
355 Vec::from([(Some(200), res)])
356 } else {
357 Vec::new()
358 }
359 }
360}
361
362impl OperationInput for &[u8] {
363 fn operation_input(
364 ctx: &mut crate::generate::GenContext,
365 operation: &mut crate::openapi::Operation,
366 ) {
367 Vec::<u8>::operation_input(ctx, operation);
368 }
369}
370
371impl OperationOutput for &[u8] {
372 type Inner = Self;
373
374 fn operation_response(
375 ctx: &mut crate::generate::GenContext,
376 operation: &mut Operation,
377 ) -> Option<crate::openapi::Response> {
378 Vec::<u8>::operation_response(ctx, operation)
379 }
380
381 fn inferred_responses(
382 ctx: &mut crate::generate::GenContext,
383 operation: &mut Operation,
384 ) -> Vec<(Option<u16>, Response)> {
385 Vec::<u8>::inferred_responses(ctx, operation)
386 }
387}
388
389impl OperationInput for Cow<'_, [u8]> {
390 fn operation_input(
391 ctx: &mut crate::generate::GenContext,
392 operation: &mut crate::openapi::Operation,
393 ) {
394 Vec::<u8>::operation_input(ctx, operation);
395 }
396}
397
398impl OperationOutput for Cow<'_, [u8]> {
399 type Inner = Self;
400
401 fn operation_response(
402 ctx: &mut crate::generate::GenContext,
403 operation: &mut Operation,
404 ) -> Option<crate::openapi::Response> {
405 Vec::<u8>::operation_response(ctx, operation)
406 }
407
408 fn inferred_responses(
409 ctx: &mut crate::generate::GenContext,
410 operation: &mut Operation,
411 ) -> Vec<(Option<u16>, Response)> {
412 Vec::<u8>::inferred_responses(ctx, operation)
413 }
414}
415
416impl<T1, T2> OperationOutput for (T1, T2) {
431 type Inner = Infallible;
432}
433impl<T1, T2, T3> OperationOutput for (T1, T2, T3) {
434 type Inner = Infallible;
435}
436impl<T1, T2, T3, T4> OperationOutput for (T1, T2, T3, T4) {
437 type Inner = Infallible;
438}
439impl<T1, T2, T3, T4, T5> OperationOutput for (T1, T2, T3, T4, T5) {
440 type Inner = Infallible;
441}
442impl<T1, T2, T3, T4, T5, T6> OperationOutput for (T1, T2, T3, T4, T5, T6) {
443 type Inner = Infallible;
444}
445impl<T1, T2, T3, T4, T5, T6, T7> OperationOutput for (T1, T2, T3, T4, T5, T6, T7) {
446 type Inner = Infallible;
447}
448impl<T1, T2, T3, T4, T5, T6, T7, T8> OperationOutput for (T1, T2, T3, T4, T5, T6, T7, T8) {
449 type Inner = Infallible;
450}
451impl<T1, T2, T3, T4, T5, T6, T7, T8, T9> OperationOutput for (T1, T2, T3, T4, T5, T6, T7, T8, T9) {
452 type Inner = Infallible;
453}
454impl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> OperationOutput
455 for (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)
456{
457 type Inner = Infallible;
458}