diff --git a/Cargo.toml b/Cargo.toml index 19ff176b4..04a495a48 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,5 +29,5 @@ optional = false version = "5.86.0" [profile.release] -lto = true -#debug = true +#lto = true +debug = true diff --git a/benches/parse.rs b/benches/parse.rs index 35259a7ac..96448114f 100644 --- a/benches/parse.rs +++ b/benches/parse.rs @@ -2,11 +2,14 @@ extern crate melib; use melib::mailbox::email::Mail; +use melib::mailbox::backends::BackendOpGenerator; +use melib::mailbox::backends::maildir::MaildirOp; extern crate test; use self::test::Bencher; #[bench] fn mail_parse(b: &mut Bencher) { - b.iter(|| Mail::from("test/attachment_test") ); + b.iter(|| Mail::from(Box::new(BackendOpGenerator::new(Box::new(move || { + Box::new(MaildirOp::new("test/attachment_test".to_string()))})))) ); } diff --git a/src/mailbox/backends/maildir.rs b/src/mailbox/backends/maildir.rs index e9808b526..e855e7e37 100644 --- a/src/mailbox/backends/maildir.rs +++ b/src/mailbox/backends/maildir.rs @@ -22,6 +22,7 @@ use mailbox::email::Mail; use error::{MeliError, Result}; use mailbox::backends::{MailBackend, BackendOp, BackendOpGenerator}; +use mailbox::email::parser; extern crate crossbeam; use std::path::PathBuf; @@ -48,7 +49,7 @@ impl Clone for MaildirOp { } impl MaildirOp { - fn new(path: String) -> Self { + pub fn new(path: String) -> Self { MaildirOp { path: path, slice: None, @@ -66,7 +67,6 @@ impl BackendOp for MaildirOp { } Ok(unsafe { self.slice.as_ref().unwrap().as_slice() }) } - /* fn fetch_headers(&mut self) -> Result<&[u8]> { let raw = self.as_bytes()?; let result = parser::headers_raw(raw).to_full_result()?; @@ -76,7 +76,7 @@ impl BackendOp for MaildirOp { let raw = self.as_bytes()?; let result = parser::headers_raw(raw).to_full_result()?; Ok(result) - }*/ + } } diff --git a/src/mailbox/backends/mod.rs b/src/mailbox/backends/mod.rs index d77aa2a63..6326eb44c 100644 --- a/src/mailbox/backends/mod.rs +++ b/src/mailbox/backends/mod.rs @@ -37,8 +37,8 @@ pub trait BackendOp: ::std::fmt::Debug + ::std::marker::Send { fn as_bytes(&mut self) -> Result<&[u8]>; //fn delete(&self) -> (); //fn copy(&self - //fn fetch_headers(&mut self) -> Result<&[u8]>; - //fn fetch_body(&mut self) -> Result<&[u8]>; + fn fetch_headers(&mut self) -> Result<&[u8]>; + fn fetch_body(&mut self) -> Result<&[u8]>; } /* BackendOpGenerator is a wrapper for a closure that returns a BackendOp object */ diff --git a/src/mailbox/email/mod.rs b/src/mailbox/email/mod.rs index 7ca9dd15e..06b173818 100644 --- a/src/mailbox/email/mod.rs +++ b/src/mailbox/email/mod.rs @@ -108,6 +108,7 @@ pub struct Mail references: Option, datetime: Option>, + timestamp: i64, thread: usize, operation_token: Arc>, @@ -117,10 +118,7 @@ pub struct Mail impl Mail { pub fn get_date(&self) -> i64 { - match self.datetime { - Some(v) => v.timestamp(), - None => 0, - } + self.timestamp } pub fn get_datetime(&self) -> chrono::DateTime { self.datetime.unwrap_or_else(|| { chrono::FixedOffset::west(0).ymd(1970, 1, 1).and_hms(0, 0, 0)}) @@ -140,8 +138,29 @@ impl Mail None => "", } } - pub fn get_body(&self) -> &Attachment { - self.body.as_ref().unwrap() + pub fn get_body(&self) -> Attachment { + let mut operation = self.operation_token.generate(); + let file = operation.as_bytes(); + let (headers, body) = match parser::mail(file.unwrap()).to_full_result() { + Ok(v) => v, + Err(_) => { + let operation = self.operation_token.generate(); + eprintln!("error in parsing mail\n{}", operation.description()); + panic!(); + }, + }; + let mut builder = AttachmentBuilder::new(body); + for (name, value) in headers { + if value.len() == 1 && value.is_empty() { + continue; + } + if name.eq_ignore_ascii_case("content-transfer-encoding") { + builder.content_transfer_encoding(value); + } else if name.eq_ignore_ascii_case("content-type") { + builder.content_type(value); + } + } + builder.build() } pub fn get_subject(&self) -> &str { match self.subject { @@ -253,6 +272,12 @@ impl Mail } pub fn set_datetime(&mut self, new_val: Option>) -> () { self.datetime = new_val; + if let Some(v) = self.datetime { + self.timestamp = v.timestamp(); + if self.timestamp == 1485962960 { + eprintln!("it's {:?}", self); + } + } } pub fn new(token: Box) -> Self { Mail { @@ -266,6 +291,7 @@ impl Mail references: None, datetime: None, + timestamp: 0, thread: 0, @@ -275,23 +301,21 @@ impl Mail } pub fn from(operation_token: Box) -> Option { let mut operation = operation_token.generate(); - let file = operation.as_bytes(); - if file.is_err() { - return None; - } - let (headers, body) = match parser::mail(file.unwrap()).to_full_result() { - Ok(v) => v, - Err(_) => { + let headers = match parser::headers(operation.fetch_headers().unwrap()).to_full_result() { + Ok(v) => { + v + }, + _ => { let operation = operation_token.generate(); eprintln!("error in parsing mail\n{}", operation.description()); return None; - } + }, }; + let mut mail = Mail::new(operation_token); let mut in_reply_to = None; let mut datetime = None; - let mut builder = AttachmentBuilder::new(body); for (name, value) in headers { if value.len() == 1 && value.is_empty() { continue; @@ -325,14 +349,11 @@ impl Mail } else if name.eq_ignore_ascii_case("references") { { let parse_result = parser::references(value.as_bytes()); - eprintln!("{:?}", value); if parse_result.is_done() { for v in parse_result.to_full_result().unwrap() { - eprintln!("pushing {:?}", v); mail.push_references(v); } } - eprintln!("\n\n"); } mail.set_references(value.to_string()); } else if name.eq_ignore_ascii_case("in-reply-to") { @@ -341,16 +362,11 @@ impl Mail } else if name.eq_ignore_ascii_case("date") { mail.set_date(value.to_string()); datetime = Some(value.to_string()); - } else if name.eq_ignore_ascii_case("content-transfer-encoding") { - builder.content_transfer_encoding(value); - } else if name.eq_ignore_ascii_case("content-type") { - builder.content_type(value); } } if let Some(ref mut x) = in_reply_to { mail.push_references(x); } - mail.set_body(builder.build()); if let Some(ref mut d) = datetime { mail.set_datetime(parser::date(d)); } diff --git a/src/mailbox/email/parser.rs b/src/mailbox/email/parser.rs index 7ec28e384..38ecdebe0 100644 --- a/src/mailbox/email/parser.rs +++ b/src/mailbox/email/parser.rs @@ -107,7 +107,7 @@ named!(name<&str>, named!(header<(&str, &str)>, separated_pair!(complete!(name), ws!(tag!(":")), complete!(header_value))); /* Parse all headers -> Vec<(&str, Vec<&str>)> */ -named!(headers>, +named!(pub headers>, many1!(complete!(header))); named!(pub headers_raw<&[u8]>,