1use std::borrow::Cow;
2
3use puzz_http::body::{Body, BodyExt, BoxBody, Bytes, MapErr, StreamBody};
4use puzz_http::{header, HeaderMap, HeaderValue, StatusCode};
5
6use crate::BoxError;
7
8pub type Response<B = BoxBody> = puzz_http::Response<B>;
9
10pub trait IntoResponse {
11 fn into_response(self) -> Response;
12}
13
14impl IntoResponse for () {
15 fn into_response(self) -> Response {
16 Response::new(self.boxed())
17 }
18}
19
20impl IntoResponse for &'static str {
21 fn into_response(self) -> Response {
22 Cow::Borrowed(self).into_response()
23 }
24}
25
26impl IntoResponse for String {
27 fn into_response(self) -> Response {
28 Cow::<'static, str>::Owned(self).into_response()
29 }
30}
31
32impl IntoResponse for Cow<'static, str> {
33 fn into_response(self) -> Response {
34 let mut res = Response::new(self.boxed());
35 res.headers_mut().insert(
36 header::CONTENT_TYPE,
37 HeaderValue::from_static(mime::TEXT_PLAIN_UTF_8.as_ref()),
38 );
39 res
40 }
41}
42
43impl IntoResponse for &'static [u8] {
44 fn into_response(self) -> Response {
45 Cow::Borrowed(self).into_response()
46 }
47}
48
49impl IntoResponse for Vec<u8> {
50 fn into_response(self) -> Response {
51 Cow::<'static, [u8]>::Owned(self).into_response()
52 }
53}
54
55impl IntoResponse for Cow<'static, [u8]> {
56 fn into_response(self) -> Response {
57 let mut res = Response::new(self.boxed());
58 res.headers_mut().insert(
59 header::CONTENT_TYPE,
60 HeaderValue::from_static(mime::APPLICATION_OCTET_STREAM.as_ref()),
61 );
62 res
63 }
64}
65
66impl IntoResponse for Bytes {
67 fn into_response(self) -> Response {
68 let mut res = Response::new(self.boxed());
69 res.headers_mut().insert(
70 header::CONTENT_TYPE,
71 HeaderValue::from_static(mime::APPLICATION_OCTET_STREAM.as_ref()),
72 );
73 res
74 }
75}
76
77impl IntoResponse for BoxBody {
78 fn into_response(self) -> Response {
79 Response::new(self)
80 }
81}
82
83impl<S> IntoResponse for StreamBody<S>
84where
85 Self: Body + 'static,
86 <Self as Body>::Error: Into<BoxError>,
87{
88 fn into_response(self) -> Response {
89 Response::new(self.boxed())
90 }
91}
92
93impl<B, F, E> IntoResponse for MapErr<B, F>
94where
95 B: Body + 'static,
96 F: FnMut(B::Error) -> E + 'static,
97 E: Into<BoxError>,
98{
99 fn into_response(self) -> Response {
100 Response::new(self.boxed())
101 }
102}
103
104impl<B> IntoResponse for Response<B>
105where
106 B: Body + 'static,
107 B::Error: Into<BoxError>,
108{
109 fn into_response(self) -> Response {
110 self.map(BodyExt::boxed)
111 }
112}
113
114impl IntoResponse for puzz_http::response::Head {
115 fn into_response(self) -> Response {
116 Response::from_head(self, ().boxed())
117 }
118}
119
120impl IntoResponse for StatusCode {
121 fn into_response(self) -> Response {
122 let mut res = Response::new(().boxed());
123 *res.status_mut() = self;
124 res
125 }
126}
127
128impl IntoResponse for HeaderMap {
129 fn into_response(self) -> Response {
130 let mut res = Response::new(().boxed());
131 *res.headers_mut() = self;
132 res
133 }
134}
135
136impl<T> IntoResponse for (StatusCode, T)
137where
138 T: IntoResponse,
139{
140 fn into_response(self) -> Response {
141 let mut res = self.1.into_response();
142 *res.status_mut() = self.0;
143 res
144 }
145}
146
147impl<T> IntoResponse for (HeaderMap, T)
148where
149 T: IntoResponse,
150{
151 fn into_response(self) -> Response {
152 let mut res = self.1.into_response();
153 res.headers_mut().extend(self.0);
154 res
155 }
156}
157
158impl<T> IntoResponse for (StatusCode, HeaderMap, T)
159where
160 T: IntoResponse,
161{
162 fn into_response(self) -> Response {
163 let mut res = self.2.into_response();
164 *res.status_mut() = self.0;
165 res.headers_mut().extend(self.1);
166 res
167 }
168}