diff options
author | Philipp Korber <philippkorber@gmail.com> | 2018-11-22 14:18:11 +0100 |
---|---|---|
committer | Philipp Korber <philippkorber@gmail.com> | 2018-11-22 14:18:11 +0100 |
commit | 186e763e7686c95a414d4ac79c3ebcf1b0f87f36 (patch) | |
tree | 138676260cc07b1f947e3a6cd809a74a9e3c19a7 | |
parent | ff0d27240642d8b5b0b1e70656f9411afabb5000 (diff) |
feat(handlebars) added initial handlebars bindings
-rw-r--r-- | Cargo.toml | 3 | ||||
-rw-r--r-- | examples/readme.rs | 6 | ||||
-rw-r--r-- | src/handlebars.rs | 96 | ||||
-rw-r--r-- | src/lib.rs | 3 |
4 files changed, 101 insertions, 7 deletions
@@ -12,7 +12,7 @@ repository = "https://github.com/1aim/mail-template" [features] default = [] -handlebars-bindings = [] +handlebars-bindings = ["handlebars"] [dependencies] mail-core = { git="https://github.com/1aim/mail", features=["serde-impl"] } @@ -27,6 +27,7 @@ serde = { version="1", features=["derive"] } toml = "0.4.8" maybe-owned = "0.3.2" +handlebars = { version="1.1.0", optional=true } [dependencies.mime] git="https://github.com/1aim/mime" diff --git a/examples/readme.rs b/examples/readme.rs deleted file mode 100644 index ea19f16..0000000 --- a/examples/readme.rs +++ /dev/null @@ -1,6 +0,0 @@ - - - -fn main() { - -}
\ No newline at end of file diff --git a/src/handlebars.rs b/src/handlebars.rs new file mode 100644 index 0000000..887dce1 --- /dev/null +++ b/src/handlebars.rs @@ -0,0 +1,96 @@ +use hbs; +use serde::{Serialize, Deserialize}; +use galemu::{Bound, BoundExt, create_gal_wrapper_type, Ref}; +use failure::Error; + + +use super::{ + TemplateEngine, + TemplateEngineCanHandleData, + BodyTemplate, + PreparationData, + AdditionalCIds, + PathRebaseable, + UnsupportedPathError, + serde_impl +}; + + + +pub struct Handlebars { + inner: hbs::Handlebars, + name_counter: usize +} + +impl Handlebars { + + fn next_body_template_name(&mut self) -> String { + let name = format!("body_{}", self.name_counter); + self.name_counter += 1; + name + } +} +impl TemplateEngine for Handlebars { + type Id = String; + + type LazyBodyTemplate = serde_impl::StandardLazyBodyTemplate; + + fn load_body_template(&mut self, tmpl: Self::LazyBodyTemplate) + -> Result<BodyTemplate<Self>, Error> + { + let StandardLazyBodyTemplate { + path, embeddings, media_type + } = tmpl; + + let name = self.next_body_template_name(); + self.inner.register_template_file(name, path)?; + + let media_type = + if let Some(media_type) = media_type { + media_type + } else if let Some(extension) = path.extension().and_then(|osstr| osstr.as_str()) { + match extension { + "html" => "text/html; charset=utf-8".parse().unwrap(), + "txt" => "text/plain; charset=utf-8".parse().unwrap() + } + } else { + return Err(failure::err_msg( + "handlebars requires html/txt file extension or media type given in template spec" + )); + }; + + Ok(BodyTemplate { + template_id: name, + media_type: TODO, + inline_embeddings: Default::default(), + }) + } + + fn load_subject_template(&mut self, template_string: String) + -> Result<Self::Id, Error> + { + Ok(self.inner.register_template_string("subject".to_owned(), template_string)?) + } +} + +/// Additional trait a template engine needs to implement for the types it can process as input. +/// +/// This could for example be implemented in a wild card impl for the template engine for +/// any data `D` which implements `Serialize`. +impl<D> TemplateEngineCanHandleData<D> for Handlebars + where D: Serialize +{ + fn render<'r, 'a>( + &'r self, + id: &'r Self::Id, + data: &'r D, + additional_cids: AdditionalCIds<'r> + ) -> Result<String, Error> { + Ok(self.inner.render(id, SerHelper { data, cids: additional_cid })?) + } +} + +struct SerHelper<'r, D> { + data: &'r D, + cids: AdditionalCIds<'r> +}
\ No newline at end of file @@ -9,6 +9,9 @@ extern crate maybe_owned; #[cfg(feature="handlebars")] extern crate handlebars as hbs; +#[cfg(all(feature="handlebars", not(feature="handlebars-bindings")))] +compile_error!("use feature `handlebars-bindings` instead of opt-dep-auto-feature `handlebars`"); + use std::{ fs, collections::HashMap, |