1pub mod sse;
11
12use crate::RequestContext;
13use crate::body::ResponseBody;
14use http::{HeaderValue, 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
91const TEXT_PLAIN_CONTENT_TYPE: HeaderValue = HeaderValue::from_static("text/plain; charset=utf-8");
92
93impl Responder for &'static str {
95 fn response_to(self, _req: &RequestContext) -> Response<ResponseBody> {
96 let mut builder = Response::builder();
97 let headers = builder.headers_mut().unwrap();
98 headers.reserve(16);
99 headers.insert(http::header::CONTENT_TYPE, TEXT_PLAIN_CONTENT_TYPE);
100
101 builder.status(StatusCode::OK).body(ResponseBody::from(self)).unwrap()
102 }
103}
104
105impl Responder for String {
107 fn response_to(self, _req: &RequestContext) -> Response<ResponseBody> {
108 let mut builder = Response::builder();
109 let headers = builder.headers_mut().unwrap();
110 headers.reserve(16);
111 headers.insert(http::header::CONTENT_TYPE, TEXT_PLAIN_CONTENT_TYPE);
112 builder.status(StatusCode::OK).body(ResponseBody::from(self)).unwrap()
113 }
114}
115
116impl Responder for Infallible {
117 fn response_to(self, _req: &RequestContext) -> Response<ResponseBody> {
118 unreachable!()
119 }
120}
121
122#[derive(Debug)]
123pub struct NotFound;
124
125impl Responder for NotFound {
126 #[inline]
127 fn response_to(self, req: &RequestContext) -> Response<ResponseBody> {
128 ("404 Not Found.", StatusCode::NOT_FOUND).response_to(req)
129 }
130}