predawn_core/
into_response.rs

1use std::{borrow::Cow, convert::Infallible};
2
3use bytes::{Bytes, BytesMut};
4use http::{header::CONTENT_TYPE, HeaderValue, StatusCode};
5
6use crate::{
7    body::ResponseBody, either::Either, error::BoxError, media_type::MediaType, response::Response,
8    response_error::ResponseError,
9};
10
11pub trait IntoResponse {
12    type Error: ResponseError;
13
14    fn into_response(self) -> Result<Response, Self::Error>;
15}
16
17impl<B> IntoResponse for Response<B>
18where
19    B: http_body::Body<Data = Bytes> + Send + 'static,
20    B::Error: Into<BoxError>,
21{
22    type Error = Infallible;
23
24    fn into_response(self) -> Result<Response, Self::Error> {
25        Ok(self.map(ResponseBody::new))
26    }
27}
28
29impl IntoResponse for http::response::Parts {
30    type Error = Infallible;
31
32    fn into_response(self) -> Result<Response, Self::Error> {
33        Ok(Response::from_parts(self, ResponseBody::empty()))
34    }
35}
36
37impl IntoResponse for ResponseBody {
38    type Error = Infallible;
39
40    fn into_response(self) -> Result<Response, Self::Error> {
41        Ok(Response::new(self))
42    }
43}
44
45impl IntoResponse for () {
46    type Error = Infallible;
47
48    fn into_response(self) -> Result<Response, Self::Error> {
49        ResponseBody::empty().into_response()
50    }
51}
52
53impl IntoResponse for StatusCode {
54    type Error = Infallible;
55
56    fn into_response(self) -> Result<Response, Self::Error> {
57        let mut response = ().into_response()?;
58        *response.status_mut() = self;
59        Ok(response)
60    }
61}
62
63impl IntoResponse for Infallible {
64    type Error = Infallible;
65
66    fn into_response(self) -> Result<Response, Self::Error> {
67        match self {}
68    }
69}
70
71macro_rules! some_impl {
72    ($ty:ty; $($desc:tt)+) => {
73        impl $($desc)+
74        {
75            type Error = Infallible;
76
77            fn into_response(self) -> Result<Response, Self::Error> {
78                let mut response = Response::new(self.into());
79
80                response
81                    .headers_mut()
82                    .insert(CONTENT_TYPE, HeaderValue::from_static(<$ty as MediaType>::MEDIA_TYPE));
83
84                Ok(response)
85            }
86        }
87    };
88}
89
90some_impl!(String; IntoResponse for &'static str);
91some_impl!(String; IntoResponse for Cow<'static, str>);
92some_impl!(String; IntoResponse for String);
93some_impl!(String; IntoResponse for Box<str>);
94
95some_impl!(Vec<u8>; IntoResponse for &'static [u8]);
96some_impl!(Vec<u8>; IntoResponse for Cow<'static, [u8]>);
97some_impl!(Vec<u8>; IntoResponse for Vec<u8>);
98some_impl!(Vec<u8>; IntoResponse for Bytes);
99some_impl!(Vec<u8>; IntoResponse for BytesMut);
100some_impl!(Vec<u8>; IntoResponse for Box<[u8]>);
101
102some_impl!([u8; N]; <const N: usize> IntoResponse for [u8; N]);
103some_impl!([u8; N]; <const N: usize> IntoResponse for &'static [u8; N]);
104
105impl<T, E> IntoResponse for Result<T, E>
106where
107    T: IntoResponse,
108    E: ResponseError,
109{
110    type Error = Either<T::Error, E>;
111
112    fn into_response(self) -> Result<Response, Self::Error> {
113        match self {
114            Ok(t) => t.into_response().map_err(Either::Left),
115            Err(e) => Err(Either::Right(e)),
116        }
117    }
118}