1use std::borrow::Cow;
2use std::convert::Infallible;
3
4use http::{Extensions, HeaderMap, HeaderName, HeaderValue, StatusCode, Version, header};
5
6use crate::BoxError;
7use crate::body::{Body, Bytes, HttpBody};
8use crate::response::{Response, ResponseParts};
9
10pub trait IntoResponse {
43 type Error: Into<BoxError>;
45
46 fn into_response(self) -> Result<Response, Self::Error>;
48}
49
50pub trait IntoResponseParts {
52 type Error: Into<BoxError>;
54
55 fn into_response_parts(self, parts: ResponseParts) -> Result<ResponseParts, Self::Error>;
57}
58
59impl IntoResponse for Infallible {
60 type Error = Infallible;
61
62 fn into_response(self) -> Result<Response, Self::Error> {
63 match self {}
64 }
65}
66
67impl IntoResponse for () {
68 type Error = Infallible;
69
70 fn into_response(self) -> Result<Response, Self::Error> {
71 Ok(Response::new(Body::empty()))
72 }
73}
74
75impl IntoResponse for &'static str {
76 type Error = Infallible;
77
78 fn into_response(self) -> Result<Response, Self::Error> {
79 Cow::Borrowed(self).into_response()
80 }
81}
82
83impl IntoResponse for String {
84 type Error = Infallible;
85
86 fn into_response(self) -> Result<Response, Self::Error> {
87 Cow::<'static, str>::Owned(self).into_response()
88 }
89}
90
91impl IntoResponse for Cow<'static, str> {
92 type Error = Infallible;
93
94 fn into_response(self) -> Result<Response, Self::Error> {
95 let mut res = Response::new(Body::from(self));
96 res.headers_mut().insert(
97 header::CONTENT_TYPE,
98 HeaderValue::from_static(mime::TEXT_PLAIN_UTF_8.as_ref()),
99 );
100 Ok(res)
101 }
102}
103
104impl IntoResponse for &'static [u8] {
105 type Error = Infallible;
106
107 fn into_response(self) -> Result<Response, Self::Error> {
108 Cow::Borrowed(self).into_response()
109 }
110}
111
112impl IntoResponse for Vec<u8> {
113 type Error = Infallible;
114
115 fn into_response(self) -> Result<Response, Self::Error> {
116 Cow::<'static, [u8]>::Owned(self).into_response()
117 }
118}
119
120impl IntoResponse for Cow<'static, [u8]> {
121 type Error = Infallible;
122
123 fn into_response(self) -> Result<Response, Self::Error> {
124 let mut res = Response::new(Body::from(self));
125 res.headers_mut().insert(
126 header::CONTENT_TYPE,
127 HeaderValue::from_static(mime::APPLICATION_OCTET_STREAM.as_ref()),
128 );
129 Ok(res)
130 }
131}
132
133impl IntoResponse for Bytes {
134 type Error = Infallible;
135
136 fn into_response(self) -> Result<Response, Self::Error> {
137 let mut res = Response::new(Body::from(self));
138 res.headers_mut().insert(
139 header::CONTENT_TYPE,
140 HeaderValue::from_static(mime::APPLICATION_OCTET_STREAM.as_ref()),
141 );
142 Ok(res)
143 }
144}
145
146impl IntoResponse for Body {
147 type Error = Infallible;
148
149 fn into_response(self) -> Result<Response, Self::Error> {
150 Ok(Response::new(self))
151 }
152}
153
154impl<B> IntoResponse for Response<B>
155where
156 B: HttpBody<Data = Bytes> + Send + 'static,
157 B::Error: Into<BoxError>,
158{
159 type Error = Infallible;
160
161 fn into_response(self) -> Result<Response, Self::Error> {
162 Ok(self.map(Body::new))
163 }
164}
165
166impl<R, E> IntoResponse for Result<R, E>
167where
168 R: IntoResponse,
169 E: Into<BoxError>,
170{
171 type Error = BoxError;
172
173 fn into_response(self) -> Result<Response, Self::Error> {
174 self.map_or_else(|e| Err(e.into()), |r| r.into_response().map_err(Into::into))
175 }
176}
177
178impl<P> IntoResponse for P
179where
180 P: IntoResponseParts,
181{
182 type Error = P::Error;
183
184 fn into_response(self) -> Result<Response, Self::Error> {
185 let parts = Response::new(()).into_parts();
186 self.into_response_parts(parts)
187 .map(|parts| Response::from_parts(parts, Body::empty()))
188 }
189}
190
191macro_rules! into_response_tuples {
192 ($($ty:ident),* @ $($tyr:ident),* $(,)?) => {
193 #[allow(non_snake_case)]
194 impl<R, $($ty,)*> IntoResponse for ($($ty),*, R)
195 where
196 $($ty: IntoResponseParts,)*
197 R: IntoResponse,
198 {
199 type Error = BoxError;
200
201 fn into_response(self) -> Result<Response, Self::Error> {
202 let ($($ty),*, res) = self;
203
204 let res = res.into_response().map_err(Into::into)?;
205 let (parts, body) = res.into_inner();
206 $(
207 let parts = $tyr.into_response_parts(parts).map_err(Into::into)?;
208 )*
209 Ok(Response::from_parts(parts, body))
210 }
211 }
212 }
213}
214
215into_response_tuples!(
216 T1 @
217 T1
218);
219into_response_tuples!(
220 T1, T2 @
221 T2, T1
222);
223into_response_tuples!(
224 T1, T2, T3 @
225 T3, T2, T1
226);
227into_response_tuples!(
228 T1, T2, T3, T4 @
229 T4, T3, T2, T1
230);
231into_response_tuples!(
232 T1, T2, T3, T4, T5 @
233 T5, T4, T3, T2, T1
234);
235into_response_tuples!(
236 T1, T2, T3, T4, T5, T6 @
237 T6, T5, T4, T3, T2, T1
238);
239into_response_tuples!(
240 T1, T2, T3, T4, T5, T6, T7 @
241 T7, T6, T5, T4, T3, T2, T1
242);
243into_response_tuples!(
244 T1, T2, T3, T4, T5, T6, T7, T8 @
245 T8, T7, T6, T5, T4, T3, T2, T1
246);
247into_response_tuples!(
248 T1, T2, T3, T4, T5, T6, T7, T8, T9 @
249 T9, T8, T7, T6, T5, T4, T3, T2, T1
250);
251into_response_tuples!(
252 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 @
253 T10, T9, T8, T7, T6, T5, T4, T3, T2, T1
254);
255into_response_tuples!(
256 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 @
257 T11, T10, T9, T8, T7, T6, T5, T4, T3, T2, T1
258);
259into_response_tuples!(
260 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 @
261 T12, T11, T10, T9, T8, T7, T6, T5, T4, T3, T2, T1
262);
263into_response_tuples!(
264 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 @
265 T13, T12, T11, T10, T9, T8, T7, T6, T5, T4, T3, T2, T1
266);
267into_response_tuples!(
268 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 @
269 T14, T13, T12, T11, T10, T9, T8, T7, T6, T5, T4, T3, T2, T1
270);
271into_response_tuples!(
272 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 @
273 T15, T14, T13, T12, T11, T10, T9, T8, T7, T6, T5, T4, T3, T2, T1
274);
275into_response_tuples!(
276 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 @
277 T16, T15, T14, T13, T12, T11, T10, T9, T8, T7, T6, T5, T4, T3, T2, T1
278);
279
280impl<T> IntoResponseParts for Option<T>
281where
282 T: IntoResponseParts,
283{
284 type Error = T::Error;
285
286 fn into_response_parts(self, parts: ResponseParts) -> Result<ResponseParts, Self::Error> {
287 match self {
288 Some(this) => this.into_response_parts(parts),
289 None => Ok(parts),
290 }
291 }
292}
293
294impl IntoResponseParts for StatusCode {
295 type Error = Infallible;
296
297 fn into_response_parts(self, mut parts: ResponseParts) -> Result<ResponseParts, Self::Error> {
298 parts.status = self;
299 Ok(parts)
300 }
301}
302
303impl IntoResponseParts for Version {
304 type Error = Infallible;
305
306 fn into_response_parts(self, mut parts: ResponseParts) -> Result<ResponseParts, Self::Error> {
307 parts.version = self;
308 Ok(parts)
309 }
310}
311
312impl IntoResponseParts for HeaderMap {
313 type Error = Infallible;
314
315 fn into_response_parts(self, mut parts: ResponseParts) -> Result<ResponseParts, Self::Error> {
316 parts.headers.extend(self);
317 Ok(parts)
318 }
319}
320
321impl IntoResponseParts for Extensions {
322 type Error = Infallible;
323
324 fn into_response_parts(self, mut parts: ResponseParts) -> Result<ResponseParts, Self::Error> {
325 parts.extensions.extend(self);
326 Ok(parts)
327 }
328}
329
330impl IntoResponseParts for ResponseParts {
331 type Error = Infallible;
332
333 fn into_response_parts(self, mut parts: ResponseParts) -> Result<ResponseParts, Self::Error> {
334 parts = self.extensions.into_response_parts(parts)?;
335 parts = self.headers.into_response_parts(parts)?;
336 parts = self.version.into_response_parts(parts)?;
337 parts = self.status.into_response_parts(parts)?;
338 Ok(parts)
339 }
340}
341
342impl<K, V, const N: usize> IntoResponseParts for [(K, V); N]
343where
344 K: TryInto<HeaderName>,
345 K::Error: std::fmt::Display,
346 V: TryInto<HeaderValue>,
347 V::Error: std::fmt::Display,
348{
349 type Error = HeaderResponseError;
350
351 fn into_response_parts(self, mut parts: ResponseParts) -> Result<ResponseParts, Self::Error> {
352 for (k, v) in self {
353 let k = k
354 .try_into()
355 .map_err(|e| HeaderResponseError::InvalidHeaderName(e.to_string()))?;
356 let v = v
357 .try_into()
358 .map_err(|e| HeaderResponseError::InvalidHeaderValue(e.to_string()))?;
359 parts.headers.insert(k, v);
360 }
361 Ok(parts)
362 }
363}
364
365impl<K, V> IntoResponseParts for Vec<(K, V)>
366where
367 K: TryInto<HeaderName>,
368 K::Error: std::fmt::Display,
369 V: TryInto<HeaderValue>,
370 V::Error: std::fmt::Display,
371{
372 type Error = HeaderResponseError;
373
374 fn into_response_parts(self, mut parts: ResponseParts) -> Result<ResponseParts, Self::Error> {
375 for (k, v) in self {
376 let k = k
377 .try_into()
378 .map_err(|e| HeaderResponseError::InvalidHeaderName(e.to_string()))?;
379 let v = v
380 .try_into()
381 .map_err(|e| HeaderResponseError::InvalidHeaderValue(e.to_string()))?;
382 parts.headers.insert(k, v);
383 }
384 Ok(parts)
385 }
386}
387
388#[derive(Debug, Clone)]
390pub enum HeaderResponseError {
391 InvalidHeaderName(String),
393 InvalidHeaderValue(String),
395}
396
397impl std::fmt::Display for HeaderResponseError {
398 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
399 match self {
400 HeaderResponseError::InvalidHeaderName(e) => {
401 write!(f, "invalid response header name ({e})")
402 }
403 HeaderResponseError::InvalidHeaderValue(e) => {
404 write!(f, "invalid response header value ({e})")
405 }
406 }
407 }
408}
409
410impl std::error::Error for HeaderResponseError {}