xitca_web/handler/types/
html.rs1use core::{convert::Infallible, fmt};
4
5use xitca_http::util::service::router::{PathGen, RouteGen, RouterMapErr};
6
7use crate::{
8 body::ResponseBody,
9 context::WebContext,
10 error::Error,
11 handler::Responder,
12 http::{WebResponse, const_header_value::TEXT_HTML_UTF8, header::CONTENT_TYPE},
13 service::Service,
14};
15
16#[derive(Clone)]
17pub struct Html<T>(pub T);
18
19impl<T> fmt::Debug for Html<T>
20where
21 T: fmt::Debug,
22{
23 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24 f.debug_struct("Html").field("value", &self.0).finish()
25 }
26}
27
28impl<'r, C, B, T> Responder<WebContext<'r, C, B>> for Html<T>
29where
30 T: Into<ResponseBody>,
31{
32 type Response = WebResponse;
33 type Error = Error;
34
35 #[inline]
36 async fn respond(self, ctx: WebContext<'r, C, B>) -> Result<Self::Response, Self::Error> {
37 let mut res = ctx.into_response(self.0);
38 res.headers_mut().insert(CONTENT_TYPE, TEXT_HTML_UTF8);
39 Ok(res)
40 }
41
42 fn map(self, mut res: Self::Response) -> Result<Self::Response, Self::Error> {
43 res.headers_mut().insert(CONTENT_TYPE, TEXT_HTML_UTF8);
44 Ok(res.map(|_| self.0.into()))
45 }
46}
47
48impl<T> PathGen for Html<T> {}
49
50impl<T> RouteGen for Html<T> {
51 type Route<R> = RouterMapErr<R>;
52
53 fn route_gen<R>(route: R) -> Self::Route<R> {
54 RouterMapErr(route)
55 }
56}
57
58impl<T> Service for Html<T>
59where
60 T: Clone,
61{
62 type Response = Self;
63 type Error = Infallible;
64
65 async fn call(&self, _: ()) -> Result<Self::Response, Self::Error> {
66 Ok(self.clone())
67 }
68}
69
70impl<'r, C, B, T> Service<WebContext<'r, C, B>> for Html<T>
71where
72 T: Clone + Into<ResponseBody>,
73{
74 type Response = WebResponse;
75 type Error = Error;
76
77 #[inline]
78 async fn call(&self, ctx: WebContext<'r, C, B>) -> Result<Self::Response, Self::Error> {
79 self.clone().respond(ctx).await
80 }
81}
82
83#[cfg(test)]
84mod test {
85 use xitca_unsafe_collection::futures::NowOrPanic;
86
87 use crate::{App, http::WebRequest};
88
89 use super::*;
90
91 #[test]
92 fn service() {
93 let res = App::new()
94 .at("/", Html("hello,world!"))
95 .finish()
96 .call(())
97 .now_or_panic()
98 .unwrap()
99 .call(WebRequest::default())
100 .now_or_panic()
101 .unwrap();
102 assert_eq!(res.status().as_u16(), 200);
103 }
104}