viz_core/
into_response.rs1use http_body_util::Full;
2
3use crate::{
4 header::{CONTENT_LENGTH, CONTENT_TYPE},
5 Error, Response, Result, StatusCode,
6};
7
8pub trait IntoResponse: Sized {
10 #[must_use]
12 fn into_response(self) -> Response;
13
14 fn into_error(self) -> Error {
16 Error::Responder(self.into_response())
17 }
18}
19
20impl IntoResponse for Response {
21 fn into_response(self) -> Response {
22 self
23 }
24}
25
26impl IntoResponse for Error {
27 fn into_response(self) -> Response {
28 match self {
29 Self::Boxed(error) => {
30 let body = error.to_string();
31 Response::builder()
32 .status(StatusCode::INTERNAL_SERVER_ERROR)
33 .header(CONTENT_LENGTH, body.len())
34 .body(Full::from(body).into())
35 .unwrap()
36 }
37 Self::Responder(resp) | Self::Report(_, resp) => resp,
38 }
39 }
40}
41
42impl IntoResponse for std::io::Error {
43 fn into_response(self) -> Response {
44 let body = self.to_string();
45 Response::builder()
46 .status(StatusCode::INTERNAL_SERVER_ERROR)
47 .header(CONTENT_LENGTH, body.len())
48 .body(Full::from(body).into())
49 .unwrap()
50 }
51}
52
53impl IntoResponse for std::convert::Infallible {
54 fn into_response(self) -> Response {
55 Response::new(().into())
56 }
57}
58
59impl IntoResponse for String {
60 fn into_response(self) -> Response {
61 Response::builder()
62 .header(CONTENT_TYPE, mime::TEXT_PLAIN_UTF_8.as_ref())
63 .header(CONTENT_LENGTH, self.len())
64 .body(Full::from(self).into())
65 .unwrap()
66 }
67}
68
69impl IntoResponse for &'static str {
70 fn into_response(self) -> Response {
71 Response::builder()
72 .header(CONTENT_TYPE, mime::TEXT_PLAIN_UTF_8.as_ref())
73 .header(CONTENT_LENGTH, self.len())
74 .body(Full::from(self).into())
75 .unwrap()
76 }
77}
78
79impl IntoResponse for &'static [u8] {
80 fn into_response(self) -> Response {
81 bytes::Bytes::into_response(self.into())
82 }
83}
84
85impl IntoResponse for Vec<u8> {
86 fn into_response(self) -> Response {
87 bytes::Bytes::into_response(self.into())
88 }
89}
90
91impl IntoResponse for bytes::Bytes {
92 fn into_response(self) -> Response {
93 Response::builder()
94 .header(CONTENT_TYPE, mime::APPLICATION_OCTET_STREAM.as_ref())
95 .header(CONTENT_LENGTH, self.len())
96 .body(Full::from(self).into())
97 .unwrap()
98 }
99}
100
101impl IntoResponse for StatusCode {
102 fn into_response(self) -> Response {
103 Response::builder().status(self).body(().into()).unwrap()
104 }
105}
106
107impl<T> IntoResponse for Option<T>
108where
109 T: IntoResponse,
110{
111 fn into_response(self) -> Response {
112 self.map_or_else(
113 || StatusCode::NOT_FOUND.into_response(),
114 IntoResponse::into_response,
115 )
116 }
117}
118
119impl<T, E> IntoResponse for Result<T, E>
120where
121 T: IntoResponse,
122 E: IntoResponse,
123{
124 fn into_response(self) -> Response {
125 match self {
126 Ok(r) => r.into_response(),
127 Err(e) => e.into_response(),
128 }
129 }
130}
131
132impl IntoResponse for () {
133 fn into_response(self) -> Response {
134 Response::new(self.into())
135 }
136}
137
138impl<T> IntoResponse for (StatusCode, T)
139where
140 T: IntoResponse,
141{
142 fn into_response(self) -> Response {
143 let mut res = self.1.into_response();
144 *res.status_mut() = self.0;
145 res
146 }
147}