use crate::{http::header::HeaderMap, response::into_parts::IntoParts, StatusCode};
use super::{Parts, Response};
pub trait IntoResponse: IntoResponseBoxed {
fn into_response(self) -> Response;
}
impl IntoResponse for () {
fn into_response(self) -> Response {
Response::default()
}
}
impl IntoResponse for StatusCode {
fn into_response(self) -> Response {
let mut res = Response::default();
*res.status_mut() = self;
res
}
}
impl IntoResponse for &str {
fn into_response(self) -> Response {
let mut res = Response::new(self.as_bytes().to_vec());
res.headers_mut()
.insert("Content-Type", "text/plain; charset=utf-8");
res
}
}
impl IntoResponse for String {
fn into_response(self) -> Response {
let mut res = Response::new(self.into_bytes());
res.headers_mut()
.insert("Content-Type", "text/plain; charset=utf-8");
res
}
}
impl IntoResponse for HeaderMap {
fn into_response(self) -> Response {
let mut res = Response::default();
*res.headers_mut() = self;
res
}
}
impl IntoResponse for Response {
fn into_response(self) -> Response {
self
}
}
impl<R> IntoResponse for (Parts, R)
where
R: IntoResponse,
{
fn into_response(self) -> Response {
let mut res = self.1.into_response();
*res.status_mut() = self.0.status;
*res.headers_mut() = self.0.headers;
res
}
}
impl<T, E> IntoResponse for Result<T, E>
where
T: IntoResponse,
E: IntoResponse,
{
fn into_response(self) -> Response {
match self {
Ok(t) => t.into_response(),
Err(e) => e.into_response(),
}
}
}
macro_rules! define_into_response_for_tuple {
($($t:ident),*) => {
#[allow(non_snake_case)]
impl<$($t,)* R> IntoResponse for ($($t,)* R)
where
$($t: IntoParts + Clone,)*
R: IntoResponse
{
fn into_response(self) -> Response {
let ($($t,)* res) = self;
let mut parts = Parts::default();
$(
parts = $t.clone().into_parts(parts.clone());
)*
(parts, res).into_response()
}
}
};
}
define_into_response_for_tuple!(T1);
define_into_response_for_tuple!(T1, T2);
define_into_response_for_tuple!(T1, T2, T3);
define_into_response_for_tuple!(T1, T2, T3, T4);
define_into_response_for_tuple!(T1, T2, T3, T4, T5);
define_into_response_for_tuple!(T1, T2, T3, T4, T5, T6);
define_into_response_for_tuple!(T1, T2, T3, T4, T5, T6, T7);
define_into_response_for_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);
pub trait IntoResponseBoxed {
fn into_response_boxed(self: Box<Self>) -> Response;
}
impl<T> IntoResponseBoxed for T
where
T: IntoResponse,
{
fn into_response_boxed(self: Box<Self>) -> Response {
(*self).into_response()
}
}
impl<T> IntoResponse for Box<T>
where
T: ?Sized + IntoResponse,
{
fn into_response(self) -> Response {
self.into_response_boxed()
}
}