diff options
author | Philipp Korber <philippkorber@gmail.com> | 2018-11-22 20:22:23 +0100 |
---|---|---|
committer | Philipp Korber <philippkorber@gmail.com> | 2018-11-22 20:22:23 +0100 |
commit | 55482f880cfa67e68e52e5937f36251e886c137c (patch) | |
tree | 6092677fac3b5422433188b99b098a66d029f563 /template | |
parent | e0cdb9dbae5649b29753232bed9136389b940e23 (diff) |
fix(examples) made template example usable again
Diffstat (limited to 'template')
-rw-r--r-- | template/src/handlebars.rs | 27 | ||||
-rw-r--r-- | template/src/lib.rs | 3 | ||||
-rw-r--r-- | template/src/serde_impl.rs | 72 |
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(()) } } |