diff --git a/melib/src/backends/imap/protocol_parser.rs b/melib/src/backends/imap/protocol_parser.rs
index 2f93f7fb..f9a7eadd 100644
--- a/melib/src/backends/imap/protocol_parser.rs
+++ b/melib/src/backends/imap/protocol_parser.rs
@@ -719,7 +719,7 @@ named!(
let mut env = Envelope::new(0);
if let Some(date) = date {
env.set_date(&date);
- if let Some(d) = crate::email::parser::date(env.date_as_str().as_bytes()) {
+ if let Ok(d) = crate::email::parser::date(env.date_as_str().as_bytes()) {
env.set_datetime(d);
}
}
diff --git a/melib/src/email.rs b/melib/src/email.rs
index b8d089e4..6cc30aa7 100644
--- a/melib/src/email.rs
+++ b/melib/src/email.rs
@@ -122,7 +122,7 @@ pub struct Envelope {
to: Vec
,
cc: Vec,
bcc: Vec,
- subject: Option>,
+ subject: Option,
message_id: MessageID,
in_reply_to: Option,
references: Option,
@@ -315,7 +315,7 @@ impl Envelope {
if let Some(ref mut x) = in_reply_to {
self.push_references(x);
}
- if let Some(d) = parser::date(&self.date.as_bytes()) {
+ if let Ok(d) = parser::date(&self.date.as_bytes()) {
self.set_datetime(d);
}
if self.message_id.raw().is_empty() {
@@ -343,7 +343,7 @@ impl Envelope {
}
pub fn datetime(&self) -> chrono::DateTime {
- if let Some(d) = parser::date(&self.date.as_bytes()) {
+ if let Ok(d) = parser::date(&self.date.as_bytes()) {
return d;
}
chrono::FixedOffset::west(0)
@@ -412,7 +412,7 @@ impl Envelope {
pub fn subject(&self) -> Cow {
match self.subject {
- Some(ref s) => String::from_utf8_lossy(s),
+ Some(ref s) => Cow::from(s),
_ => Cow::from(String::new()),
}
}
@@ -467,10 +467,13 @@ impl Envelope {
};
self.in_reply_to = Some(MessageID::new(new_val, slice));
}
- pub fn set_subject(&mut self, mut new_val: Vec) {
+ pub fn set_subject(&mut self, new_val: Vec) {
+ let mut new_val = String::from_utf8(new_val)
+ .unwrap_or_else(|err| String::from_utf8_lossy(&err.into_bytes()).into());
while new_val
+ .chars()
.last()
- .map(|&u| char::is_control(u as char))
+ .map(|c| char::is_control(c))
.unwrap_or(false)
{
new_val.pop();
diff --git a/melib/src/email/parser.rs b/melib/src/email/parser.rs
index 449613e3..4176dce9 100644
--- a/melib/src/email/parser.rs
+++ b/melib/src/email/parser.rs
@@ -658,13 +658,18 @@ fn eat_comments(input: &[u8]) -> Vec {
* right now we expect input will have no extra spaces in between tokens
*
* We should use a custom parser here*/
-pub fn date(input: &[u8]) -> Option> {
- let parsed_result = phrase(&eat_comments(input))
- .to_full_result()
- .unwrap()
- .replace(b"-", b"+");
- chrono::DateTime::parse_from_rfc2822(String::from_utf8_lossy(parsed_result.trim()).as_ref())
- .ok()
+pub fn date(input: &[u8]) -> Result> {
+ let mut parsed_result = phrase(&eat_comments(input)).to_full_result()?;
+ if let Some(pos) = parsed_result.find(b"-0000") {
+ parsed_result[pos] = b'+';
+ }
+
+ Ok(
+ chrono::DateTime::parse_from_rfc2822(
+ String::from_utf8_lossy(parsed_result.trim()).as_ref(),
+ )
+ .map_err(|err| MeliError::new(err.to_string()))?,
+ )
}
named!(pub message_id<&[u8]>,
@@ -1052,38 +1057,48 @@ mod tests {
let words = b"=?iso-8859-7?B?W215Y291cnNlcy5udHVhLmdyIC0gyvXs4fTp6t4g6uHpIMri4e306ere?=
=?iso-8859-7?B?INb18+nq3l0gzd3hIMHt4erv3+358+c6IMzF0c/TIMHQz9TFy8XTzMHU?=
=?iso-8859-7?B?2c0gwiDUzC4gysHNLiDFzsXUwdPH0yAyMDE3LTE4OiDTx8zFydnTxw==?=";
- assert!("[mycourses.ntua.gr - Κυματική και Κβαντική Φυσική] Νέα Ανακοίνωση: ΜΕΡΟΣ ΑΠΟΤΕΛΕΣΜΑΤΩΝ Β ΤΜ. ΚΑΝ. ΕΞΕΤΑΣΗΣ 2017-18: ΣΗΜΕΙΩΣΗ" == std::str::from_utf8(&phrase(words.trim()).to_full_result().unwrap()).unwrap());
+ assert_eq!("[mycourses.ntua.gr - Κυματική και Κβαντική Φυσική] Νέα Ανακοίνωση: ΜΕΡΟΣ ΑΠΟΤΕΛΕΣΜΑΤΩΝ Β ΤΜ. ΚΑΝ. ΕΞΕΤΑΣΗΣ 2017-18: ΣΗΜΕΙΩΣΗ" , std::str::from_utf8(&phrase(words.trim()).to_full_result().unwrap()).unwrap());
let words = b"=?UTF-8?Q?=CE=A0=CF=81=CF=8C=CF=83=CE=B8=CE=B5?= =?UTF-8?Q?=CF=84=CE=B7_=CE=B5=CE=BE=CE=B5=CF=84?= =?UTF-8?Q?=CE=B1=CF=83=CF=84=CE=B9=CE=BA=CE=AE?=";
- assert!(
- "Πρόσθετη εξεταστική"
- == std::str::from_utf8(&phrase(words.trim()).to_full_result().unwrap()).unwrap()
+ assert_eq!(
+ "Πρόσθετη εξεταστική",
+ std::str::from_utf8(&phrase(words.trim()).to_full_result().unwrap()).unwrap()
);
let words = b"[Advcomparch] =?utf-8?b?zqPPhc68z4DOtc+BzrnPhs6/z4HOrCDPg861IGZs?=\n\t=?utf-8?b?dXNoIM67z4zOs8+JIG1pc3ByZWRpY3Rpb24gzrrOsc+Ezqwgz4TOt869?=\n\t=?utf-8?b?IM61zrrPhM6tzrvOtc+Dzrcgc3RvcmU=?=";
- assert!(
- "[Advcomparch] Συμπεριφορά σε flush λόγω misprediction κατά την εκτέλεση store"
- == std::str::from_utf8(&phrase(words.trim()).to_full_result().unwrap()).unwrap()
+ assert_eq!(
+ "[Advcomparch] Συμπεριφορά σε flush λόγω misprediction κατά την εκτέλεση store",
+ std::str::from_utf8(&phrase(words.trim()).to_full_result().unwrap()).unwrap()
);
let words = b"Re: [Advcomparch] =?utf-8?b?zqPPhc68z4DOtc+BzrnPhs6/z4HOrCDPg861IGZs?=
=?utf-8?b?dXNoIM67z4zOs8+JIG1pc3ByZWRpY3Rpb24gzrrOsc+Ezqwgz4TOt869?=
=?utf-8?b?IM61zrrPhM6tzrvOtc+Dzrcgc3RvcmU=?=";
- assert!(
- "Re: [Advcomparch] Συμπεριφορά σε flush λόγω misprediction κατά την εκτέλεση store"
- == std::str::from_utf8(&phrase(words.trim()).to_full_result().unwrap()).unwrap()
+ assert_eq!(
+ "Re: [Advcomparch] Συμπεριφορά σε flush λόγω misprediction κατά την εκτέλεση store",
+ std::str::from_utf8(&phrase(words.trim()).to_full_result().unwrap()).unwrap()
);
let words = b"sdf";
- assert!("sdf" == std::str::from_utf8(&phrase(words).to_full_result().unwrap()).unwrap());
+ assert_eq!(
+ "sdf",
+ std::str::from_utf8(&phrase(words).to_full_result().unwrap()).unwrap()
+ );
let words = b"=?iso-8859-7?b?U2VnIGZhdWx0IPP05+0g5er03evl8+cg9O/1?= =?iso-8859-7?q?_example_ru_n_=5Fsniper?=";
- assert!(
- "Seg fault στην εκτέλεση του example ru n _sniper"
- == std::str::from_utf8(&phrase(words).to_full_result().unwrap()).unwrap()
+ assert_eq!(
+ "Seg fault στην εκτέλεση του example ru n _sniper",
+ std::str::from_utf8(&phrase(words).to_full_result().unwrap()).unwrap()
);
let words = b"Re: [Advcomparch]
=?iso-8859-7?b?U2VnIGZhdWx0IPP05+0g5er03evl8+cg9O/1?=
=?iso-8859-7?q?_example_ru_n_=5Fsniper?=";
- assert!(
- "Re: [Advcomparch] Seg fault στην εκτέλεση του example ru n _sniper"
- == std::str::from_utf8(&phrase(words).to_full_result().unwrap()).unwrap()
+ assert_eq!(
+ "Re: [Advcomparch] Seg fault στην εκτέλεση του example ru n _sniper",
+ std::str::from_utf8(&phrase(words).to_full_result().unwrap()).unwrap()
+ );
+
+ let words = r#"[internal] =?UTF-8?B?zp3Orc6/z4Igzp/OtM63zrPPjM+CIM6jz4XOs86zz4E=?=
+ =?UTF-8?B?zrHPhs6uz4I=?="#;
+ assert_eq!(
+ "[internal] Νέος Οδηγός Συγγραφής",
+ std::str::from_utf8(&phrase(words.as_bytes()).to_full_result().unwrap()).unwrap()
);
}