summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Korber <philippkorber@gmail.com>2018-11-22 14:18:11 +0100
committerPhilipp Korber <philippkorber@gmail.com>2018-11-22 14:18:11 +0100
commit186e763e7686c95a414d4ac79c3ebcf1b0f87f36 (patch)
tree138676260cc07b1f947e3a6cd809a74a9e3c19a7
parentff0d27240642d8b5b0b1e70656f9411afabb5000 (diff)
feat(handlebars) added initial handlebars bindings
-rw-r--r--Cargo.toml3
-rw-r--r--examples/readme.rs6
-rw-r--r--src/handlebars.rs96
-rw-r--r--src/lib.rs3
4 files changed, 101 insertions, 7 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 624f1dd..18ef13f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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
diff --git a/src/lib.rs b/src/lib.rs
index dc9f529..b889213 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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,