mail_template/
handlebars.rs1use hbs;
2use serde::Serialize;
3use failure::Error;
4
5
6use super::{
7 TemplateEngine,
8 TemplateEngineCanHandleData,
9 BodyTemplate,
10 AdditionalCIds,
11 serde_impl
12};
13
14pub struct Handlebars {
25 inner: hbs::Handlebars,
26 name_counter: usize
27}
28
29impl Handlebars {
30
31 pub fn new() -> Self {
32 Handlebars {
33 inner: hbs::Handlebars::new(),
34 name_counter: 0
35 }
36 }
37
38 pub fn inner(&self) -> &hbs::Handlebars {
39 &self.inner
40 }
41
42 pub fn inner_mut(&mut self) -> &mut hbs::Handlebars {
47 &mut self.inner
48 }
49
50 fn next_body_template_name(&mut self) -> String {
51 let name = format!("body_{}", self.name_counter);
52 self.name_counter += 1;
53 name
54 }
55}
56impl TemplateEngine for Handlebars {
57 type Id = String;
58
59 type LazyBodyTemplate = serde_impl::StandardLazyBodyTemplate;
60
61 fn load_body_template(&mut self, tmpl: Self::LazyBodyTemplate)
62 -> Result<BodyTemplate<Self>, Error>
63 {
64 let serde_impl::StandardLazyBodyTemplate {
65 path, embeddings, media_type
66 } = tmpl;
67
68 let name = self.next_body_template_name();
69 self.inner.register_template_file(&name, &path)?;
70
71 const ERR_BAD_MEDIA_TYPE_DETECTION: &str =
72 "handlebars requires html/txt file extension or media type given in template spec";
73
74 let media_type =
75 if let Some(media_type) = media_type {
76 media_type
77 } else if let Some(extension) = path.extension().and_then(|osstr| osstr.to_str()) {
78 match extension {
79 "html" => "text/html; charset=utf-8".parse().unwrap(),
80 "txt" => "text/plain; charset=utf-8".parse().unwrap(),
81 _ => { return Err(failure::err_msg(ERR_BAD_MEDIA_TYPE_DETECTION)); }
82 }
83 } else {
84 return Err(failure::err_msg(ERR_BAD_MEDIA_TYPE_DETECTION));
85 };
86
87 Ok(BodyTemplate {
88 template_id: name,
89 media_type,
90 inline_embeddings: embeddings,
91 })
92 }
93
94 fn load_subject_template(&mut self, template_string: String)
95 -> Result<Self::Id, Error>
96 {
97 let id = "subject".to_owned();
98 self.inner.register_template_string(&id, template_string)?;
99 Ok(id)
100 }
101}
102
103impl<D> TemplateEngineCanHandleData<D> for Handlebars
108 where D: Serialize
109{
110 fn render<'r, 'a>(
111 &'r self,
112 id: &'r Self::Id,
113 data: &'r D,
114 additional_cids: AdditionalCIds<'r>
115 ) -> Result<String, Error> {
116 Ok(self.inner.render(id, &SerHelper { data, cids: additional_cids })?)
117 }
118}
119
120#[derive(Serialize)]
121struct SerHelper<'r, D: 'r> {
122 data: &'r D,
123 cids: AdditionalCIds<'r>
124}