diff options
Diffstat (limited to 'lib/domain/libimagmail/src/hasher.rs')
-rw-r--r-- | lib/domain/libimagmail/src/hasher.rs | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/lib/domain/libimagmail/src/hasher.rs b/lib/domain/libimagmail/src/hasher.rs new file mode 100644 index 00000000..8ea3f036 --- /dev/null +++ b/lib/domain/libimagmail/src/hasher.rs @@ -0,0 +1,87 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; version +// 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// + +use std::io::Read; +use std::path::PathBuf; + +use email::MimeMessage; + +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; + use email::Header; + + let mut s = String::new(); + try!(c.read_to_string(&mut s).map_err_into(REK::UTF8Error).map_err_into(REK::IOError)); + + MimeMessage::parse(&s) + .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: &Header, exp: &str| hdr.name == exp; + + let subject_filter = |hdr: &Header| has_key(hdr, "Subject"); + let from_filter = |hdr: &Header| has_key(hdr, "From"); + let to_filter = |hdr: &Header| has_key(hdr, "To"); + + let filter = subject_filter.or(from_filter).or(to_filter); + + let mut v : Vec<String> = vec![]; + for hdr in mail.headers.iter().filter(|item| filter.filter(item)) { + let s = try!(hdr + .get_value() + .map_err(Box::new) + .map_err(|e| REK::RefHashingError.into_error_with_cause(e))); + + v.push(s); + } + let s : String = v.join(""); + + self.defaulthasher.create_hash(pb, &mut s.as_bytes()) + }) + } + +} |