diff options
Diffstat (limited to 'template/src')
-rw-r--r-- | template/src/additional_cid.rs | 37 | ||||
-rw-r--r-- | template/src/base_dir.rs | 46 | ||||
-rw-r--r-- | template/src/error.rs | 2 | ||||
-rw-r--r-- | template/src/handlebars.rs | 70 | ||||
-rw-r--r-- | template/src/lib.rs | 202 | ||||
-rw-r--r-- | template/src/path_rebase.rs | 81 | ||||
-rw-r--r-- | template/src/serde_impl.rs | 197 |
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, |