predawn_core/
into_response.rs1use 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}