axum_core/response/
into_response.rs

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
17/// Trait for generating responses.
18///
19/// Types that implement `IntoResponse` can be returned from handlers.
20///
21/// # Implementing `IntoResponse`
22///
23/// You generally shouldn't have to implement `IntoResponse` manually, as axum
24/// provides implementations for many common types.
25///
26/// However it might be necessary if you have a custom error type that you want
27/// to return from handlers:
28///
29/// ```rust
30/// use axum::{
31///     Router,
32///     body::{self, Bytes},
33///     routing::get,
34///     http::StatusCode,
35///     response::{IntoResponse, Response},
36/// };
37///
38/// enum MyError {
39///     SomethingWentWrong,
40///     SomethingElseWentWrong,
41/// }
42///
43/// impl IntoResponse for MyError {
44///     fn into_response(self) -> Response {
45///         let body = match self {
46///             MyError::SomethingWentWrong => "something went wrong",
47///             MyError::SomethingElseWentWrong => "something else went wrong",
48///         };
49///
50///         // it's often easiest to implement `IntoResponse` by calling other implementations
51///         (StatusCode::INTERNAL_SERVER_ERROR, body).into_response()
52///     }
53/// }
54///
55/// // `Result<impl IntoResponse, MyError>` can now be returned from handlers
56/// let app = Router::new().route("/", get(handler));
57///
58/// async fn handler() -> Result<(), MyError> {
59///     Err(MyError::SomethingWentWrong)
60/// }
61/// # let _: Router = app;
62/// ```
63///
64/// Or if you have a custom body type you'll also need to implement
65/// `IntoResponse` for it:
66///
67/// ```rust
68/// use axum::{
69///     body,
70///     routing::get,
71///     response::{IntoResponse, Response},
72///     body::Body,
73///     Router,
74/// };
75/// use http::HeaderMap;
76/// use bytes::Bytes;
77/// use http_body::Frame;
78/// use std::{
79///     convert::Infallible,
80///     task::{Poll, Context},
81///     pin::Pin,
82/// };
83///
84/// struct MyBody;
85///
86/// // First implement `Body` for `MyBody`. This could for example use
87/// // some custom streaming protocol.
88/// impl http_body::Body for MyBody {
89///     type Data = Bytes;
90///     type Error = Infallible;
91///
92///     fn poll_frame(
93///         self: Pin<&mut Self>,
94///         cx: &mut Context<'_>,
95///     ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
96///         # unimplemented!()
97///         // ...
98///     }
99/// }
100///
101/// // Now we can implement `IntoResponse` directly for `MyBody`
102/// impl IntoResponse for MyBody {
103///     fn into_response(self) -> Response {
104///         Response::new(Body::new(self))
105///     }
106/// }
107///
108/// // `MyBody` can now be returned from handlers.
109/// let app = Router::new().route("/", get(|| async { MyBody }));
110/// # let _: Router = app;
111/// ```
112pub trait IntoResponse {
113    /// Create a response.
114    #[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);