1use super::{IntoResponseParts, Response, ResponseParts};
2use crate::{body::Body, BoxError};
3use bytes::{buf::Chain, Buf, Bytes, BytesMut};
4use http::{
5 header::{self, HeaderMap, HeaderName, HeaderValue},
6 Extensions, StatusCode,
7};
8use http_body::{Frame, SizeHint};
9use std::{
10 borrow::Cow,
11 convert::Infallible,
12 fmt,
13 pin::Pin,
14 task::{Context, Poll},
15};
16
17pub trait IntoResponse {
113 #[must_use]
115 fn into_response(self) -> Response;
116}
117
118impl IntoResponse for StatusCode {
119 fn into_response(self) -> Response {
120 let mut res = ().into_response();
121 *res.status_mut() = self;
122 res
123 }
124}
125
126impl IntoResponse for () {
127 fn into_response(self) -> Response {
128 Body::empty().into_response()
129 }
130}
131
132impl IntoResponse for Infallible {
133 fn into_response(self) -> Response {
134 match self {}
135 }
136}
137
138impl<T, E> IntoResponse for Result<T, E>
139where
140 T: IntoResponse,
141 E: IntoResponse,
142{
143 fn into_response(self) -> Response {
144 match self {
145 Ok(value) => value.into_response(),
146 Err(err) => err.into_response(),
147 }
148 }
149}
150
151impl<B> IntoResponse for Response<B>
152where
153 B: http_body::Body<Data = Bytes> + Send + 'static,
154 B::Error: Into<BoxError>,
155{
156 fn into_response(self) -> Response {
157 self.map(Body::new)
158 }
159}
160
161impl IntoResponse for http::response::Parts {
162 fn into_response(self) -> Response {
163 Response::from_parts(self, Body::empty())
164 }
165}
166
167impl IntoResponse for Body {
168 fn into_response(self) -> Response {
169 Response::new(self)
170 }
171}
172
173impl IntoResponse for &'static str {
174 fn into_response(self) -> Response {
175 Cow::Borrowed(self).into_response()
176 }
177}
178
179impl IntoResponse for String {
180 fn into_response(self) -> Response {
181 Cow::<'static, str>::Owned(self).into_response()
182 }
183}
184
185impl IntoResponse for Box<str> {
186 fn into_response(self) -> Response {
187 String::from(self).into_response()
188 }
189}
190
191impl IntoResponse for Cow<'static, str> {
192 fn into_response(self) -> Response {
193 let mut res = Body::from(self).into_response();
194 res.headers_mut().insert(
195 header::CONTENT_TYPE,
196 HeaderValue::from_static(mime::TEXT_PLAIN_UTF_8.as_ref()),
197 );
198 res
199 }
200}
201
202impl IntoResponse for Bytes {
203 fn into_response(self) -> Response {
204 let mut res = Body::from(self).into_response();
205 res.headers_mut().insert(
206 header::CONTENT_TYPE,
207 HeaderValue::from_static(mime::APPLICATION_OCTET_STREAM.as_ref()),
208 );
209 res
210 }
211}
212
213impl IntoResponse for BytesMut {
214 fn into_response(self) -> Response {
215 self.freeze().into_response()
216 }
217}
218
219impl<T, U> IntoResponse for Chain<T, U>
220where
221 T: Buf + Unpin + Send + 'static,
222 U: Buf + Unpin + Send + 'static,
223{
224 fn into_response(self) -> Response {
225 let (first, second) = self.into_inner();
226 let mut res = Response::new(Body::new(BytesChainBody {
227 first: Some(first),
228 second: Some(second),
229 }));
230 res.headers_mut().insert(
231 header::CONTENT_TYPE,
232 HeaderValue::from_static(mime::APPLICATION_OCTET_STREAM.as_ref()),
233 );
234 res
235 }
236}
237
238struct BytesChainBody<T, U> {
239 first: Option<T>,
240 second: Option<U>,
241}
242
243impl<T, U> http_body::Body for BytesChainBody<T, U>
244where
245 T: Buf + Unpin,
246 U: Buf + Unpin,
247{
248 type Data = Bytes;
249 type Error = Infallible;
250
251 fn poll_frame(
252 mut self: Pin<&mut Self>,
253 _cx: &mut Context<'_>,
254 ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
255 if let Some(mut buf) = self.first.take() {
256 let bytes = buf.copy_to_bytes(buf.remaining());
257 return Poll::Ready(Some(Ok(Frame::data(bytes))));
258 }
259
260 if let Some(mut buf) = self.second.take() {
261 let bytes = buf.copy_to_bytes(buf.remaining());
262 return Poll::Ready(Some(Ok(Frame::data(bytes))));
263 }
264
265 Poll::Ready(None)
266 }
267
268 fn is_end_stream(&self) -> bool {
269 self.first.is_none() && self.second.is_none()
270 }
271
272 fn size_hint(&self) -> SizeHint {
273 match (self.first.as_ref(), self.second.as_ref()) {
274 (Some(first), Some(second)) => {
275 let total_size = first.remaining() + second.remaining();
276 SizeHint::with_exact(total_size as u64)
277 }
278 (Some(buf), None) => SizeHint::with_exact(buf.remaining() as u64),
279 (None, Some(buf)) => SizeHint::with_exact(buf.remaining() as u64),
280 (None, None) => SizeHint::with_exact(0),
281 }
282 }
283}
284
285impl IntoResponse for &'static [u8] {
286 fn into_response(self) -> Response {
287 Cow::Borrowed(self).into_response()
288 }
289}
290
291impl<const N: usize> IntoResponse for &'static [u8; N] {
292 fn into_response(self) -> Response {
293 self.as_slice().into_response()
294 }
295}
296
297impl<const N: usize> IntoResponse for [u8; N] {
298 fn into_response(self) -> Response {
299 self.to_vec().into_response()
300 }
301}
302
303impl IntoResponse for Vec<u8> {
304 fn into_response(self) -> Response {
305 Cow::<'static, [u8]>::Owned(self).into_response()
306 }
307}
308
309impl IntoResponse for Box<[u8]> {
310 fn into_response(self) -> Response {
311 Vec::from(self).into_response()
312 }
313}
314
315impl IntoResponse for Cow<'static, [u8]> {
316 fn into_response(self) -> Response {
317 let mut res = Body::from(self).into_response();
318 res.headers_mut().insert(
319 header::CONTENT_TYPE,
320 HeaderValue::from_static(mime::APPLICATION_OCTET_STREAM.as_ref()),
321 );
322 res
323 }
324}
325
326impl<R> IntoResponse for (StatusCode, R)
327where
328 R: IntoResponse,
329{
330 fn into_response(self) -> Response {
331 let mut res = self.1.into_response();
332 *res.status_mut() = self.0;
333 res
334 }
335}
336
337impl IntoResponse for HeaderMap {
338 fn into_response(self) -> Response {
339 let mut res = ().into_response();
340 *res.headers_mut() = self;
341 res
342 }
343}
344
345impl IntoResponse for Extensions {
346 fn into_response(self) -> Response {
347 let mut res = ().into_response();
348 *res.extensions_mut() = self;
349 res
350 }
351}
352
353impl<K, V, const N: usize> IntoResponse for [(K, V); N]
354where
355 K: TryInto<HeaderName>,
356 K::Error: fmt::Display,
357 V: TryInto<HeaderValue>,
358 V::Error: fmt::Display,
359{
360 fn into_response(self) -> Response {
361 (self, ()).into_response()
362 }
363}
364
365impl<R> IntoResponse for (http::response::Parts, R)
366where
367 R: IntoResponse,
368{
369 fn into_response(self) -> Response {
370 let (parts, res) = self;
371 (parts.status, parts.headers, parts.extensions, res).into_response()
372 }
373}
374
375impl<R> IntoResponse for (http::response::Response<()>, R)
376where
377 R: IntoResponse,
378{
379 fn into_response(self) -> Response {
380 let (template, res) = self;
381 let (parts, ()) = template.into_parts();
382 (parts, res).into_response()
383 }
384}
385
386impl<R> IntoResponse for (R,)
387where
388 R: IntoResponse,
389{
390 fn into_response(self) -> Response {
391 let (res,) = self;
392 res.into_response()
393 }
394}
395
396macro_rules! impl_into_response {
397 ( $($ty:ident),* $(,)? ) => {
398 #[allow(non_snake_case)]
399 impl<R, $($ty,)*> IntoResponse for ($($ty),*, R)
400 where
401 $( $ty: IntoResponseParts, )*
402 R: IntoResponse,
403 {
404 fn into_response(self) -> Response {
405 let ($($ty),*, res) = self;
406
407 let res = res.into_response();
408 let parts = ResponseParts { res };
409
410 $(
411 let parts = match $ty.into_response_parts(parts) {
412 Ok(parts) => parts,
413 Err(err) => {
414 return err.into_response();
415 }
416 };
417 )*
418
419 parts.res
420 }
421 }
422
423 #[allow(non_snake_case)]
424 impl<R, $($ty,)*> IntoResponse for (StatusCode, $($ty),*, R)
425 where
426 $( $ty: IntoResponseParts, )*
427 R: IntoResponse,
428 {
429 fn into_response(self) -> Response {
430 let (status, $($ty),*, res) = self;
431
432 let res = res.into_response();
433 let parts = ResponseParts { res };
434
435 $(
436 let parts = match $ty.into_response_parts(parts) {
437 Ok(parts) => parts,
438 Err(err) => {
439 return err.into_response();
440 }
441 };
442 )*
443
444 (status, parts.res).into_response()
445 }
446 }
447
448 #[allow(non_snake_case)]
449 impl<R, $($ty,)*> IntoResponse for (http::response::Parts, $($ty),*, R)
450 where
451 $( $ty: IntoResponseParts, )*
452 R: IntoResponse,
453 {
454 fn into_response(self) -> Response {
455 let (outer_parts, $($ty),*, res) = self;
456
457 let res = res.into_response();
458 let parts = ResponseParts { res };
459 $(
460 let parts = match $ty.into_response_parts(parts) {
461 Ok(parts) => parts,
462 Err(err) => {
463 return err.into_response();
464 }
465 };
466 )*
467
468 (outer_parts, parts.res).into_response()
469 }
470 }
471
472 #[allow(non_snake_case)]
473 impl<R, $($ty,)*> IntoResponse for (http::response::Response<()>, $($ty),*, R)
474 where
475 $( $ty: IntoResponseParts, )*
476 R: IntoResponse,
477 {
478 fn into_response(self) -> Response {
479 let (template, $($ty),*, res) = self;
480 let (parts, ()) = template.into_parts();
481 (parts, $($ty),*, res).into_response()
482 }
483 }
484 }
485}
486
487all_the_tuples_no_last_special_case!(impl_into_response);