1use axum::response::Response;
2
3use crate::{Codec, CodecEncode, ContentType};
4
5#[cfg(not(feature = "aide"))]
6pub trait IntoCodecResponse {
7 fn into_codec_response(self, content_type: ContentType) -> Response;
8}
9
10#[cfg(feature = "aide")]
11pub trait IntoCodecResponse: aide::OperationOutput {
12 fn into_codec_response(self, content_type: ContentType) -> Response;
13}
14
15#[cfg(not(feature = "aide"))]
16impl<D> IntoCodecResponse for Codec<D>
17where
18 D: CodecEncode,
19{
20 fn into_codec_response(self, content_type: ContentType) -> Response {
21 self.to_response(content_type)
22 }
23}
24
25#[cfg(feature = "aide")]
26impl<D> IntoCodecResponse for Codec<D>
27where
28 D: CodecEncode,
29 Self: aide::OperationOutput,
30{
31 fn into_codec_response(self, content_type: ContentType) -> Response {
32 self.to_response(content_type)
33 }
34}
35
36mod axum_impls {
37 use std::borrow::Cow;
38
39 use axum::{
40 body::Bytes,
41 http::StatusCode,
42 response::{IntoResponse, Response},
43 BoxError,
44 };
45
46 use super::{ContentType, IntoCodecResponse};
47
48 impl<T, E> IntoCodecResponse for Result<T, E>
49 where
50 T: IntoCodecResponse,
51 E: IntoCodecResponse,
52 {
53 fn into_codec_response(self, content_type: ContentType) -> Response {
54 match self {
55 Ok(value) => value.into_codec_response(content_type),
56 Err(err) => err.into_codec_response(content_type),
57 }
58 }
59 }
60
61 impl<B> IntoCodecResponse for Response<B>
62 where
63 B: axum::body::HttpBody<Data = Bytes> + Send + 'static,
64 B::Error: Into<BoxError>,
65 {
66 fn into_codec_response(self, _ct: ContentType) -> Response {
67 self.into_response()
68 }
69 }
70
71 macro_rules! forward_to_into_response {
72 ( $($ty:ty),* ) => {
73 $(
74 impl IntoCodecResponse for $ty {
75 fn into_codec_response(self, _ct: ContentType) -> Response {
76 self.into_response()
77 }
78 }
79 )*
80 }
81 }
82
83 forward_to_into_response! {
84 StatusCode, (), &'static str, String, Bytes, Cow<'static, str>, &'static [u8], Vec<u8>, Cow<'static, [u8]>
85 }
86
87 impl<R> IntoCodecResponse for (StatusCode, R)
88 where
89 R: IntoCodecResponse,
90 {
91 fn into_codec_response(self, content_type: ContentType) -> Response {
92 let mut res = self.1.into_codec_response(content_type);
93 *res.status_mut() = self.0;
94 res
95 }
96 }
97}