viz_core/
into_response.rs

1use std::borrow::Cow;
2
3use http::header::CONTENT_LENGTH;
4
5use crate::{Body, Error, Response, ResponseExt, Result, StatusCode};
6
7/// Trait implemented by types that can be converted to an HTTP [`Response`].
8pub trait IntoResponse: Sized {
9    /// Convert self to HTTP [`Response`].
10    #[must_use]
11    fn into_response(self) -> Response;
12
13    /// Convert self to the [`Error`].
14    fn into_error(self) -> Error {
15        Error::Responder(Box::new(self.into_response()))
16    }
17}
18
19impl IntoResponse for Response {
20    fn into_response(self) -> Response {
21        self
22    }
23}
24
25impl IntoResponse for Body {
26    fn into_response(self) -> Response {
27        Response::new(self)
28    }
29}
30
31impl IntoResponse for Error {
32    fn into_response(self) -> Response {
33        match self {
34            Self::Boxed(error) => {
35                let mut resp = error.to_string().into_response();
36                *resp.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
37                resp
38            }
39            Self::Responder(resp) | Self::Report(_, resp) => *resp,
40        }
41    }
42}
43
44impl IntoResponse for std::io::Error {
45    fn into_response(self) -> Response {
46        let mut resp = self.to_string().into_response();
47        *resp.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
48        resp
49    }
50}
51
52impl IntoResponse for std::convert::Infallible {
53    fn into_response(self) -> Response {
54        Response::new(().into())
55    }
56}
57
58impl IntoResponse for String {
59    fn into_response(self) -> Response {
60        let size = self.len();
61        let mut resp = Response::text(self);
62        resp.headers_mut().insert(CONTENT_LENGTH, size.into());
63        resp
64    }
65}
66
67impl IntoResponse for &'static str {
68    fn into_response(self) -> Response {
69        let size = self.len();
70        let mut resp = Response::text(self);
71        resp.headers_mut().insert(CONTENT_LENGTH, size.into());
72        resp
73    }
74}
75
76impl IntoResponse for &'static [u8] {
77    fn into_response(self) -> Response {
78        bytes::Bytes::from(self).into_response()
79    }
80}
81
82impl IntoResponse for Vec<u8> {
83    fn into_response(self) -> Response {
84        bytes::Bytes::from(self).into_response()
85    }
86}
87
88impl<B> IntoResponse for Cow<'static, B>
89where
90    bytes::Bytes: From<&'static B> + From<B::Owned>,
91    B: ToOwned + ?Sized,
92{
93    fn into_response(self) -> Response {
94        match self {
95            Cow::Borrowed(b) => bytes::Bytes::from(b),
96            Cow::Owned(o) => bytes::Bytes::from(o),
97        }
98        .into_response()
99    }
100}
101
102impl IntoResponse for bytes::Bytes {
103    fn into_response(self) -> Response {
104        let size = self.len();
105        let mut resp = Response::binary(self);
106        resp.headers_mut().insert(CONTENT_LENGTH, size.into());
107        resp
108    }
109}
110
111impl IntoResponse for StatusCode {
112    fn into_response(self) -> Response {
113        Response::builder().status(self).body(().into()).unwrap()
114    }
115}
116
117impl<T> IntoResponse for Option<T>
118where
119    T: IntoResponse,
120{
121    fn into_response(self) -> Response {
122        self.map_or_else(
123            || StatusCode::NOT_FOUND.into_response(),
124            IntoResponse::into_response,
125        )
126    }
127}
128
129impl<T, E> IntoResponse for Result<T, E>
130where
131    T: IntoResponse,
132    E: IntoResponse,
133{
134    fn into_response(self) -> Response {
135        match self {
136            Ok(r) => r.into_response(),
137            Err(e) => e.into_response(),
138        }
139    }
140}
141
142impl IntoResponse for () {
143    fn into_response(self) -> Response {
144        Response::new(self.into())
145    }
146}
147
148impl<T> IntoResponse for (StatusCode, T)
149where
150    T: IntoResponse,
151{
152    fn into_response(self) -> Response {
153        let mut resp = self.1.into_response();
154        *resp.status_mut() = self.0;
155        resp
156    }
157}