From 726a74e41cc03b8d24af9024cdc6c46905c5f4ea Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 9 Aug 2016 15:25:10 +0200 Subject: [PATCH 01/19] Initial import --- libimagmail/Cargo.toml | 6 ++++++ libimagmail/src/lib.rs | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 libimagmail/Cargo.toml create mode 100644 libimagmail/src/lib.rs diff --git a/libimagmail/Cargo.toml b/libimagmail/Cargo.toml new file mode 100644 index 00000000..1a3c5849 --- /dev/null +++ b/libimagmail/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "libimagmail" +version = "0.1.0" +authors = ["Matthias Beyer "] + +[dependencies] diff --git a/libimagmail/src/lib.rs b/libimagmail/src/lib.rs new file mode 100644 index 00000000..cdfbe1aa --- /dev/null +++ b/libimagmail/src/lib.rs @@ -0,0 +1,6 @@ +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + } +} From b53f12c0a6f9e98aa77684f4e4ad01cbf68476f1 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 9 Aug 2016 15:38:27 +0200 Subject: [PATCH 02/19] Add dependencies --- libimagmail/Cargo.toml | 13 ++++++++++++- libimagmail/src/lib.rs | 18 ++++++++++++------ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/libimagmail/Cargo.toml b/libimagmail/Cargo.toml index 1a3c5849..de9fbe64 100644 --- a/libimagmail/Cargo.toml +++ b/libimagmail/Cargo.toml @@ -1,6 +1,17 @@ [package] name = "libimagmail" -version = "0.1.0" +version = "0.2.0" authors = ["Matthias Beyer "] [dependencies] +log = "0.3" +mailparse = "0.2.0" +semver = "0.2" +toml = "0.2.*" + +[dependencies.libimagstore] +path = "../libimagstore" + +[dependencies.libimagerror] +path = "../libimagerror" + diff --git a/libimagmail/src/lib.rs b/libimagmail/src/lib.rs index cdfbe1aa..3629c24e 100644 --- a/libimagmail/src/lib.rs +++ b/libimagmail/src/lib.rs @@ -1,6 +1,12 @@ -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - } -} +#[macro_use] extern crate log; +extern crate mailparse; +extern crate semver; +extern crate toml; + +#[macro_use] extern crate libimagerror; +extern crate libimagstore; + +pub mod mail; +pub mod error; +pub mod result; + From 50fbc3898453257a82447d9e5a0f8e33feb42ef0 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 9 Aug 2016 15:38:35 +0200 Subject: [PATCH 03/19] Initial import of codebase --- libimagmail/src/error.rs | 10 ++++++++ libimagmail/src/mail.rs | 52 +++++++++++++++++++++++++++++++++++++++ libimagmail/src/result.rs | 6 +++++ 3 files changed, 68 insertions(+) create mode 100644 libimagmail/src/error.rs create mode 100644 libimagmail/src/mail.rs create mode 100644 libimagmail/src/result.rs diff --git a/libimagmail/src/error.rs b/libimagmail/src/error.rs new file mode 100644 index 00000000..6e3df32b --- /dev/null +++ b/libimagmail/src/error.rs @@ -0,0 +1,10 @@ +generate_error_module!( + generate_error_types!(MailError, MailErrorKind, + IOError => "IO Error" + ); +); + +pub use self::error::MailError; +pub use self::error::MailErrorKind; +pub use self::error::MapErrInto; + diff --git a/libimagmail/src/mail.rs b/libimagmail/src/mail.rs new file mode 100644 index 00000000..2fde3547 --- /dev/null +++ b/libimagmail/src/mail.rs @@ -0,0 +1,52 @@ +use std::result::Result as RResult; +use std::path::Path; + +use libimagstore::store::{FileLockEntry, Store}; + +pub struct Mail<'a> { + fle: FileLockEntry<'a>, + parsedmail: ParsedMail, +} + +impl<'a> Mail<'a> { + + /// Imports a mail from the Path passed + pub fn import_from_path>(store: &Store, p: P) -> Result { + unimplemented!() + } + + /// Imports a mail from the String passed + pub fn import_from_string>(store: &Store, s: S) -> Result { + unimplemented!() + } + + /// Opens a mail by the passed hash + pub fn open>(store: &Store, hash: S) -> Result> { + unimplemented!() + } + + pub fn get_field>(&self, field: S) -> Result> { + unimplemented!() + } + + pub fn get_from(&self) -> Result> { + unimplemented!() + } + + pub fn get_to(&self) -> Result> { + unimplemented!() + } + + pub fn get_subject(&self) -> Result> { + unimplemented!() + } + + pub fn get_message_id(&self) -> Result> { + unimplemented!() + } + + pub fn get_in_reply_to(&self) -> Result> { + unimplemented!() + } + +} diff --git a/libimagmail/src/result.rs b/libimagmail/src/result.rs new file mode 100644 index 00000000..e7715513 --- /dev/null +++ b/libimagmail/src/result.rs @@ -0,0 +1,6 @@ +use std::result::Result as RResult; + +use error::MailError; + +pub type Result = RResult; + From 80a320d769611ca7da7da30f1c6640824ffb6172 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 21 Sep 2016 17:43:27 +0200 Subject: [PATCH 04/19] Add intermediate buffer type for abstracting away lifetime foo from mailparse --- libimagmail/src/mail.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/libimagmail/src/mail.rs b/libimagmail/src/mail.rs index 2fde3547..897fc37e 100644 --- a/libimagmail/src/mail.rs +++ b/libimagmail/src/mail.rs @@ -3,9 +3,27 @@ use std::path::Path; use libimagstore::store::{FileLockEntry, Store}; +use mailparse::{MailParseError, ParsedMail, parse_mail}; + +use result::Result; + +struct Buffer(String); + +impl Buffer { + pub fn parsed<'a>(&'a self) -> RResult, MailParseError> { + parse_mail(self.0.as_bytes()) + } +} + +impl From for Buffer { + fn from(data: String) -> Buffer { + Buffer(data) + } +} + pub struct Mail<'a> { fle: FileLockEntry<'a>, - parsedmail: ParsedMail, + buffer: Buffer, } impl<'a> Mail<'a> { From eec6ef0652451beee12725f29e2ff66d95714ee4 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 21 Sep 2016 18:03:07 +0200 Subject: [PATCH 05/19] Add agnostic "RefHashingError" to be used by implementors of Hasher. --- libimagref/src/error.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libimagref/src/error.rs b/libimagref/src/error.rs index b1e5e2c5..a133e8a5 100644 --- a/libimagref/src/error.rs +++ b/libimagref/src/error.rs @@ -41,7 +41,9 @@ generate_error_module!( RefTargetPermissionError => "Ref Target permissions insufficient for referencing", RefTargetCannotBeHashed => "Ref Target cannot be hashed (is it a directory?)", RefTargetFileCannotBeOpened => "Ref Target File cannot be open()ed", - RefTargetCannotReadPermissions => "Ref Target: Cannot read permissions" + RefTargetCannotReadPermissions => "Ref Target: Cannot read permissions", + + RefHashingError => "Error while hashing" ); ); From 3e63d65689a766337c52a27db85c3e92c74b1763 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 21 Sep 2016 18:05:12 +0200 Subject: [PATCH 06/19] Add dependency: filters = 0.1.0 --- libimagmail/Cargo.toml | 1 + libimagmail/src/lib.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/libimagmail/Cargo.toml b/libimagmail/Cargo.toml index de9fbe64..4494f32a 100644 --- a/libimagmail/Cargo.toml +++ b/libimagmail/Cargo.toml @@ -8,6 +8,7 @@ log = "0.3" mailparse = "0.2.0" semver = "0.2" toml = "0.2.*" +filters = "0.1.0" [dependencies.libimagstore] path = "../libimagstore" diff --git a/libimagmail/src/lib.rs b/libimagmail/src/lib.rs index 3629c24e..d21252eb 100644 --- a/libimagmail/src/lib.rs +++ b/libimagmail/src/lib.rs @@ -2,6 +2,7 @@ extern crate mailparse; extern crate semver; extern crate toml; +extern crate filters; #[macro_use] extern crate libimagerror; extern crate libimagstore; From 4d83ce8b6e235da674cced1bf258f9861a692176 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 21 Sep 2016 18:13:53 +0200 Subject: [PATCH 07/19] Add error kind if ref could not be created --- libimagmail/src/error.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/libimagmail/src/error.rs b/libimagmail/src/error.rs index 6e3df32b..cac14af1 100644 --- a/libimagmail/src/error.rs +++ b/libimagmail/src/error.rs @@ -1,5 +1,6 @@ generate_error_module!( generate_error_types!(MailError, MailErrorKind, + RefCreationError => "Error creating a reference to a file/directory", IOError => "IO Error" ); ); From 03ae71497046f915125806ce4fb9dd687c3836ac Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 21 Sep 2016 18:14:11 +0200 Subject: [PATCH 08/19] Add MailHasher --- libimagmail/src/error.rs | 1 + libimagmail/src/hasher.rs | 64 +++++++++++++++++++++++++++++++++++++++ libimagmail/src/lib.rs | 3 +- 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 libimagmail/src/hasher.rs diff --git a/libimagmail/src/error.rs b/libimagmail/src/error.rs index cac14af1..59664b66 100644 --- a/libimagmail/src/error.rs +++ b/libimagmail/src/error.rs @@ -1,6 +1,7 @@ generate_error_module!( generate_error_types!(MailError, MailErrorKind, RefCreationError => "Error creating a reference to a file/directory", + MailParsingError => "Error while parsing mail", IOError => "IO Error" ); ); diff --git a/libimagmail/src/hasher.rs b/libimagmail/src/hasher.rs new file mode 100644 index 00000000..f0ced139 --- /dev/null +++ b/libimagmail/src/hasher.rs @@ -0,0 +1,64 @@ +use std::io::Read; +use std::path::PathBuf; + +use mailparse::{MailHeader, parse_mail}; + +use libimagref::hasher::Hasher; +use libimagref::hasher::DefaultHasher; +use libimagref::error::RefErrorKind as REK; +use libimagref::error::MapErrInto; +use libimagref::result::Result as RResult; +use libimagerror::into::IntoError; + +use error::MailErrorKind as MEK; + +pub struct MailHasher { + defaulthasher: DefaultHasher, +} + +impl MailHasher { + + pub fn new() -> MailHasher { + MailHasher { defaulthasher: DefaultHasher::new() } + } + +} + +impl Hasher for MailHasher { + + fn hash_name(&self) -> &'static str { + "default_mail_hasher" + } + + fn create_hash(&mut self, pb: &PathBuf, c: &mut R) -> RResult { + use filters::filter::Filter; + + let mut s = String::new(); + try!(c.read_to_string(&mut s).map_err_into(REK::UTF8Error).map_err_into(REK::IOError)); + + parse_mail(&s.as_bytes()) + .map_err(Box::new) + .map_err(|e| MEK::MailParsingError.into_error_with_cause(e)) + .map_err_into(REK::RefHashingError) + .and_then(|mail| { + let has_key = |hdr: &MailHeader, exp: &str| + hdr.get_key().map(|s| s == exp).unwrap_or(false); + + let subject_filter = |hdr: &MailHeader| has_key(hdr, "Subject"); + let from_filter = |hdr: &MailHeader| has_key(hdr, "From"); + let to_filter = |hdr: &MailHeader| has_key(hdr, "To"); + + let filter = subject_filter.or(from_filter).or(to_filter); + + let s : String = mail.headers + .iter() + .filter(|item| filter.filter(item)) + .filter_map(|hdr| hdr.get_value().ok()) // TODO: Do not hide error here + .collect::>() + .join(""); + + self.defaulthasher.create_hash(pb, &mut s.as_bytes()) + }) + } + +} diff --git a/libimagmail/src/lib.rs b/libimagmail/src/lib.rs index d21252eb..14105f3c 100644 --- a/libimagmail/src/lib.rs +++ b/libimagmail/src/lib.rs @@ -7,7 +7,8 @@ extern crate filters; #[macro_use] extern crate libimagerror; extern crate libimagstore; -pub mod mail; pub mod error; +pub mod hasher; +pub mod mail; pub mod result; From 5b8239e45e01fc8917d7f058434d49a33f92cb5e Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 21 Sep 2016 18:14:20 +0200 Subject: [PATCH 09/19] Impl Mail::import_from_path() --- libimagmail/src/mail.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/libimagmail/src/mail.rs b/libimagmail/src/mail.rs index 897fc37e..cae45db1 100644 --- a/libimagmail/src/mail.rs +++ b/libimagmail/src/mail.rs @@ -1,11 +1,16 @@ use std::result::Result as RResult; use std::path::Path; +use std::path::PathBuf; use libimagstore::store::{FileLockEntry, Store}; +use libimagref::reference::Ref; +use libimagref::flags::RefFlags; use mailparse::{MailParseError, ParsedMail, parse_mail}; +use hasher::MailHasher; use result::Result; +use error::{MapErrInto, MailErrorKind as MEK}; struct Buffer(String); @@ -21,16 +26,19 @@ impl From for Buffer { } } -pub struct Mail<'a> { - fle: FileLockEntry<'a>, - buffer: Buffer, -} +pub struct Mail<'a>(Ref<'a>); impl<'a> Mail<'a> { /// Imports a mail from the Path passed pub fn import_from_path>(store: &Store, p: P) -> Result { - unimplemented!() + let h = MailHasher::new(); + let f = RefFlags::default().with_content_hashing(true).with_permission_tracking(false); + let p = PathBuf::from(p.as_ref()); + + Ref::create_with_hasher(store, p, f, h) + .map_err_into(MEK::RefCreationError) + .map(|r| Mail(r)) } /// Imports a mail from the String passed From d4be497d417d780384c1fb26c9717682924527aa Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 21 Sep 2016 18:15:19 +0200 Subject: [PATCH 10/19] Add dep: libimagref --- libimagmail/Cargo.toml | 3 +++ libimagmail/src/lib.rs | 1 + 2 files changed, 4 insertions(+) diff --git a/libimagmail/Cargo.toml b/libimagmail/Cargo.toml index 4494f32a..68f348f8 100644 --- a/libimagmail/Cargo.toml +++ b/libimagmail/Cargo.toml @@ -16,3 +16,6 @@ path = "../libimagstore" [dependencies.libimagerror] path = "../libimagerror" +[dependencies.libimagref] +path = "../libimagref" + diff --git a/libimagmail/src/lib.rs b/libimagmail/src/lib.rs index 14105f3c..e4db2f4f 100644 --- a/libimagmail/src/lib.rs +++ b/libimagmail/src/lib.rs @@ -6,6 +6,7 @@ extern crate filters; #[macro_use] extern crate libimagerror; extern crate libimagstore; +extern crate libimagref; pub mod error; pub mod hasher; From 3136060ecfa505b038a1273a955d0d7025362feb Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 21 Sep 2016 19:06:47 +0200 Subject: [PATCH 11/19] Remove Mail::import_from_string() --- libimagmail/src/mail.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libimagmail/src/mail.rs b/libimagmail/src/mail.rs index cae45db1..bc57c402 100644 --- a/libimagmail/src/mail.rs +++ b/libimagmail/src/mail.rs @@ -41,11 +41,6 @@ impl<'a> Mail<'a> { .map(|r| Mail(r)) } - /// Imports a mail from the String passed - pub fn import_from_string>(store: &Store, s: S) -> Result { - unimplemented!() - } - /// Opens a mail by the passed hash pub fn open>(store: &Store, hash: S) -> Result> { unimplemented!() From 042f286c34d49032c78a4b34eb8a55e9ab277026 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 21 Sep 2016 19:11:21 +0200 Subject: [PATCH 12/19] Add fetch-error kinds --- libimagmail/src/error.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libimagmail/src/error.rs b/libimagmail/src/error.rs index 59664b66..a87548d6 100644 --- a/libimagmail/src/error.rs +++ b/libimagmail/src/error.rs @@ -2,6 +2,9 @@ generate_error_module!( generate_error_types!(MailError, MailErrorKind, RefCreationError => "Error creating a reference to a file/directory", MailParsingError => "Error while parsing mail", + + FetchByHashError => "Error fetching mail from Store by hash", + FetchError => "Error fetching mail from Store", IOError => "IO Error" ); ); From 662af88eb5a5bf05dd25d90f30d418b90725d6a7 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 21 Sep 2016 19:11:31 +0200 Subject: [PATCH 13/19] Impl Mail::open() --- libimagmail/src/mail.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libimagmail/src/mail.rs b/libimagmail/src/mail.rs index bc57c402..3eb07fa0 100644 --- a/libimagmail/src/mail.rs +++ b/libimagmail/src/mail.rs @@ -43,7 +43,10 @@ impl<'a> Mail<'a> { /// Opens a mail by the passed hash pub fn open>(store: &Store, hash: S) -> Result> { - unimplemented!() + Ref::get_by_hash(store, String::from(hash.as_ref())) + .map(|opt| opt.map(|r| Mail(r))) + .map_err_into(MEK::FetchByHashError) + .map_err_into(MEK::FetchError) } pub fn get_field>(&self, field: S) -> Result> { From c7f890d0d4b014c82925514a1679ccc5a9c42d98 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 21 Sep 2016 19:25:25 +0200 Subject: [PATCH 14/19] Add error kind for ref handling errors --- libimagmail/src/error.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/libimagmail/src/error.rs b/libimagmail/src/error.rs index a87548d6..a11a0a94 100644 --- a/libimagmail/src/error.rs +++ b/libimagmail/src/error.rs @@ -1,6 +1,7 @@ generate_error_module!( generate_error_types!(MailError, MailErrorKind, RefCreationError => "Error creating a reference to a file/directory", + RefHandlingError => "Error while handling the internal reference object", MailParsingError => "Error while parsing mail", FetchByHashError => "Error fetching mail from Store by hash", From 953f53767063194120e04bfecfa283e1ec088bb0 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 21 Sep 2016 19:26:08 +0200 Subject: [PATCH 15/19] Create internal file buffer when storing/loading --- libimagmail/src/mail.rs | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/libimagmail/src/mail.rs b/libimagmail/src/mail.rs index 3eb07fa0..dd98345d 100644 --- a/libimagmail/src/mail.rs +++ b/libimagmail/src/mail.rs @@ -1,6 +1,8 @@ use std::result::Result as RResult; use std::path::Path; use std::path::PathBuf; +use std::fs::File; +use std::io::Read; use libimagstore::store::{FileLockEntry, Store}; use libimagref::reference::Ref; @@ -26,7 +28,7 @@ impl From for Buffer { } } -pub struct Mail<'a>(Ref<'a>); +pub struct Mail<'a>(Ref<'a>, Buffer); impl<'a> Mail<'a> { @@ -38,15 +40,43 @@ impl<'a> Mail<'a> { Ref::create_with_hasher(store, p, f, h) .map_err_into(MEK::RefCreationError) - .map(|r| Mail(r)) + .and_then(|reference| { + reference.fs_file() + .map_err_into(MEK::RefHandlingError) + .and_then(|path| File::open(path).map_err_into(MEK::IOError)) + .and_then(|mut file| { + let mut s = String::new(); + file.read_to_string(&mut s) + .map(|_| s) + .map_err_into(MEK::IOError) + }) + .map(Buffer::from) + .map(|buffer| Mail(reference, buffer)) + }) } /// Opens a mail by the passed hash pub fn open>(store: &Store, hash: S) -> Result> { - Ref::get_by_hash(store, String::from(hash.as_ref())) - .map(|opt| opt.map(|r| Mail(r))) + let r = try!(Ref::get_by_hash(store, String::from(hash.as_ref())) .map_err_into(MEK::FetchByHashError) - .map_err_into(MEK::FetchError) + .map_err_into(MEK::FetchError)); + + if r.is_none() { + return Ok(None); + } + let r = r.unwrap(); + + r.fs_file() + .map_err_into(MEK::RefHandlingError) + .and_then(|path| File::open(path).map_err_into(MEK::IOError)) + .and_then(|mut file| { + let mut s = String::new(); + file.read_to_string(&mut s) + .map(|_| s) + .map_err_into(MEK::IOError) + }) + .map(Buffer::from) + .map(|buffer| Some(Mail(r, buffer))) } pub fn get_field>(&self, field: S) -> Result> { From 5825022e5d17fa52870c1889a2a0479e1d5a648b Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 21 Sep 2016 19:26:16 +0200 Subject: [PATCH 16/19] Impl Mail::get_field() --- libimagmail/src/mail.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/libimagmail/src/mail.rs b/libimagmail/src/mail.rs index dd98345d..62625b03 100644 --- a/libimagmail/src/mail.rs +++ b/libimagmail/src/mail.rs @@ -79,8 +79,19 @@ impl<'a> Mail<'a> { .map(|buffer| Some(Mail(r, buffer))) } - pub fn get_field>(&self, field: S) -> Result> { - unimplemented!() + pub fn get_field(&self, field: &str) -> Result> { + use mailparse::MailHeader; + + self.1 + .parsed() + .map_err_into(MEK::MailParsingError) + .map(|parsed| { + parsed.headers + .iter() + .filter(|hdr| hdr.get_key().map(|n| n == field).unwrap_or(false)) + .next() + .and_then(|field| field.get_value().ok()) + }) } pub fn get_from(&self) -> Result> { From 80010f6043a6e4e2051f22a5826f368d1ed2d27b Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 21 Sep 2016 19:46:26 +0200 Subject: [PATCH 17/19] Impl get_{from,to,subject,message_id,in_reply_to} --- libimagmail/src/mail.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libimagmail/src/mail.rs b/libimagmail/src/mail.rs index 62625b03..2187b1fe 100644 --- a/libimagmail/src/mail.rs +++ b/libimagmail/src/mail.rs @@ -94,24 +94,24 @@ impl<'a> Mail<'a> { }) } - pub fn get_from(&self) -> Result> { - unimplemented!() + pub fn get_from(&self) -> Result> { + self.get_field("From") } - pub fn get_to(&self) -> Result> { - unimplemented!() + pub fn get_to(&self) -> Result> { + self.get_field("To") } - pub fn get_subject(&self) -> Result> { - unimplemented!() + pub fn get_subject(&self) -> Result> { + self.get_field("Subject") } - pub fn get_message_id(&self) -> Result> { - unimplemented!() + pub fn get_message_id(&self) -> Result> { + self.get_field("Message-ID") } - pub fn get_in_reply_to(&self) -> Result> { - unimplemented!() + pub fn get_in_reply_to(&self) -> Result> { + self.get_field("In-Reply-To") } } From af54e621a83cfadb63569f63f722301c60661168 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 4 Oct 2016 14:15:57 +0200 Subject: [PATCH 18/19] Add Mail::from_ref() --- libimagmail/src/mail.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/libimagmail/src/mail.rs b/libimagmail/src/mail.rs index 2187b1fe..b49e0ed5 100644 --- a/libimagmail/src/mail.rs +++ b/libimagmail/src/mail.rs @@ -57,15 +57,18 @@ impl<'a> Mail<'a> { /// Opens a mail by the passed hash pub fn open>(store: &Store, hash: S) -> Result> { - let r = try!(Ref::get_by_hash(store, String::from(hash.as_ref())) + Ref::get_by_hash(store, String::from(hash.as_ref())) .map_err_into(MEK::FetchByHashError) - .map_err_into(MEK::FetchError)); + .map_err_into(MEK::FetchError) + .and_then(|o| match o { + Some(r) => Mail::from_ref(r).map(Some), + None => Ok(None), + }) - if r.is_none() { - return Ok(None); - } - let r = r.unwrap(); + } + /// Implement me as TryFrom as soon as it is stable + pub fn from_ref(r: Ref<'a>) -> Result { r.fs_file() .map_err_into(MEK::RefHandlingError) .and_then(|path| File::open(path).map_err_into(MEK::IOError)) @@ -76,7 +79,7 @@ impl<'a> Mail<'a> { .map_err_into(MEK::IOError) }) .map(Buffer::from) - .map(|buffer| Some(Mail(r, buffer))) + .map(|buffer| Mail(r, buffer)) } pub fn get_field(&self, field: &str) -> Result> { From 0250a2c66259f147962ec40cbf86bfb5de04c886 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 4 Oct 2016 14:19:36 +0200 Subject: [PATCH 19/19] Add MailIter --- libimagmail/src/iter.rs | 37 +++++++++++++++++++++++++++++++++++++ libimagmail/src/lib.rs | 1 + 2 files changed, 38 insertions(+) create mode 100644 libimagmail/src/iter.rs diff --git a/libimagmail/src/iter.rs b/libimagmail/src/iter.rs new file mode 100644 index 00000000..365a0928 --- /dev/null +++ b/libimagmail/src/iter.rs @@ -0,0 +1,37 @@ +//! Module for the MailIter +//! +//! MailIter is a iterator which takes an Iterator that yields `Ref` and yields itself +//! `Result`, where `Err(_)` is returned if the Ref is not a Mail or parsing of the +//! referenced mail file failed. +//! + +use mail::Mail; +use result::Result; + +use libimagref::reference::Ref; + +use std::marker::PhantomData; + +struct MailIter<'a, I: 'a + Iterator>> { + _marker: PhantomData<&'a I>, + i: I, +} + +impl<'a, I: Iterator>> MailIter<'a, I> { + + pub fn new(i: I) -> MailIter<'a, I> { + MailIter { _marker: PhantomData, i: i } + } + +} + +impl<'a, I: Iterator>> Iterator for MailIter<'a, I> { + + type Item = Result>; + + fn next(&mut self) -> Option>> { + self.i.next().map(Mail::from_ref) + } + +} + diff --git a/libimagmail/src/lib.rs b/libimagmail/src/lib.rs index e4db2f4f..1d88a069 100644 --- a/libimagmail/src/lib.rs +++ b/libimagmail/src/lib.rs @@ -10,6 +10,7 @@ extern crate libimagref; pub mod error; pub mod hasher; +pub mod iter; pub mod mail; pub mod result;