1use std::{borrow::Cow, convert::Infallible};
2
3use bytes::Bytes;
4use http::{header, HeaderMap, StatusCode};
5use http_body_util::{Empty, Full};
6
7use super::*;
8
9impl IntoResponse for StatusCode {
16 #[inline]
17 fn into_response(self) -> Response {
18 let mut response = Response::default();
19 *response.status_mut() = self;
20
21 response
22 }
23}
24
25impl IntoResponse for Infallible {
29 #[inline]
30 fn into_response(self) -> Response {
31 Response::default()
32 }
33}
34
35impl IntoResponse for () {
39 #[inline]
40 fn into_response(self) -> Response {
41 Response::default()
42 }
43}
44
45impl<T: IntoResponse> IntoResponse for Option<T> {
49 #[inline]
50 fn into_response(self) -> Response {
51 match self {
52 Some(value) => value.into_response(),
53 None => {
54 let mut response = Response::default();
55 *response.status_mut() = StatusCode::NO_CONTENT;
56
57 response
58 }
59 }
60 }
61}
62
63impl IntoResponseHeadParts for HeaderMap {
67 #[inline]
68 fn into_response_head(
69 self,
70 mut head: ResponseHeadParts,
71 ) -> Result<ResponseHeadParts, BoxedErrorResponse> {
72 head.headers.extend(self);
73
74 Ok(head)
75 }
76}
77
78impl IntoResponse for HeaderMap {
79 fn into_response(self) -> Response {
80 let mut response = ().into_response();
81 *response.headers_mut() = self;
82
83 response
84 }
85}
86
87impl IntoResponse for Bytes {
91 #[inline]
92 fn into_response(self) -> Response {
93 let mut response = Full::from(self).into_response();
94 response.headers_mut().insert(
95 header::CONTENT_TYPE,
96 HeaderValue::from_static(mime::APPLICATION_OCTET_STREAM.as_ref()),
97 );
98
99 response
100 }
101}
102
103impl IntoResponse for Empty<Bytes> {
107 #[inline]
108 fn into_response(self) -> Response {
109 Response::new(Body::new(self))
110 }
111}
112
113impl IntoResponse for Full<Bytes> {
117 #[inline]
118 fn into_response(self) -> Response {
119 Response::new(Body::new(self))
120 }
121}
122
123impl IntoResponse for &'static str {
127 #[inline]
128 fn into_response(self) -> Response {
129 Cow::<'_, str>::Borrowed(self).into_response()
130 }
131}
132
133impl IntoResponse for String {
137 #[inline]
138 fn into_response(self) -> Response {
139 Cow::<'_, str>::Owned(self).into_response()
140 }
141}
142
143impl IntoResponse for Cow<'static, str> {
147 #[inline]
148 fn into_response(self) -> Response {
149 let mut response = Full::from(self).into_response();
150 response.headers_mut().insert(
151 header::CONTENT_TYPE,
152 HeaderValue::from_static(mime::TEXT_PLAIN_UTF_8.as_ref()),
153 );
154
155 response
156 }
157}
158
159impl IntoResponse for &'static [u8] {
163 #[inline]
164 fn into_response(self) -> Response {
165 Cow::<'_, [u8]>::Borrowed(self).into_response()
166 }
167}
168
169impl IntoResponse for Vec<u8> {
173 #[inline]
174 fn into_response(self) -> Response {
175 Cow::<'_, [u8]>::Owned(self).into_response()
176 }
177}
178
179impl IntoResponse for Cow<'static, [u8]> {
183 #[inline]
184 fn into_response(self) -> Response {
185 let mut response = Full::from(self).into_response();
186 response.headers_mut().insert(
187 header::CONTENT_TYPE,
188 HeaderValue::from_static(mime::APPLICATION_OCTET_STREAM.as_ref()),
189 );
190
191 response
192 }
193}
194
195impl IntoResponse for Body {
199 #[inline]
200 fn into_response(self) -> Response {
201 Response::new(self)
202 }
203}
204
205impl<N, V, const C: usize> IntoResponseHeadParts for [(N, V); C]
209where
210 N: TryInto<HeaderName>,
211 N::Error: crate::StdError + Send + Sync + 'static,
212 V: TryInto<HeaderValue>,
213 V::Error: crate::StdError + Send + Sync + 'static,
214{
215 fn into_response_head(
216 self,
217 mut head: ResponseHeadParts,
218 ) -> Result<ResponseHeadParts, BoxedErrorResponse> {
219 for (key, value) in self {
220 let header_name = TryInto::<HeaderName>::try_into(key)
221 .map_err(HeaderError::<N::Error, V::Error>::from_name_error)?;
222
223 let header_value = TryInto::<HeaderValue>::try_into(value)
224 .map_err(HeaderError::<N::Error, V::Error>::from_value_error)?;
225
226 head.headers.insert(header_name, header_value);
227 }
228
229 Ok(head)
230 }
231}
232
233impl<N, V, const C: usize> IntoResponseResult for [(N, V); C]
234where
235 N: TryInto<HeaderName>,
236 N::Error: crate::StdError + Send + Sync + 'static,
237 V: TryInto<HeaderValue>,
238 V::Error: crate::StdError + Send + Sync + 'static,
239{
240 fn into_response_result(self) -> Result<Response, BoxedErrorResponse> {
241 let (head, body) = Response::default().into_parts();
242
243 self
244 .into_response_head(head)
245 .map(|head| Response::from_parts(head, body))
246 }
247}
248
249#[derive(Debug, crate::ImplError)]
250enum HeaderError<NE, VE> {
251 #[error(transparent)]
252 InvalidName(NE),
253 #[error(transparent)]
254 InvalidValue(VE),
255}
256
257impl<NE, VE> HeaderError<NE, VE> {
258 pub(crate) fn from_name_error(name_error: NE) -> Self {
259 Self::InvalidName(name_error)
260 }
261
262 pub(crate) fn from_value_error(value_error: VE) -> Self {
263 Self::InvalidValue(value_error)
264 }
265}
266
267impl<NE, VE> IntoResponse for HeaderError<NE, VE> {
268 fn into_response(self) -> Response {
269 StatusCode::INTERNAL_SERVER_ERROR.into_response()
270 }
271}
272
273macro_rules! impl_into_response_for_tuples {
277 ($t1:ident, $(($($t:ident),*),)? $tl:ident) => {
278 #[allow(non_snake_case)]
279 impl<$t1, $($($t,)*)? $tl> IntoResponseHeadParts for ($t1, $($($t,)*)? $tl)
280 where
281 $t1: IntoResponseHeadParts,
282 $($($t: IntoResponseHeadParts,)*)?
283 $tl: IntoResponseHeadParts,
284 {
285 fn into_response_head(
286 self,
287 mut head: ResponseHeadParts,
288 ) -> Result<ResponseHeadParts, BoxedErrorResponse> {
289 let ($t1, $($($t,)*)? $tl) = self;
290
291 head = $t1.into_response_head(head)?;
292
293 $($(head = $t.into_response_head(head)?;)*)?
294
295 head = $tl.into_response_head(head)?;
296
297 Ok(head)
298 }
299 }
300
301 #[allow(non_snake_case)]
302 impl<$($($t,)*)? $tl> IntoResponseResult for (StatusCode, $($($t,)*)? $tl)
303 where
304 $($($t: IntoResponseHeadParts,)*)?
305 $tl: IntoResponseResult,
306 {
307 fn into_response_result(self) -> Result<Response, BoxedErrorResponse> {
308 let (status_code, $($($t,)*)? $tl) = self;
309
310 let (head, body) = $tl.into_response_result()?.into_parts();
311
312 $($(
313 let head = $t.into_response_head(head)?;
314 )*)?
315
316 let mut response = Response::from_parts(head, body);
317 *response.status_mut() = status_code;
318
319 Ok(response)
320 }
321 }
322
323 #[allow(non_snake_case)]
324 impl<$t1, $($($t,)*)? $tl> IntoResponseResult for ($t1, $($($t,)*)? $tl)
325 where
326 $t1: IntoResponseHeadParts,
327 $($($t: IntoResponseHeadParts,)*)?
328 $tl: IntoResponseResult,
329 {
330 fn into_response_result(self) -> Result<Response, BoxedErrorResponse> {
331 let ($t1, $($($t,)*)? $tl) = self;
332
333 let (head, body) = $tl.into_response_result()?.into_parts();
334
335 let head = $t1.into_response_head(head)?;
336
337 $($(
338 let head = $t.into_response_head(head)?;
339 )*)?
340
341 Ok(Response::from_parts(head, body))
342 }
343 }
344 };
345}
346
347call_for_tuples!(impl_into_response_for_tuples!);
348
349