summaryrefslogtreecommitdiffstats
path: root/template
diff options
context:
space:
mode:
authorPhilipp Korber <philippkorber@gmail.com>2018-11-22 20:22:23 +0100
committerPhilipp Korber <philippkorber@gmail.com>2018-11-22 20:22:23 +0100
commit55482f880cfa67e68e52e5937f36251e886c137c (patch)
tree6092677fac3b5422433188b99b098a66d029f563 /template
parente0cdb9dbae5649b29753232bed9136389b940e23 (diff)
fix(examples) made template example usable again
Diffstat (limited to 'template')
-rw-r--r--template/src/handlebars.rs27
-rw-r--r--template/src/lib.rs3
-rw-r--r--template/src/serde_impl.rs72
3 files changed, 86 insertions, 16 deletions
diff --git a/template/src/handlebars.rs b/template/src/handlebars.rs
index 2d06a31..370e649 100644
--- a/template/src/handlebars.rs
+++ b/template/src/handlebars.rs
@@ -11,6 +11,14 @@ use super::{
serde_impl
};
+//TODO[FEAT] add custom engine config section to loading
+// e.g. something like:
+// ```
+// [engine]
+// load_partial = "../partials/baseh.html"
+// ```
+//
+// Just specific to each engine.
pub struct Handlebars {
@@ -20,6 +28,25 @@ pub struct Handlebars {
impl Handlebars {
+ pub fn new() -> Self {
+ Handlebars {
+ inner: hbs::Handlebars::new(),
+ name_counter: 0
+ }
+ }
+
+ pub fn inner(&self) -> &hbs::Handlebars {
+ &self.inner
+ }
+
+ /// Provides mutable access to the underling handlebars instance.
+ ///
+ /// This can be used to e.g. add partials (in the future the template
+ /// file will have a custom config section but currently it doesn't).
+ pub fn inner_mut(&mut self) -> &mut hbs::Handlebars {
+ &mut self.inner
+ }
+
fn next_body_template_name(&mut self) -> String {
let name = format!("body_{}", self.name_counter);
self.name_counter += 1;
diff --git a/template/src/lib.rs b/template/src/lib.rs
index 09aea12..26e70cb 100644
--- a/template/src/lib.rs
+++ b/template/src/lib.rs
@@ -87,6 +87,9 @@ pub trait TemplateEngineCanHandleData<D>: TemplateEngine {
}
/// Load a template as described in a toml file.
+///
+/// This will set the default of the base_dir to the
+/// dir the template file loaded is in.
pub fn load_toml_template_from_path<TE, C>(
engine: TE,
path: PathBuf,
diff --git a/template/src/serde_impl.rs b/template/src/serde_impl.rs
index 2ab709d..f8e7021 100644
--- a/template/src/serde_impl.rs
+++ b/template/src/serde_impl.rs
@@ -1,13 +1,12 @@
use std::{
collections::HashMap,
- path::{Path, PathBuf}
+ path::{Path, PathBuf},
+ mem
};
use serde::{
Serialize, Deserialize,
- de::{
- Deserializer,
- },
+ Serializer, Deserializer
};
use failure::Error;
use futures::{Future, future::{self, Either}};
@@ -52,10 +51,10 @@ pub struct TemplateBase<TE: TemplateEngine> {
base_dir: Option<CwdBaseDir>,
subject: LazySubject,
bodies: Vec1<TE::LazyBodyTemplate>,
- //TODO impl. deserialize where
- // resource:String -> IRI::new("path", resource) -> Resource::Source
+ #[serde(default)]
#[serde(deserialize_with="deserialize_embeddings")]
embeddings: HashMap<String, Resource>,
+ #[serde(default)]
#[serde(deserialize_with="deserialize_attachments")]
attachments: Vec<Resource>,
}
@@ -65,7 +64,7 @@ impl<TE> TemplateBase<TE>
{
//TODO!! make this load all embeddings/attachments and make it a future
- /// Couples the template base with a specific engine instance.
+ /// Couples the template base with a specific engine instance.``
pub fn load(self, mut engine: TE, default_base_dir: CwdBaseDir, ctx: &impl Context) -> impl Future<Item=Template<TE>, Error=Error> {
let TemplateBase {
template_name,
@@ -98,18 +97,31 @@ impl<TE> TemplateBase<TE>
Ok((subject, bodies))
})();
- let (subject, bodies) =
+ let (subject, mut bodies) =
match catch_res {
Ok(vals) => vals,
Err(err) => { return Either::B(future::err(err)); }
};
- let loading_fut = Resource::load_container(embeddings, ctx)
- .join(Resource::load_container(attachments, ctx));
+ let loading_embeddings = Resource::load_container(embeddings, ctx);
+ let loading_attachments = Resource::load_container(attachments, ctx);
+ let loading_body_embeddings = bodies.iter_mut()
+ .map(|body| {
+ //Note: empty HashMap does not alloc!
+ let body_embeddings = mem::replace(&mut body.inline_embeddings, HashMap::new());
+ Resource::load_container(body_embeddings, ctx)
+ })
+ .collect::<Vec<_>>();
+ let loading_body_embeddings = future::join_all(loading_body_embeddings);
+
- let fut = loading_fut
+ let fut = loading_embeddings
+ .join3(loading_attachments, loading_body_embeddings)
.map_err(Error::from)
- .map(|(embeddings, attachments)| {
+ .map(|(embeddings, attachments, body_embeddings)| {
+ for (body, loaded_embeddings) in bodies.iter_mut().zip(body_embeddings) {
+ mem::replace(&mut body.inline_embeddings, loaded_embeddings);
+ }
Template {
template_name,
base_dir,
@@ -125,12 +137,30 @@ impl<TE> TemplateBase<TE>
}
}
-#[derive(Debug, Serialize, Deserialize)]
+#[derive(Debug)]
struct LazySubject {
- #[serde(flatten)]
template_string: String
}
+impl Serialize for LazySubject {
+
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where S: Serializer
+ {
+ serializer.serialize_str(&self.template_string)
+ }
+}
+
+impl<'de> Deserialize<'de> for LazySubject {
+
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where D: Deserializer<'de>
+ {
+ let template_string = String::deserialize(deserializer)?;
+ Ok(LazySubject { template_string })
+ }
+}
+
#[derive(Deserialize)]
#[serde(untagged)]
enum ResourceDeserializationHelper {
@@ -214,13 +244,23 @@ impl PathRebaseable for StandardLazyBodyTemplate {
fn rebase_to_include_base_dir(&mut self, base_dir: impl AsRef<Path>)
-> Result<(), UnsupportedPathError>
{
- self.path.rebase_to_include_base_dir(base_dir)
+ let base_dir = base_dir.as_ref();
+ self.path.rebase_to_include_base_dir(base_dir)?;
+ for embedding in self.embeddings.values_mut() {
+ embedding.rebase_to_include_base_dir(base_dir)?;
+ }
+ Ok(())
}
fn rebase_to_exclude_base_dir(&mut self, base_dir: impl AsRef<Path>)
-> Result<(), UnsupportedPathError>
{
- self.path.rebase_to_exclude_base_dir(base_dir)
+ let base_dir = base_dir.as_ref();
+ self.path.rebase_to_exclude_base_dir(base_dir)?;
+ for embedding in self.embeddings.values_mut() {
+ embedding.rebase_to_exclude_base_dir(base_dir)?;
+ }
+ Ok(())
}
}