finchers_template/
askama.rs1extern crate askama;
4
5#[doc(no_inline)]
6pub use self::askama::Template;
7pub use self::imp::{renderer, RenderEndpoint, Renderer};
8
9mod imp {
10 use super::askama::Template;
11
12 use finchers::endpoint::wrapper::Wrapper;
13 use finchers::endpoint::{ApplyContext, ApplyResult, Endpoint};
14 use finchers::error;
15 use finchers::error::Error;
16
17 use futures::{Future, Poll};
18 use http::header;
19 use http::header::HeaderValue;
20 use http::Response;
21 use mime;
22 use mime::Mime;
23
24 pub fn renderer() -> Renderer {
27 Renderer {
28 content_type: mime::TEXT_HTML_UTF_8.as_ref().parse().unwrap(),
29 }
30 }
31
32 #[derive(Debug)]
34 pub struct Renderer {
35 content_type: HeaderValue,
36 }
37
38 impl Renderer {
39 pub fn content_type(self, content_type: Mime) -> Renderer {
43 let content_type = content_type
44 .as_ref()
45 .parse()
46 .expect("the MIME value should be a valid header value");
47 Renderer {
48 content_type,
49 ..self
50 }
51 }
52
53 fn render_response<T>(&self, ctx: &T) -> Result<Response<String>, super::askama::Error>
54 where
55 T: Template,
56 {
57 let mut response = ctx.render().map(Response::new)?;
58 response
59 .headers_mut()
60 .insert(header::CONTENT_TYPE, self.content_type.clone());
61 Ok(response)
62 }
63 }
64
65 impl<'a, E, CtxT> Wrapper<'a, E> for Renderer
66 where
67 E: Endpoint<'a, Output = (CtxT,)>,
68 CtxT: Template,
69 {
70 type Output = (Response<String>,);
71 type Endpoint = RenderEndpoint<E>;
72
73 fn wrap(self, endpoint: E) -> Self::Endpoint {
74 RenderEndpoint {
75 endpoint,
76 renderer: self,
77 }
78 }
79 }
80
81 #[derive(Debug)]
84 pub struct RenderEndpoint<E> {
85 endpoint: E,
86 renderer: Renderer,
87 }
88
89 impl<'a, E, CtxT> Endpoint<'a> for RenderEndpoint<E>
90 where
91 E: Endpoint<'a, Output = (CtxT,)>,
92 CtxT: Template,
93 {
94 type Output = (Response<String>,);
95 type Future = RenderFuture<'a, E>;
96
97 fn apply(&'a self, cx: &mut ApplyContext<'_>) -> ApplyResult<Self::Future> {
98 Ok(RenderFuture {
99 future: self.endpoint.apply(cx)?,
100 endpoint: self,
101 })
102 }
103 }
104
105 #[derive(Debug)]
107 pub struct RenderFuture<'a, E: Endpoint<'a>> {
108 future: E::Future,
109 endpoint: &'a RenderEndpoint<E>,
110 }
111
112 impl<'a, E, CtxT> Future for RenderFuture<'a, E>
113 where
114 E: Endpoint<'a, Output = (CtxT,)>,
115 CtxT: Template,
116 {
117 type Item = (Response<String>,);
118 type Error = Error;
119
120 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
121 let (ctx,) = try_ready!(self.future.poll());
122 self.endpoint
123 .renderer
124 .render_response(&ctx)
125 .map(|response| (response,).into())
126 .map_err(error::fail)
127 }
128 }
129}