summaryrefslogtreecommitdiffstats
path: root/template/src
diff options
context:
space:
mode:
Diffstat (limited to 'template/src')
-rw-r--r--template/src/additional_cid.rs37
-rw-r--r--template/src/base_dir.rs46
-rw-r--r--template/src/error.rs2
-rw-r--r--template/src/handlebars.rs70
-rw-r--r--template/src/lib.rs202
-rw-r--r--template/src/path_rebase.rs81
-rw-r--r--template/src/serde_impl.rs197
7 files changed, 327 insertions, 308 deletions
diff --git a/template/src/additional_cid.rs b/template/src/additional_cid.rs
index eecf2e7..7d17d4b 100644
--- a/template/src/additional_cid.rs
+++ b/template/src/additional_cid.rs
@@ -1,6 +1,4 @@
-use std::collections::{
- HashMap, HashSet
-};
+use std::collections::{HashMap, HashSet};
use serde::{Serialize, Serializer};
@@ -8,20 +6,20 @@ use mail_core::Resource;
use mail_headers::header_components::ContentId;
pub struct AdditionalCIds<'a> {
- additional_resources: &'a [&'a HashMap<String, Resource>]
+ additional_resources: &'a [&'a HashMap<String, Resource>],
}
impl<'a> AdditionalCIds<'a> {
-
/// Creates a new `AdditionalCIds` instance.
///
/// All resources in the all hash maps have to be loaded to the
/// `Data` or `EncData` variants or using `get` can panic.
pub(crate) fn new(additional_resources: &'a [&'a HashMap<String, Resource>]) -> Self {
- AdditionalCIds { additional_resources }
+ AdditionalCIds {
+ additional_resources,
+ }
}
-
/// Returns the content id associated with the given name.
///
/// If multiple of the maps used to create this type contain the
@@ -35,7 +33,10 @@ impl<'a> AdditionalCIds<'a> {
pub fn get(&self, name: &str) -> Option<&ContentId> {
for possible_source in self.additional_resources {
if let Some(res) = possible_source.get(name) {
- return Some(res.content_id().expect("all resources should be loaded/have a content id"));
+ return Some(
+ res.content_id()
+ .expect("all resources should be loaded/have a content id"),
+ );
}
}
return None;
@@ -44,17 +45,23 @@ impl<'a> AdditionalCIds<'a> {
impl<'a> Serialize for AdditionalCIds<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- where S: Serializer
+ where
+ S: Serializer,
{
let mut existing_keys = HashSet::new();
serializer.collect_map(
self.additional_resources
- .iter()
- .flat_map(|m| m.iter().map(|(k, resc)| {
- (k, resc.content_id().expect("all resources should be loaded/have a content id"))
- }))
- .filter(|key| existing_keys.insert(key.to_owned()))
+ .iter()
+ .flat_map(|m| {
+ m.iter().map(|(k, resc)| {
+ (
+ k,
+ resc.content_id()
+ .expect("all resources should be loaded/have a content id"),
+ )
+ })
+ })
+ .filter(|key| existing_keys.insert(key.to_owned())),
)
}
}
-
diff --git a/template/src/base_dir.rs b/template/src/base_dir.rs
index 91e824a..501945a 100644
--- a/template/src/base_dir.rs
+++ b/template/src/base_dir.rs
@@ -1,19 +1,18 @@
use std::{
- path::{Path, PathBuf},
+ env, io,
ops::{Deref, DerefMut},
- env, io
+ path::{Path, PathBuf},
};
use serde::{
+ de::{Deserialize, Deserializer},
ser::{Serialize, Serializer},
- de::{Deserialize, Deserializer}
};
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CwdBaseDir(PathBuf);
impl CwdBaseDir {
-
/// Creates a new `CwdBaseDir` instance containing exactly the given path.
pub fn new_unchanged(path: PathBuf) -> Self {
CwdBaseDir(path)
@@ -33,16 +32,16 @@ impl CwdBaseDir {
///
/// As getting the CWD can fail this function can fail with a I/O Error, too.
pub fn from_path<P>(path: P) -> Result<Self, io::Error>
- where P: AsRef<Path> + Into<PathBuf>
+ where
+ P: AsRef<Path> + Into<PathBuf>,
{
- let path =
- if path.as_ref().is_absolute() {
- path.into()
- } else {
- let mut cwd = env::current_dir()?;
- cwd.push(path.as_ref());
- cwd
- };
+ let path = if path.as_ref().is_absolute() {
+ path.into()
+ } else {
+ let mut cwd = env::current_dir()?;
+ cwd.push(path.as_ref());
+ cwd
+ };
Ok(CwdBaseDir(path))
}
@@ -64,9 +63,7 @@ impl CwdBaseDir {
pub fn to_base_path(&self) -> Result<&Path, io::Error> {
let cwd = env::current_dir()?;
self.strip_prefix(&cwd)
- .or_else(|_err_does_not_has_that_prefix| {
- Ok(&self)
- })
+ .or_else(|_err_does_not_has_that_prefix| Ok(&self))
}
/// Turns this instance into the `PathBuf` it dereferences to.
@@ -96,32 +93,29 @@ impl AsRef<Path> for CwdBaseDir {
}
}
-
-
impl<'de> Deserialize<'de> for CwdBaseDir {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where D: Deserializer<'de>
+ where
+ D: Deserializer<'de>,
{
use serde::de::Error;
let path_buf = PathBuf::deserialize(deserializer)?;
- Self::from_path(path_buf)
- .map_err(|err| D::Error::custom(err))
+ Self::from_path(path_buf).map_err(|err| D::Error::custom(err))
}
}
impl Serialize for CwdBaseDir {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- where S: Serializer,
+ where
+ S: Serializer,
{
use serde::ser::Error;
- let path = self.to_base_path()
- .map_err(|err| S::Error::custom(err))?;
+ let path = self.to_base_path().map_err(|err| S::Error::custom(err))?;
path.serialize(serializer)
}
}
-
#[cfg(test)]
mod tests {
use super::*;
@@ -150,4 +144,4 @@ mod tests {
let path = base_dir.to_base_path().unwrap();
assert_eq!(path, Path::new("hy/there"));
}
-} \ No newline at end of file
+}
diff --git a/template/src/error.rs b/template/src/error.rs
index 94fd942..539045f 100644
--- a/template/src/error.rs
+++ b/template/src/error.rs
@@ -1,3 +1,3 @@
//! Module re-exporting all error types.
-pub use crate::path_rebase::UnsupportedPathError; \ No newline at end of file
+pub use crate::path_rebase::UnsupportedPathError;
diff --git a/template/src/handlebars.rs b/template/src/handlebars.rs
index 370e649..751ba8a 100644
--- a/template/src/handlebars.rs
+++ b/template/src/handlebars.rs
@@ -1,14 +1,9 @@
+use failure::Error;
use hbs;
use serde::Serialize;
-use failure::Error;
-
use super::{
- TemplateEngine,
- TemplateEngineCanHandleData,
- BodyTemplate,
- AdditionalCIds,
- serde_impl
+ serde_impl, AdditionalCIds, BodyTemplate, TemplateEngine, TemplateEngineCanHandleData,
};
//TODO[FEAT] add custom engine config section to loading
@@ -20,18 +15,16 @@ use super::{
//
// Just specific to each engine.
-
pub struct Handlebars {
inner: hbs::Handlebars,
- name_counter: usize
+ name_counter: usize,
}
impl Handlebars {
-
pub fn new() -> Self {
Handlebars {
inner: hbs::Handlebars::new(),
- name_counter: 0
+ name_counter: 0,
}
}
@@ -58,11 +51,14 @@ impl TemplateEngine for Handlebars {
type LazyBodyTemplate = serde_impl::StandardLazyBodyTemplate;
- fn load_body_template(&mut self, tmpl: Self::LazyBodyTemplate)
- -> Result<BodyTemplate<Self>, Error>
- {
+ fn load_body_template(
+ &mut self,
+ tmpl: Self::LazyBodyTemplate,
+ ) -> Result<BodyTemplate<Self>, Error> {
let serde_impl::StandardLazyBodyTemplate {
- path, embeddings, media_type
+ path,
+ embeddings,
+ media_type,
} = tmpl;
let name = self.next_body_template_name();
@@ -71,18 +67,19 @@ impl TemplateEngine for Handlebars {
const ERR_BAD_MEDIA_TYPE_DETECTION: &str =
"handlebars requires html/txt file extension or media type given in template spec";
- let media_type =
- if let Some(media_type) = media_type {
- media_type
- } else if let Some(extension) = path.extension().and_then(|osstr| osstr.to_str()) {
- match extension {
- "html" => "text/html; charset=utf-8".parse().unwrap(),
- "txt" => "text/plain; charset=utf-8".parse().unwrap(),
- _ => { return Err(failure::err_msg(ERR_BAD_MEDIA_TYPE_DETECTION)); }
+ let media_type = if let Some(media_type) = media_type {
+ media_type
+ } else if let Some(extension) = path.extension().and_then(|osstr| osstr.to_str()) {
+ match extension {
+ "html" => "text/html; charset=utf-8".parse().unwrap(),
+ "txt" => "text/plain; charset=utf-8".parse().unwrap(),
+ _ => {
+ return Err(failure::err_msg(ERR_BAD_MEDIA_TYPE_DETECTION));
}
- } else {
- return Err(failure::err_msg(ERR_BAD_MEDIA_TYPE_DETECTION));
- };
+ }
+ } else {
+ return Err(failure::err_msg(ERR_BAD_MEDIA_TYPE_DETECTION));
+ };
Ok(BodyTemplate {
template_id: name,
@@ -91,9 +88,7 @@ impl TemplateEngine for Handlebars {
})
}
- fn load_subject_template(&mut self, template_string: String)
- -> Result<Self::Id, Error>
- {
+ fn load_subject_template(&mut self, template_string: String) -> Result<Self::Id, Error> {
let id = "subject".to_owned();
self.inner.register_template_string(&id, template_string)?;
Ok(id)
@@ -105,20 +100,27 @@ impl TemplateEngine for Handlebars {
/// 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
+where
+ D: Serialize,
{
fn render<'r, 'a>(
&'r self,
id: &'r Self::Id,
data: &'r D,
- additional_cids: AdditionalCIds<'r>
+ additional_cids: AdditionalCIds<'r>,
) -> Result<String, Error> {
- Ok(self.inner.render(id, &SerHelper { data, cids: additional_cids })?)
+ Ok(self.inner.render(
+ id,
+ &SerHelper {
+ data,
+ cids: additional_cids,
+ },
+ )?)
}
}
#[derive(Serialize)]
struct SerHelper<'r, D: 'r> {
data: &'r D,
- cids: AdditionalCIds<'r>
-} \ No newline at end of file
+ cids: AdditionalCIds<'r>,
+}
diff --git a/template/src/lib.rs b/template/src/lib.rs
index be3ce45..f0763fa 100644
--- a/template/src/lib.rs
+++ b/template/src/lib.rs
@@ -1,63 +1,52 @@
extern crate failure;
-extern crate serde;
extern crate futures;
+#[cfg(feature = "handlebars")]
+extern crate handlebars as hbs;
extern crate mail_core;
extern crate mail_headers;
-extern crate vec1;
-extern crate toml;
extern crate maybe_owned;
-#[cfg(feature="handlebars")]
-extern crate handlebars as hbs;
+extern crate serde;
+extern crate toml;
+extern crate vec1;
-#[cfg(all(feature="handlebars", not(feature="handlebars-bindings")))]
+#[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,
fmt::Debug,
+ fs,
+ ops::Deref,
path::{Path, PathBuf},
- ops::Deref
};
-use serde::{
- Serialize,
- Deserialize
-};
use failure::Error;
use futures::{
- Future, Poll, Async,
- try_ready,
- future::{self, Join, Either}
+ future::{self, Either, Join},
+ try_ready, Async, Future, Poll,
};
-use vec1::Vec1;
use maybe_owned::MaybeOwned;
+use serde::{Deserialize, Serialize};
+use vec1::Vec1;
use mail_core::{
- Resource,
- Data, Metadata,
- Context, ResourceContainerLoadingFuture,
- compose::{MailParts, BodyPart},
- Mail
-};
-use mail_headers::{
- HeaderKind, Header,
- header_components::MediaType,
- headers
+ compose::{BodyPart, MailParts},
+ Context, Data, Mail, Metadata, Resource, ResourceContainerLoadingFuture,
};
+use mail_headers::{header_components::MediaType, headers, Header, HeaderKind};
+mod additional_cid;
mod base_dir;
+pub mod error;
mod path_rebase;
-mod additional_cid;
pub mod serde_impl;
-pub mod error;
-#[cfg(feature="handlebars")]
+#[cfg(feature = "handlebars")]
pub mod handlebars;
+pub use self::additional_cid::*;
pub use self::base_dir::*;
pub use self::path_rebase::*;
-pub use self::additional_cid::*;
/// Trait used to bind/implement template engines.
pub trait TemplateEngine: Sized {
@@ -65,11 +54,12 @@ pub trait TemplateEngine: Sized {
type LazyBodyTemplate: PathRebaseable + Debug + Send + Serialize + for<'a> Deserialize<'a>;
- fn load_body_template(&mut self, tmpl: Self::LazyBodyTemplate)
- -> Result<BodyTemplate<Self>, Error>;
+ fn load_body_template(
+ &mut self,
+ tmpl: Self::LazyBodyTemplate,
+ ) -> Result<BodyTemplate<Self>, Error>;
- fn load_subject_template(&mut self, template_string: String)
- -> Result<Self::Id, Error>;
+ fn load_subject_template(&mut self, template_string: String) -> Result<Self::Id, Error>;
}
/// Additional trait a template engine needs to implement for the types it can process as input.
@@ -77,12 +67,11 @@ pub trait TemplateEngine: Sized {
/// This could for example be implemented in a wild card impl for the template engine for
/// any data `D` which implements `Serialize`.
pub trait TemplateEngineCanHandleData<D>: TemplateEngine {
-
fn render<'r, 'a>(
&'r self,
id: &'r Self::Id,
data: &'r D,
- additional_cids: AdditionalCIds<'r>
+ additional_cids: AdditionalCIds<'r>,
) -> Result<String, Error>;
}
@@ -93,45 +82,48 @@ pub trait TemplateEngineCanHandleData<D>: TemplateEngine {
pub fn load_toml_template_from_path<TE, C>(
engine: TE,
path: PathBuf,
- ctx: &C
-) -> impl Future<Item=Template<TE>, Error=Error>
- where TE: TemplateEngine + 'static, C: Context
+ ctx: &C,
+) -> impl Future<Item = Template<TE>, Error = Error>
+where
+ TE: TemplateEngine + 'static,
+ C: Context,
{
-
let ctx2 = ctx.clone();
ctx.offload_fn(move || {
let content = fs::read_to_string(&path)?;
let base: serde_impl::TemplateBase<TE> = toml::from_str(&content)?;
- let base_dir = path.parent().unwrap_or_else(||Path::new("."));
+ let base_dir = path.parent().unwrap_or_else(|| Path::new("."));
let base_dir = CwdBaseDir::from_path(base_dir)?;
Ok((base, base_dir))
- }).and_then(move |(base, base_dir)| base.load(engine, base_dir, &ctx2))
+ })
+ .and_then(move |(base, base_dir)| base.load(engine, base_dir, &ctx2))
}
/// Load a template as described in a toml string;
pub fn load_toml_template_from_str<TE, C>(
engine: TE,
content: &str,
- ctx: &C
-) -> impl Future<Item=Template<TE>, Error=Error>
- where TE: TemplateEngine, C: Context
+ ctx: &C,
+) -> impl Future<Item = Template<TE>, Error = Error>
+where
+ TE: TemplateEngine,
+ C: Context,
{
- let base: serde_impl::TemplateBase<TE> =
- match toml::from_str(content) {
- Ok(base) => base,
- Err(err) => { return Either::B(future::err(Error::from(err))); }
- };
+ let base: serde_impl::TemplateBase<TE> = match toml::from_str(content) {
+ Ok(base) => base,
+ Err(err) => {
+ return Either::B(future::err(Error::from(err)));
+ }
+ };
- let base_dir =
- match CwdBaseDir::from_path(Path::new(".")) {
- Ok(base_dir) => base_dir,
- Err(err) => { return Either::B(future::err(Error::from(err))) }
- };
+ let base_dir = match CwdBaseDir::from_path(Path::new(".")) {
+ Ok(base_dir) => base_dir,
+ Err(err) => return Either::B(future::err(Error::from(err))),
+ };
Either::A(base.load(engine, base_dir, ctx))
}
-
/// A Mail template.
#[derive(Debug)]
pub struct Template<TE: TemplateEngine> {
@@ -149,7 +141,8 @@ pub struct Template<TE: TemplateEngine> {
}
impl<TE> Template<TE>
- where TE: TemplateEngine
+where
+ TE: TemplateEngine,
{
pub fn inline_embeddings(&self) -> &HashMap<String, Resource> {
&self.embeddings
@@ -172,17 +165,17 @@ impl<TE> Template<TE>
}
}
-
/// Represents one of potentially many alternate bodies in a template.
#[derive(Debug)]
pub struct BodyTemplate<TE: TemplateEngine> {
pub template_id: TE::Id,
pub media_type: MediaType,
- pub inline_embeddings: HashMap<String, Resource>
+ pub inline_embeddings: HashMap<String, Resource>,
}
impl<TE> BodyTemplate<TE>
- where TE: TemplateEngine
+where
+ TE: TemplateEngine,
{
pub fn template_id(&self) -> &TE::Id {
&self.template_id
@@ -200,11 +193,12 @@ impl<TE> BodyTemplate<TE>
/// Represents a template used for generating the subject of a mail.
#[derive(Debug)]
pub struct Subject<TE: TemplateEngine> {
- template_id: TE::Id
+ template_id: TE::Id,
}
impl<TE> Subject<TE>
- where TE: TemplateEngine
+where
+ TE: TemplateEngine,
{
pub fn template_id(&self) -> &TE::Id {
&self.template_id
@@ -218,13 +212,20 @@ impl<TE> Subject<TE>
///
/// This trait should not be implemented by hand.
pub trait TemplateExt<TE, D>
- where TE: TemplateEngine + TemplateEngineCanHandleData<D>
+where
+ TE: TemplateEngine + TemplateEngineCanHandleData<D>,
{
-
- fn render_to_mail_parts<'r>(&self, data: LoadedTemplateData<'r, D>, ctx: &impl Context)
- -> Result<(MailParts, Header<headers::Subject>), Error>;
-
- fn render<'r>(&self, data: LoadedTemplateData<'r, D>, ctx: &impl Context) -> Result<Mail, Error> {
+ fn render_to_mail_parts<'r>(
+ &self,
+ data: LoadedTemplateData<'r, D>,
+ ctx: &impl Context,
+ ) -> Result<(MailParts, Header<headers::Subject>), Error>;
+
+ fn render<'r>(
+ &self,
+ data: LoadedTemplateData<'r, D>,
+ ctx: &impl Context,
+ ) -> Result<Mail, Error> {
let (parts, subject) = self.render_to_mail_parts(data, ctx)?;
let mut mail = parts.compose();
mail.insert_header(subject);
@@ -232,24 +233,24 @@ pub trait TemplateExt<TE, D>
}
}
-
impl<TE, D> TemplateExt<TE, D> for Template<TE>
- where TE: TemplateEngine + TemplateEngineCanHandleData<D>
+where
+ TE: TemplateEngine + TemplateEngineCanHandleData<D>,
{
- fn render_to_mail_parts<'r>(&self, data: LoadedTemplateData<'r, D>, ctx: &impl Context)
- -> Result<(MailParts, Header<headers::Subject>), Error>
- {
+ fn render_to_mail_parts<'r>(
+ &self,
+ data: LoadedTemplateData<'r, D>,
+ ctx: &impl Context,
+ ) -> Result<(MailParts, Header<headers::Subject>), Error> {
let TemplateData {
data,
inline_embeddings,
- mut attachments
+ mut attachments,
} = data.into();
- let subject = self.engine().render(
- self.subject_template_id(),
- &data,
- AdditionalCIds::new(&[])
- )?;
+ let subject =
+ self.engine()
+ .render(self.subject_template_id(), &data, AdditionalCIds::new(&[]))?;
let subject = headers::Subject::auto_body(subject)?;
@@ -262,8 +263,8 @@ impl<TE, D> TemplateExt<TE, D> for Template<TE>
AdditionalCIds::new(&[
&inline_embeddings,
body.inline_embeddings(),
- self.inline_embeddings()
- ])
+ self.inline_embeddings(),
+ ]),
)?;
let data = Data::new(
@@ -271,19 +272,16 @@ impl<TE, D> TemplateExt<TE, D> for Template<TE>
Metadata {
file_meta: Default::default(),
media_type: body.media_type().clone(),
- content_id: ctx.generate_content_id()
- }
+ content_id: ctx.generate_content_id(),
+ },
);
- let inline_embeddings = body.inline_embeddings()
- .values()
- .cloned()
- .collect();
+ let inline_embeddings = body.inline_embeddings().values().cloned().collect();
bodies.push(BodyPart {
resource: Resource::Data(data),
inline_embeddings,
- attachments: Vec::new()
+ attachments: Vec::new(),
});
}
@@ -296,13 +294,13 @@ impl<TE, D> TemplateExt<TE, D> for Template<TE>
}
}
- inline_embeddings_vec.extend(inline_embeddings.into_iter().map(|(_,v)|v));
+ inline_embeddings_vec.extend(inline_embeddings.into_iter().map(|(_, v)| v));
let parts = MailParts {
//UNWRAP_SAFE (complexly mapping a Vec1 is safe)
alternative_bodies: Vec1::try_from_vec(bodies).unwrap(),
inline_embeddings: inline_embeddings_vec,
- attachments
+ attachments,
};
Ok((parts, subject))
@@ -310,18 +308,17 @@ impl<TE, D> TemplateExt<TE, D> for Template<TE>
}
pub struct TemplateData<'a, D: 'a> {
- pub data: MaybeOwned<'a, D>,
+ pub data: MaybeOwned<'a, D>,
pub attachments: Vec<Resource>,
- pub inline_embeddings: HashMap<String, Resource>
+ pub inline_embeddings: HashMap<String, Resource>,
}
impl<'a, D> TemplateData<'a, D> {
-
pub fn load(self, ctx: &impl Context) -> DataLoadingFuture<'a, D> {
let TemplateData {
data,
attachments,
- inline_embeddings
+ inline_embeddings,
} = self;
let loading_fut = Resource::load_container(inline_embeddings, ctx)
@@ -329,7 +326,7 @@ impl<'a, D> TemplateData<'a, D> {
DataLoadingFuture {
payload: Some(data),
- loading_fut
+ loading_fut,
}
}
}
@@ -338,7 +335,7 @@ impl<D> From<D> for TemplateData<'static, D> {
TemplateData {
data: data.into(),
attachments: Default::default(),
- inline_embeddings: Default::default()
+ inline_embeddings: Default::default(),
}
}
}
@@ -348,7 +345,7 @@ impl<'a, D> From<&'a D> for TemplateData<'a, D> {
TemplateData {
data: data.into(),
attachments: Default::default(),
- inline_embeddings: Default::default()
+ inline_embeddings: Default::default(),
}
}
}
@@ -387,8 +384,8 @@ pub struct DataLoadingFuture<'a, D: 'a> {
payload: Option<MaybeOwned<'a, D>>,
loading_fut: Join<
ResourceContainerLoadingFuture<HashMap<String, Resource>>,
- ResourceContainerLoadingFuture<Vec<Resource>>
- >
+ ResourceContainerLoadingFuture<Vec<Resource>>,
+ >,
}
impl<'a, D> Future for DataLoadingFuture<'a, D> {
@@ -396,10 +393,7 @@ impl<'a, D> Future for DataLoadingFuture<'a, D> {
type Error = Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
- let (
- inline_embeddings,
- attachments
- ) = try_ready!(self.loading_fut.poll());
+ let (inline_embeddings, attachments) = try_ready!(self.loading_fut.poll());
//UNWRAP_SAFE only non if polled after resolved
let data = self.payload.take().unwrap();
@@ -407,7 +401,7 @@ impl<'a, D> Future for DataLoadingFuture<'a, D> {
let inner = TemplateData {
data,
inline_embeddings,
- attachments
+ attachments,
};
Ok(Async::Ready(LoadedTemplateData(inner)))
diff --git a/template/src/path_rebase.rs b/template/src/path_rebase.rs
index 9818aa3..3a64198 100644
--- a/template/src/path_rebase.rs
+++ b/template/src/path_rebase.rs
@@ -1,13 +1,16 @@
use std::{
+ mem,
path::{Path, PathBuf},
- mem
};
-use mail_core::{IRI, Resource};
-use failure::{Fail, Context};
+use failure::{Context, Fail};
+use mail_core::{Resource, IRI};
#[derive(Fail, Debug)]
-#[fail(display = "unsupported path, only paths with following constraint are allowed: {}", _0)]
+#[fail(
+ display = "unsupported path, only paths with following constraint are allowed: {}",
+ _0
+)]
pub struct UnsupportedPathError(Context<&'static str>);
impl UnsupportedPathError {
@@ -25,8 +28,10 @@ pub trait PathRebaseable {
/// For example a implementor requiring rust string
/// compatible paths might return a
/// `Err(UnsupportedPathError::new("utf-8"))`.
- fn rebase_to_include_base_dir(&mut self, base_dir: impl AsRef<Path>)
- -> Result<(), UnsupportedPathError>;
+ fn rebase_to_include_base_dir(
+ &mut self,
+ base_dir: impl AsRef<Path>,
+ ) -> Result<(), UnsupportedPathError>;
/// Removes the `base_dir` prefix.
///
@@ -36,14 +41,17 @@ pub trait PathRebaseable {
/// For example a implementor requiring rust string
/// compatible paths might return a
/// `Err(UnsupportedPathError::new("utf-8"))`.
- fn rebase_to_exclude_base_dir(&mut self, base_dir: impl AsRef<Path>)
- -> Result<(), UnsupportedPathError>;
+ fn rebase_to_exclude_base_dir(
+ &mut self,
+ base_dir: impl AsRef<Path>,
+ ) -> Result<(), UnsupportedPathError>;
}
impl PathRebaseable for PathBuf {
- fn rebase_to_include_base_dir(&mut self, base_dir: impl AsRef<Path>)
- -> Result<(), UnsupportedPathError>
- {
+ fn rebase_to_include_base_dir(
+ &mut self,
+ base_dir: impl AsRef<Path>,
+ ) -> Result<(), UnsupportedPathError> {
let new_path;
if self.is_relative() {
new_path = base_dir.as_ref().join(&self);
@@ -54,9 +62,10 @@ impl PathRebaseable for PathBuf {
Ok(())
}
- fn rebase_to_exclude_base_dir(&mut self, base_dir: impl AsRef<Path>)
- -> Result<(), UnsupportedPathError>
- {
+ fn rebase_to_exclude_base_dir(
+ &mut self,
+ base_dir: impl AsRef<Path>,
+ ) -> Result<(), UnsupportedPathError> {
let new_path;
if let Ok(path) = self.strip_prefix(base_dir) {
new_path = path.to_owned();
@@ -69,9 +78,10 @@ impl PathRebaseable for PathBuf {
}
impl PathRebaseable for IRI {
- fn rebase_to_include_base_dir(&mut self, base_dir: impl AsRef<Path>)
- -> Result<(), UnsupportedPathError>
- {
+ fn rebase_to_include_base_dir(
+ &mut self,
+ base_dir: impl AsRef<Path>,
+ ) -> Result<(), UnsupportedPathError> {
if self.scheme() != "path" {
return Ok(());
}
@@ -85,7 +95,8 @@ impl PathRebaseable for IRI {
}
};
- let new_tail = new_tail.to_str()
+ let new_tail = new_tail
+ .to_str()
.ok_or_else(|| UnsupportedPathError::new("utf-8"))?;
let new_iri = self.with_tail(new_tail);
@@ -93,9 +104,10 @@ impl PathRebaseable for IRI {
Ok(())
}
- fn rebase_to_exclude_base_dir(&mut self, base_dir: impl AsRef<Path>)
- -> Result<(), UnsupportedPathError>
- {
+ fn rebase_to_exclude_base_dir(
+ &mut self,
+ base_dir: impl AsRef<Path>,
+ ) -> Result<(), UnsupportedPathError> {
if self.scheme() != "path" {
return Ok(());
}
@@ -119,28 +131,27 @@ impl PathRebaseable for IRI {
}
impl PathRebaseable for Resource {
- fn rebase_to_include_base_dir(&mut self, base_dir: impl AsRef<Path>)
- -> Result<(), UnsupportedPathError>
- {
+ fn rebase_to_include_base_dir(
+ &mut self,
+ base_dir: impl AsRef<Path>,
+ ) -> Result<(), UnsupportedPathError> {
if let &mut Resource::Source(ref mut source) = self {
source.iri.rebase_to_include_base_dir(base_dir)?;
}
Ok(())
}
- fn rebase_to_exclude_base_dir(&mut self, base_dir: impl AsRef<Path>)
- -> Result<(), UnsupportedPathError>
- {
+ fn rebase_to_exclude_base_dir(
+ &mut self,
+ base_dir: impl AsRef<Path>,
+ ) -> Result<(), UnsupportedPathError> {
if let &mut Resource::Source(ref mut source) = self {
source.iri.rebase_to_exclude_base_dir(base_dir)?;
}
Ok(())
}
-
}
-
-
#[cfg(test)]
mod test {
use super::*;
@@ -175,7 +186,7 @@ mod test {
let mut resource = Resource::Source(Source {
iri: "path:abc/def".parse().unwrap(),
use_media_type: Default::default(),
- use_file_name: Default::default()
+ use_file_name: Default::default(),
});
resource.rebase_to_include_base_dir("./abc").unwrap();
@@ -184,8 +195,10 @@ mod test {
resource.rebase_to_exclude_base_dir("abc").unwrap();
resource.rebase_to_include_base_dir("abc").unwrap();
- if let Resource::Source(Source { iri, ..}) = resource {
+ if let Resource::Source(Source { iri, .. }) = resource {
assert_eq!(iri.as_str(), "path:abc/abc/def");
- } else { unreachable!() }
+ } else {
+ unreachable!()
+ }
}
-} \ No newline at end of file
+}
diff --git a/template/src/serde_impl.rs b/template/src/serde_impl.rs
index f8e7021..444def2 100644
--- a/template/src/serde_impl.rs
+++ b/template/src/serde_impl.rs
@@ -1,28 +1,21 @@
use std::{
collections::HashMap,
+ mem,
path::{Path, PathBuf},
- mem
};
-use serde::{
- Serialize, Deserialize,
- Serializer, Deserializer
-};
use failure::Error;
-use futures::{Future, future::{self, Either}};
+use futures::{
+ future::{self, Either},
+ Future,
+};
+use serde::{Deserialize, Deserializer, Serialize, Serializer};
use vec1::Vec1;
-use mail_core::{Resource, Source, IRI, Context};
+use mail_core::{Context, Resource, Source, IRI};
use mail_headers::header_components::MediaType;
-use super::{
- Template,
- TemplateEngine,
- CwdBaseDir,
- PathRebaseable,
- Subject,
- UnsupportedPathError,
-};
+use super::{CwdBaseDir, PathRebaseable, Subject, Template, TemplateEngine, UnsupportedPathError};
/// Type used when deserializing a template using serde.
///
@@ -45,41 +38,48 @@ use super::{
/// content as the iris "tail".
#[derive(Debug, Serialize, Deserialize)]
pub struct TemplateBase<TE: TemplateEngine> {
- #[serde(rename="name")]
+ #[serde(rename = "name")]
template_name: String,
#[serde(default)]
base_dir: Option<CwdBaseDir>,
subject: LazySubject,
bodies: Vec1<TE::LazyBodyTemplate>,
#[serde(default)]
- #[serde(deserialize_with="deserialize_embeddings")]
+ #[serde(deserialize_with = "deserialize_embeddings")]
embeddings: HashMap<String, Resource>,
#[serde(default)]
- #[serde(deserialize_with="deserialize_attachments")]
+ #[serde(deserialize_with = "deserialize_attachments")]
attachments: Vec<Resource>,
}
impl<TE> TemplateBase<TE>
- where TE: TemplateEngine
+where
+ TE: TemplateEngine,
{
-
//TODO!! make this load all embeddings/attachments and make it a future
/// 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> {
+ 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,