1pub mod sse;
11
12use crate::RequestContext;
13use crate::body::ResponseBody;
14use http::{Response, StatusCode};
15use std::convert::Infallible;
16
17pub trait Responder {
22 fn response_to(self, req: &RequestContext) -> Response<ResponseBody>;
23}
24
25impl<T: Responder, E: Responder> Responder for Result<T, E> {
28 fn response_to(self, req: &RequestContext) -> Response<ResponseBody> {
29 match self {
30 Ok(t) => t.response_to(req),
31 Err(e) => e.response_to(req),
32 }
33 }
34}
35
36impl<T: Responder> Responder for Option<T> {
39 fn response_to(self, req: &RequestContext) -> Response<ResponseBody> {
40 match self {
41 Some(t) => t.response_to(req),
42 None => Response::new(ResponseBody::empty()),
43 }
44 }
45}
46
47impl<B> Responder for Response<B>
50where
51 B: Into<ResponseBody>,
52{
53 fn response_to(self, _req: &RequestContext) -> Response<ResponseBody> {
54 self.map(|b| b.into())
55 }
56}
57
58impl<T: Responder> Responder for (StatusCode, T) {
61 fn response_to(self, req: &RequestContext) -> Response<ResponseBody> {
62 let (status, responder) = self;
63 let mut response = responder.response_to(req);
64 *response.status_mut() = status;
65 response
66 }
67}
68
69impl<T: Responder> Responder for (T, StatusCode) {
71 fn response_to(self, req: &RequestContext) -> Response<ResponseBody> {
72 let (responder, status) = self;
73 (status, responder).response_to(req)
74 }
75}
76
77impl<T: Responder> Responder for Box<T> {
79 fn response_to(self, req: &RequestContext) -> Response<ResponseBody> {
80 (*self).response_to(req)
81 }
82}
83
84impl Responder for () {
86 fn response_to(self, _req: &RequestContext) -> Response<ResponseBody> {
87 Response::new(ResponseBody::empty())
88 }
89}
90
91impl Responder for &'static str {
93 fn response_to(self, _req: &RequestContext) -> Response<ResponseBody> {
94 let mut builder = Response::builder();
95 let headers = builder.headers_mut().unwrap();
96 headers.reserve(8);
97 headers.insert(http::header::CONTENT_TYPE, mime::TEXT_PLAIN_UTF_8.as_ref().parse().unwrap());
98
99 builder.status(StatusCode::OK).body(ResponseBody::from(self)).unwrap()
100 }
101}
102
103impl Responder for String {
105 fn response_to(self, _req: &RequestContext) -> Response<ResponseBody> {
106 let mut builder = Response::builder();
107 let headers = builder.headers_mut().unwrap();
108 headers.reserve(8);
109 headers.insert(http::header::CONTENT_TYPE, mime::TEXT_PLAIN_UTF_8.as_ref().parse().unwrap());
110
111 builder.status(StatusCode::OK).body(ResponseBody::from(self)).unwrap()
112 }
113}
114
115impl Responder for Infallible {
116 fn response_to(self, _req: &RequestContext) -> Response<ResponseBody> {
117 unreachable!()
118 }
119}
120
121pub struct NotFound;
122
123impl Responder for NotFound {
124 #[inline]
125 fn response_to(self, req: &RequestContext) -> Response<ResponseBody> {
126 ("404 Not Found.", StatusCode::NOT_FOUND).response_to(req)
127 }
128}