summaryrefslogtreecommitdiffstats
path: root/libimagmail
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2016-09-21 18:14:11 +0200
committerMatthias Beyer <mail@beyermatthias.de>2016-10-12 19:17:40 +0200
commit03ae71497046f915125806ce4fb9dd687c3836ac (patch)
treee33a2ce59eecbe02a0627f65bb3894cb3a5987e7 /libimagmail
parent4d83ce8b6e235da674cced1bf258f9861a692176 (diff)
Add MailHasher
Diffstat (limited to 'libimagmail')
-rw-r--r--libimagmail/src/error.rs1
-rw-r--r--libimagmail/src/hasher.rs64
-rw-r--r--libimagmail/src/lib.rs3
3 files changed, 67 insertions, 1 deletions
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<R: Read>(&mut self, pb: &PathBuf, c: &mut R) -> RResult<String> {
+ 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::<Vec<String>>()
+ .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;