diff options
Diffstat (limited to 'template/src/serde_impl.rs')
-rw-r--r-- | template/src/serde_impl.rs | 197 |
1 files changed, 103 insertions, 94 deletions
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, base_dir, subject, bodies, mut embeddings, - mut attachments + mut attachments, } = self; let base_dir = base_dir.unwrap_or(default_base_dir); //FIXME[rust/catch block] use catch block let catch_res = (|| -> Result<_, Error> { - let subject = Subject{ template_id: engine.load_subject_template(subject.template_string)? }; + let subject = Subject { + template_id: engine.load_subject_template(subject.template_string)?, + }; let bodies = bodies.try_mapped(|mut lazy_body| -> Result<_, Error> { lazy_body.rebase_to_include_base_dir(&base_dir)?; @@ -97,15 +97,17 @@ impl<TE> TemplateBase<TE> Ok((subject, bodies)) })(); - let (subject, mut bodies) = - match catch_res { - Ok(vals) => vals, - Err(err) => { return Either::B(future::err(err)); } - }; + let (subject, mut bodies) = match catch_res { + Ok(vals) => vals, + Err(err) => { + return Either::B(future::err(err)); + } + }; let loading_embeddings = Resource::load_container(embeddings, ctx); let loading_attachments = Resource::load_container(attachments, ctx); - let loading_body_embeddings = bodies.iter_mut() + 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()); @@ -114,7 +116,6 @@ impl<TE> TemplateBase<TE> .collect::<Vec<_>>(); let loading_body_embeddings = future::join_all(loading_body_embeddings); - let fut = loading_embeddings .join3(loading_attachments, loading_body_embeddings) .map_err(Error::from) @@ -129,7 +130,7 @@ impl<TE> TemplateBase<TE> bodies, embeddings, attachments, - engine + engine, } }); @@ -139,22 +140,22 @@ impl<TE> TemplateBase<TE> #[derive(Debug)] struct LazySubject { - template_string: String + template_string: String, } impl Serialize for LazySubject { - fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> - where S: Serializer + 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> + where + D: Deserializer<'de>, { let template_string = String::deserialize(deserializer)?; Ok(LazySubject { template_string }) @@ -170,7 +171,7 @@ enum ResourceDeserializationHelper { // 3. as String which is interpreted as path iri Normal(Resource), FromSource(Source), - FromString(String) + FromString(String), } impl Into<Resource> for ResourceDeserializationHelper { @@ -184,42 +185,41 @@ impl Into<Resource> for ResourceDeserializationHelper { // but its static "path" which is known to be valid iri: IRI::from_parts("path", &string).unwrap(), use_media_type: Default::default(), - use_file_name: Default::default() + use_file_name: Default::default(), }; Resource::Source(source) - }, - FromSource(source) => Resource::Source(source) + } + FromSource(source) => Resource::Source(source), } } } -pub fn deserialize_embeddings<'de, D>(deserializer: D) - -> Result<HashMap<String, Resource>, D::Error> - where D: Deserializer<'de> +pub fn deserialize_embeddings<'de, D>( + deserializer: D, +) -> Result<HashMap<String, Resource>, D::Error> +where + D: Deserializer<'de>, { //FIXME[perf] write custom visitor etc. - let map = <HashMap<String, ResourceDeserializationHelper>> - ::deserialize(deserializer)?; + let map = <HashMap<String, ResourceDeserializationHelper>>::deserialize(deserializer)?; - let map = map.into_iter() + let map = map + .into_iter() .map(|(k, helper)| (k, helper.into())) .collect(); Ok(map) } -pub fn deserialize_attachments<'de, D>(deserializer: D) - -> Result<Vec<Resource>, D::Error> - where D: Deserializer<'de> +pub fn deserialize_attachments<'de, D>(deserializer: D) -> Result<Vec<Resource>, D::Error> +where + D: Deserializer<'de>, { //FIXME[perf] write custom visitor etc. - let vec = <Vec<ResourceDeserializationHelper>> - ::deserialize(deserializer)?; + let vec = <Vec<ResourceDeserializationHelper>>::deserialize(deserializer)?; - let vec = vec.into_iter() - .map(|helper| helper.into()) - .collect(); + let vec = vec.into_iter().map(|helper| helper.into()).collect(); Ok(vec) } @@ -236,14 +236,14 @@ pub fn deserialize_attachments<'de, D>(deserializer: D) pub struct StandardLazyBodyTemplate { pub path: PathBuf, pub embeddings: HashMap<String, Resource>, - pub media_type: Option<MediaType> + pub media_type: Option<MediaType>, } - impl PathRebaseable for StandardLazyBodyTemplate { - 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 base_dir = base_dir.as_ref(); self.path.rebase_to_include_base_dir(base_dir)?; for embedding in self.embeddings.values_mut() { @@ -252,9 +252,10 @@ impl PathRebaseable for StandardLazyBodyTemplate { 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 base_dir = base_dir.as_ref(); self.path.rebase_to_exclude_base_dir(base_dir)?; for embedding in self.embeddings.values_mut() { @@ -264,7 +265,6 @@ impl PathRebaseable for StandardLazyBodyTemplate { } } - #[derive(Deserialize)] #[serde(untagged)] enum StandardLazyBodyTemplateDeserializationHelper { @@ -272,60 +272,66 @@ enum StandardLazyBodyTemplateDeserializationHelper { LongForm { path: PathBuf, #[serde(default)] - #[serde(deserialize_with="deserialize_embeddings")] + #[serde(deserialize_with = "deserialize_embeddings")] embeddings: HashMap<String, Resource>, #[serde(default)] - media_type: Option<MediaType> - } + media_type: Option<MediaType>, + }, } impl<'de> Deserialize<'de> for StandardLazyBodyTemplate { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> - where D: Deserializer<'de> + where + D: Deserializer<'de>, { use self::StandardLazyBodyTemplateDeserializationHelper::*; let helper = StandardLazyBodyTemplateDeserializationHelper::deserialize(deserializer)?; - let ok_val = - match helper { - ShortForm(string) => { - StandardLazyBodyTemplate { - path: string.into(), - embeddings: Default::default(), - media_type: Default::default() - } - }, - LongForm {path, embeddings, media_type} => - StandardLazyBodyTemplate { path, embeddings, media_type } - }; + let ok_val = match helper { + ShortForm(string) => StandardLazyBodyTemplate { + path: string.into(), + embeddings: Default::default(), + media_type: Default::default(), + }, + LongForm { + path, + embeddings, + media_type, + } => StandardLazyBodyTemplate { + path, + embeddings, + media_type, + }, + }; Ok(ok_val) } } - #[cfg(test)] mod test { - use toml; use super::*; + use toml; fn test_source_iri(resource: &Resource, iri: &str) { if let &Resource::Source(ref source) = resource { assert_eq!(source.iri.as_str(), iri); } else { - panic!("unexpected resource expected resource with source and iri {:?} but got {:?}", iri, resource); + panic!( + "unexpected resource expected resource with source and iri {:?} but got {:?}", + iri, resource + ); } } mod attachment_deserialization { - use super::*; use super::super::deserialize_attachments; + use super::*; #[derive(Serialize, Deserialize)] struct Wrapper { - #[serde(deserialize_with="deserialize_attachments")] - attachments: Vec<Resource> + #[serde(deserialize_with = "deserialize_attachments")] + attachments: Vec<Resource>, } - #[test] fn should_deserialize_from_strings() { let raw_toml = r#" @@ -388,13 +394,13 @@ mod test { } mod embedding_deserialization { - use super::*; use super::super::deserialize_embeddings; + use super::*; #[derive(Serialize, Deserialize)] struct Wrapper { - #[serde(deserialize_with="deserialize_embeddings")] - embeddings: HashMap<String, Resource> + #[serde(deserialize_with = "deserialize_embeddings")] + embeddings: HashMap<String, Resource>, } #[test] @@ -421,18 +427,21 @@ mod test { test_source_iri(&embeddings["pic"], "path:hy-ya"); test_source_iri(&embeddings["pic2"], "path:ay-ya"); test_source_iri(&embeddings["pic4"], "path:nay-nay-way"); - assert_eq!(embeddings["pic3"].content_id().unwrap().as_str(), "c0rc3rcr0q0v32@example.example"); + assert_eq!( + embeddings["pic3"].content_id().unwrap().as_str(), + "c0rc3rcr0q0v32@example.example" + ); } } #[allow(non_snake_case)] mod StandardLazyBodyTemplate { - use super::*; use super::super::StandardLazyBodyTemplate; + use super::*; #[derive(Serialize, Deserialize)] struct Wrapper { - body: StandardLazyBodyTemplate + body: StandardLazyBodyTemplate, } #[test] @@ -452,7 +461,7 @@ mod test { body = { path="t.d" } "#; - let Wrapper { body }= toml::from_str(toml_str).unwrap(); + let Wrapper { body } = toml::from_str(toml_str).unwrap(); assert_eq!(body.path.to_str().unwrap(), "t.d"); assert_eq!(body.embeddings.len(), 0); } @@ -484,4 +493,4 @@ mod test { test_source_iri(resource, "path:the_embeddings"); } } -}
\ No newline at end of file +} |