From 73ffbad0503b710b2e7c7e25d64539102b0fbd49 Mon Sep 17 00:00:00 2001 From: TornaxO7 Date: Sun, 22 Aug 2021 17:26:21 +0200 Subject: [PATCH 1/8] Fixing JSON output - JSON of message includes `hasAttachment` key now - JSON output shows both body types: Text and Html - Changed `Body` struct so it can store html and text now. --- src/msg/body.rs | 174 ++++++++++++++++++++++--------------- src/msg/cli.rs | 10 ++- src/msg/model.rs | 218 ++++++++++++++++++++++++++--------------------- 3 files changed, 232 insertions(+), 170 deletions(-) diff --git a/src/msg/body.rs b/src/msg/body.rs index a3eb136a..e41e9b87 100644 --- a/src/msg/body.rs +++ b/src/msg/body.rs @@ -1,14 +1,13 @@ use error_chain::error_chain; use std::fmt; -use std::ops::{Deref, DerefMut}; use serde::Serialize; // == Macros == error_chain! { foreign_links { - ParseContentType(lettre::message::header::ContentTypeErr); + ParseContentType(lettre::message::header::ContentTypeErr); } } @@ -24,91 +23,130 @@ error_chain! { /// /// This part of the msg/msg would be stored in this struct. #[derive(Clone, Serialize, Debug, PartialEq, Eq)] -pub struct Body(String); +pub struct Body { + /// The text version of a body (if available) + pub text: Option, + + /// The html version of a body (if available) + pub html: Option, +} impl Body { - /// This function just returns a clone of it's content. If we use the - /// example from above, than you'll get a clone of the whole text. + + /// Returns a new instance of `Body` without any attributes set. (Same as `Body::default()`) /// /// # Example + /// ```rust + /// use himalaya::msg::body::Body; + /// + /// fn main() { + /// let body = Body::new(); + /// + /// let expected_body = Body { + /// text: None, + /// html: None, + /// }; + /// + /// assert_eq!(body, expected_body); + /// } + /// ``` + pub fn new() -> Self { + Self::default() + } + + /// Returns a new instance of `Body` with `text` set. + /// + /// # Example + /// ```rust + /// use himalaya::msg::body::Body; + /// + /// fn main() { + /// let body = Body::new_with_text("Text body"); + /// + /// let expected_body = Body { + /// text: Some("Text body".to_string()), + /// html: None, + /// }; + /// + /// assert_eq!(body, expected_body); + /// } /// ``` - /// # use himalaya::msg::body::Body; - /// # fn main() { - /// let body = concat![ - /// "Dear Mr. Boss,\n", - /// "I like rust. It's an awesome language. *Change my mind*....\n", - /// "\n", - /// "Sincerely", - /// ]; + pub fn new_with_text(text: S) -> Self { + Self { + text: Some(text.to_string()), + html: None, + } + } + + /// Returns a new instance of `Body` with `html` set. /// - /// // create a new instance of `Body` - /// let body_struct = Body::from(body); + /// # Example + /// ```rust + /// use himalaya::msg::body::Body; + /// + /// fn main() { + /// let body = Body::new_with_html("Html body"); + /// + /// let expected_body = Body { + /// text: None, + /// html: Some("Html body".to_string()), + /// }; /// - /// assert_eq!(body_struct.get_content(), body); - /// # } + /// assert_eq!(body, expected_body); + /// } /// ``` - pub fn get_content(&self) -> String { - self.0.clone() + pub fn new_with_html(html: S) -> Self { + Self { + text: None, + html: Some(html.to_string()), + } + } + + /// Returns a new isntance of `Body` with `text` and `html` set. + /// + /// # Example + /// ```rust + /// use himalaya::msg::body::Body; + /// + /// fn main() { + /// let body = Body::new_with_both("Text body", "Html body"); + /// + /// let expected_body = Body { + /// text: Some("Text body".to_string()), + /// html: Some("Html body".to_string()), + /// }; + /// + /// assert_eq!(body, expected_body); + /// } + /// ``` + pub fn new_with_both(text: S, html: S) -> Self { + Self { + text: Some(text.to_string()), + html: Some(html.to_string()), + } } } // == Traits == impl Default for Body { fn default() -> Self { - Self(String::new()) + Self { + text: None, + html: None, + } } } impl fmt::Display for Body { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!(formatter, "{}", &self.0) - } -} - -impl Deref for Body { - type Target = String; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for Body { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} + let content = if let Some(text) = self.text.clone() { + text + } else if let Some(html) = self.html.clone() { + html + } else { + String::new() + }; -// -- From's -- -/// Give in a `&str` to create a new instance of `Body`. -/// -/// # Example -/// ``` -/// # use himalaya::msg::body::Body; -/// # fn main() { -/// Body::from("An awesome string!"); -/// # } -/// ``` -impl From<&str> for Body { - fn from(string: &str) -> Self { - Self(string.to_string()) - } -} - -/// Give in a [`String`] to create a new instance of `Body`. -/// -/// # Example -/// ``` -/// # use himalaya::msg::body::Body; -/// # fn main() { -/// let body_content = String::from("A awesome content."); -/// Body::from(body_content); -/// # } -/// ``` -/// -/// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html -impl From for Body { - fn from(string: String) -> Self { - Self(string) + write!(formatter, "{}", content) } } diff --git a/src/msg/cli.rs b/src/msg/cli.rs index 9db281aa..890e0444 100644 --- a/src/msg/cli.rs +++ b/src/msg/cli.rs @@ -348,7 +348,11 @@ fn msg_matches_read(ctx: &Ctx, matches: &clap::ArgMatches) -> Result { if raw { ctx.output.print(msg.get_raw()?); } else { - ctx.output.print(msg.body); + if ctx.output.is_json() { + ctx.output.print(msg); + } else { + ctx.output.print(msg.body); + } } imap_conn.logout(); @@ -503,7 +507,7 @@ pub fn msg_matches_mailto(ctx: &Ctx, url: &Url) -> Result<()> { }; let mut msg = Msg::new_with_envelope(&ctx, envelope); - msg.body = Body::from(body.as_ref()); + msg.body = Body::new_with_text(body); msg_interaction(&ctx, &mut msg, &mut imap_conn)?; imap_conn.logout(); @@ -753,7 +757,7 @@ fn override_msg_with_args(msg: &mut Msg, matches: &clap::ArgMatches) { } }; - let body = Body::from(body); + let body = Body::new_with_text(body); // -- Creating and printing -- let envelope = Envelope { diff --git a/src/msg/model.rs b/src/msg/model.rs index 9e33626d..04a8aff2 100644 --- a/src/msg/model.rs +++ b/src/msg/model.rs @@ -1,5 +1,3 @@ -use std::ops::Deref; - use super::attachment::Attachment; use super::body::Body; use super::envelope::Envelope; @@ -19,7 +17,8 @@ use crate::{ #[cfg(not(test))] use crate::input; -use serde::Serialize; +use serde::{Serialize, ser}; +use serde::ser::SerializeStruct; use lettre::message::{ header::ContentTransferEncoding, header::ContentType, Attachment as lettre_Attachment, Mailbox, @@ -36,9 +35,8 @@ use colorful::Colorful; // == Macros == error_chain::error_chain! { errors { - // An error appeared, when it tried to parse the body of the msg! ParseBody (err: String) { - description("Couldn't get the body of the parsed msg."), + description("An error appeared, when it tried to parse the body of the msg!"), display("Couldn't get the body of the parsed msg: {}", err), } @@ -74,8 +72,7 @@ error_chain::error_chain! { // == Msg == /// This struct represents a whole msg with its attachments, body-content /// and its envelope. -#[derive(Debug, Serialize, PartialEq, Eq, Clone)] -#[serde(rename_all = "camelCase")] +#[derive(Debug, PartialEq, Eq, Clone)] pub struct Msg { /// All added attachments are listed in this vector. pub attachments: Vec, @@ -103,7 +100,6 @@ pub struct Msg { date: Option, /// The msg but in raw. - #[serde(skip_serializing)] raw: Vec, } @@ -170,7 +166,7 @@ impl Msg { envelope.signature = ctx.config.signature(ctx.account); } - let body = Body::from(if let Some(sig) = envelope.signature.as_ref() { + let body = Body::new_with_text(if let Some(sig) = envelope.signature.as_ref() { format!("\n{}", sig) } else { String::from("\n") @@ -229,7 +225,7 @@ impl Msg { format!("Re: {}", sub) } }) - .unwrap_or_default(); + .unwrap_or_default(); // The new fields let mut to: Vec = Vec::new(); @@ -275,14 +271,14 @@ impl Msg { // comment "out" the body of the msg, by adding the `>` characters to // each line which includes a string. - let mut new_body = self - .body + let mut new_body = self.body.text.clone() + .unwrap_or(String::new()) .lines() .map(|line| { let space = if line.starts_with(">") { "" } else { " " }; format!(">{}{}", space, line) }) - .collect::>() + .collect::>() .join("\n"); // also add the the signature in the end @@ -291,7 +287,7 @@ impl Msg { new_body.push_str(&sig) } - self.body = Body::from(new_body); + self.body = Body::new_with_text(new_body); self.envelope = new_envelope; self.attachments.clear(); @@ -351,11 +347,11 @@ impl Msg { // -- Body -- // apply a line which should indicate where the forwarded message begins body.push_str(&format!( - "\n\n---------- Forwarded Message ----------\n{}", - &self.body.deref().replace("\r", ""), - )); + "\n\n---------- Forwarded Message ----------\n{}", + self.body.text.clone().unwrap_or_default().replace("\r", ""), + )); - self.body = Body::from(body); + self.body = Body::new_with_text(body); } /// Returns the bytes of the *sendable message* of the struct! @@ -467,7 +463,7 @@ impl Msg { self.envelope = Envelope::from(&parsed); match parsed.get_body() { - Ok(body) => self.body = Body::from(body), + Ok(body) => self.body = Body::new_with_text(body), Err(err) => return Err(ErrorKind::ParseBody(err.to_string()).into()), }; @@ -551,7 +547,7 @@ impl Msg { Err(err) => { return Err( ErrorKind::Header(err.to_string(), "From", mailaddress.to_string()).into(), - ) + ) } }); } @@ -563,7 +559,7 @@ impl Msg { Err(err) => { return Err( ErrorKind::Header(err.to_string(), "To", mailaddress.to_string()).into(), - ) + ) } }); } @@ -576,11 +572,11 @@ impl Msg { Ok(bcc) => bcc, Err(err) => { return Err(ErrorKind::Header( - err.to_string(), - "Bcc", - mailaddress.to_string(), - ) - .into()) + err.to_string(), + "Bcc", + mailaddress.to_string(), + ) + .into()) } }); } @@ -593,11 +589,11 @@ impl Msg { Ok(cc) => cc, Err(err) => { return Err(ErrorKind::Header( - err.to_string(), - "Cc", - mailaddress.to_string(), - ) - .into()) + err.to_string(), + "Cc", + mailaddress.to_string(), + ) + .into()) } }); } @@ -609,11 +605,11 @@ impl Msg { Ok(in_reply_to) => in_reply_to, Err(err) => { return Err(ErrorKind::Header( - err.to_string(), - "In-Reply-To", - in_reply_to.to_string(), - ) - .into()) + err.to_string(), + "In-Reply-To", + in_reply_to.to_string(), + ) + .into()) } }); } @@ -640,11 +636,11 @@ impl Msg { Ok(reply_to) => reply_to, Err(err) => { return Err(ErrorKind::Header( - err.to_string(), - "Reply-to", - mailaddress.to_string(), - ) - .into()) + err.to_string(), + "Reply-to", + mailaddress.to_string(), + ) + .into()) } }); } @@ -657,7 +653,7 @@ impl Msg { Err(err) => { return Err( ErrorKind::Header(err.to_string(), "Sender", sender.to_string()).into(), - ) + ) } }); } @@ -675,11 +671,19 @@ impl Msg { let mut msg_parts = MultiPart::mixed().build(); // -- Body -- - let msg_body = SinglePart::builder() - .header(ContentType::TEXT_PLAIN) - .header(self.envelope.encoding) - .body(self.body.get_content()); - msg_parts = msg_parts.singlepart(msg_body); + if self.body.text.is_some() && self.body.html.is_some() { + msg_parts = msg_parts.multipart(MultiPart::alternative_plain_html( + self.body.text.clone().unwrap(), + self.body.html.clone().unwrap() + )); + } else { + let msg_body = SinglePart::builder() + .header(ContentType::TEXT_PLAIN) + .header(self.envelope.encoding) + .body(self.body.text.clone().unwrap_or_default()); + + msg_parts = msg_parts.singlepart(msg_body); + } // -- Attachments -- for attachment in self.attachments.iter() { @@ -691,10 +695,10 @@ impl Msg { } Ok(msg - .multipart(msg_parts) - // whenever an error appears, print out the messge as well to see what might be the - // error - .chain_err(|| format!("-- Current Message --\n{}", self))?) + .multipart(msg_parts) + // whenever an error appears, print out the messge as well to see what might be the + // error + .chain_err(|| format!("-- Current Message --\n{}", self))?) } /// Returns the uid of the msg. @@ -715,7 +719,7 @@ impl Msg { format!( "[{}]: Couldn't get the raw body of the msg/msg.", "Error".red() - ) + ) })?; Ok(raw_message) @@ -728,6 +732,23 @@ impl Msg { } // -- Traits -- +impl ser::Serialize for Msg { + fn serialize (&self, serializer: S) -> core::result::Result + where + S: ser::Serializer + { + println!("ÖLKJASFÖLKJ"); + let mut state = serializer.serialize_struct("Msg", 6)?; + state.serialize_field("hasAttachment", &(self.attachments.len() > 0))?; + state.serialize_field("flags", &self.flags)?; + state.serialize_field("envelope", &self.envelope)?; + state.serialize_field("body", &self.body)?; + state.serialize_field("uid", &self.uid)?; + state.serialize_field("date", &self.date)?; + state.end() + } +} + impl Default for Msg { fn default() -> Self { Self { @@ -751,7 +772,7 @@ impl fmt::Display for Msg { "{}\n{}", self.envelope.get_header_as_string(), self.body, - ) + ) } } @@ -837,28 +858,27 @@ impl TryFrom<&Fetch> for Msg { }; // -- Storing the information (body) -- - let mut body = String::new(); + let mut body = Body::new(); if let Some(parsed) = parsed { // Ok, so some mails have their mody wrapped in a multipart, some // don't. This condition hits, if the body isn't in a multipart, so we can // immediately fetch the body from the first part of the mail. - if parsed.ctype.mimetype == "text/plain" { - // Apply the body (if there exists one) - if let Ok(parsed_body) = parsed.get_body() { - debug!("Stored the body of the msg."); - body = parsed_body; - } - } + match parsed.ctype.mimetype.as_ref() { + "text/plain" => body.text = parsed.get_body().ok(), + "text/html" => body.html = parsed.get_body().ok(), + _ => (), + }; for subpart in &parsed.subparts { // now it might happen, that the body is *in* a multipart, if // that's the case, look, if we've already applied a body // (body.is_empty()) and set it, if needed - if body.is_empty() && subpart.ctype.mimetype == "text/plain" { - if let Ok(subpart_body) = subpart.get_body() { - body = subpart_body; - } + if body.text.is_none() && subpart.ctype.mimetype == "text/plain" { + body.text = subpart.get_body().ok(); + } else if body.html.is_none() && subpart.ctype.mimetype == "text/html" { + body.html = subpart.get_body().ok(); } + // otherise it's a normal attachment, like a PNG file or // something like that else if let Some(attachment) = Attachment::from_parsed_mail(subpart) { @@ -871,7 +891,7 @@ impl TryFrom<&Fetch> for Msg { "[{}] Unknown attachment with the following mime-type: {}\n", "Warning".yellow(), subpart.ctype.mimetype, - ); + ); } } } @@ -1005,7 +1025,7 @@ mod tests { from: vec![String::from("Account Name ")], ..Envelope::default() }, - ); + ); let expected_with_custom_from = Msg { envelope: Envelope { // the Msg::new_with_envelope function should use the from @@ -1025,7 +1045,7 @@ mod tests { "Left: {:?}, Right: {:?}", dbg!(&msg_with_custom_from), dbg!(&expected_with_custom_from) - ); + ); } #[test] @@ -1058,7 +1078,7 @@ mod tests { "Left: {:?}, Right: {:?}", dbg!(&msg_with_custom_signature), dbg!(&expected_with_custom_signature) - ); + ); } #[test] @@ -1090,8 +1110,8 @@ mod tests { ..Envelope::default() }, body: Body::from(concat![ - "This is a message just to say hello.\n", - "So, \"Hello\".", + "This is a message just to say hello.\n", + "So, \"Hello\".", ]), ..Msg::default() }; @@ -1113,8 +1133,8 @@ mod tests { "Name ".to_string(), ], cc: Some(vec![ - "test@testing".to_string(), - "test2@testing".to_string(), + "test@testing".to_string(), + "test2@testing".to_string(), ]), message_id: Some("RandomID123".to_string()), reply_to: Some(vec!["Reply@Mail.rofl".to_string()]), @@ -1133,7 +1153,7 @@ mod tests { from: vec!["Mary Smith ".to_string()], to: vec!["John Doe ".to_string()], reply_to: Some(vec![ - "\"Mary Smith: Personal Account\" ".to_string(), + "\"Mary Smith: Personal Account\" ".to_string(), ]), subject: Some("Re: Saying Hello".to_string()), message_id: Some("<3456@example.net>".to_string()), @@ -1141,8 +1161,8 @@ mod tests { ..Envelope::default() }, body: Body::from(concat![ - "> This is a message just to say hello.\n", - "> So, \"Hello\".", + "> This is a message just to say hello.\n", + "> So, \"Hello\".", ]), ..Msg::default() }; @@ -1158,8 +1178,8 @@ mod tests { ..Envelope::default() }, body: Body::from(concat![ - ">> This is a message just to say hello.\n", - ">> So, \"Hello\".", + ">> This is a message just to say hello.\n", + ">> So, \"Hello\".", ]), ..Msg::default() }; @@ -1174,8 +1194,8 @@ mod tests { "Reply@Mail.rofl".to_string(), ], cc: Some(vec![ - "test@testing".to_string(), - "test2@testing".to_string(), + "test@testing".to_string(), + "test2@testing".to_string(), ]), in_reply_to: Some("RandomID123".to_string()), subject: Some("Re: Have you heard of himalaya?".to_string()), @@ -1195,7 +1215,7 @@ mod tests { rfc_reply_1.envelope = Envelope { message_id: Some("<3456@example.net>".to_string()), reply_to: Some(vec![ - "\"Mary Smith: Personal Account\" ".to_string(), + "\"Mary Smith: Personal Account\" ".to_string(), ]), ..rfc_reply_1.envelope.clone() }; @@ -1214,7 +1234,7 @@ mod tests { "Left: {:?}, Right: {:?}", dbg!(&rfc_reply_1), dbg!(&expected_rfc1) - ); + ); assert_eq!( rfc_reply_2, @@ -1222,7 +1242,7 @@ mod tests { "Left: {:?}, Right: {:?}", dbg!(&rfc_reply_2), dbg!(&expected_rfc2) - ); + ); // -- custom tests -— msg_reply_all.change_to_reply(&ctx, true).unwrap(); @@ -1232,7 +1252,7 @@ mod tests { "Left: {:?}, Right: {:?}", dbg!(&msg_reply_all), dbg!(&expected_reply_all) - ); + ); } #[test] @@ -1254,7 +1274,7 @@ mod tests { subject: Some(String::from("Test subject")), ..Envelope::default() }, - ); + ); msg.body = Body::from(concat!["The body text, nice!\n", "Himalaya is nice!",]); @@ -1268,11 +1288,11 @@ mod tests { ..Envelope::default() }, body: Body::from(concat![ - "\n-- \nlol\n", - "\n", - "---------- Forwarded Message ----------\n", - "The body text, nice!\n", - "Himalaya is nice!", + "\n-- \nlol\n", + "\n", + "---------- Forwarded Message ----------\n", + "The body text, nice!\n", + "Himalaya is nice!", ]), ..Msg::default() }; @@ -1285,7 +1305,7 @@ mod tests { "Left: {:?}, Right: {:?}", dbg!(&msg), dbg!(&expected_msg) - ); + ); } #[test] @@ -1307,7 +1327,7 @@ mod tests { subject: Some(String::new()), ..Envelope::default() }, - ); + ); // == Expected Results == let expected_msg = Msg { @@ -1332,7 +1352,7 @@ mod tests { "Left: {:?}, Right: {:?}", dbg!(&msg), dbg!(&expected_msg) - ); + ); } #[test] @@ -1376,8 +1396,8 @@ mod tests { from: vec![String::from("Some ")], subject: Some(String::from("Awesome Subject")), bcc: Some(vec![ - String::from("name "), - String::from("mail1@rofl.lol"), + String::from("name "), + String::from("mail1@rofl.lol"), ]), to: vec![String::from("To ")], ..Envelope::default() @@ -1396,8 +1416,8 @@ mod tests { from: vec![String::from("Some ")], subject: Some(String::from("Awesome Subject")), bcc: Some(vec![ - String::from("name "), - String::from("mail1@rofl.lol"), + String::from("name "), + String::from("mail1@rofl.lol"), ]), to: vec![String::from("To ")], custom_headers: Some(custom_headers), @@ -1420,7 +1440,7 @@ mod tests { "Left: {:?}, Right: {:?}", dbg!(&msg1), dbg!(&expect) - ); + ); assert_eq!( msg2, @@ -1428,6 +1448,6 @@ mod tests { "Left: {:?}, Right: {:?}", dbg!(&msg2), dbg!(&expect_custom_header) - ); + ); } } From c883ed86633c478955feee5a483436030dce3498 Mon Sep 17 00:00:00 2001 From: TornaxO7 Date: Sun, 22 Aug 2021 17:32:34 +0200 Subject: [PATCH 2/8] Tests Updated tests with the latest Body implementation --- src/msg/model.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/msg/model.rs b/src/msg/model.rs index 04a8aff2..e9e0ed32 100644 --- a/src/msg/model.rs +++ b/src/msg/model.rs @@ -520,7 +520,7 @@ impl Msg { /// }, /// ); /// - /// msg.body = Body::from("A little text."); + /// msg.body = Body::new_with_text("A little text."); /// let sendable_msg = msg.to_sendable_msg().unwrap(); /// /// // now send the msg. Hint: Do the appropriate error handling here! @@ -900,7 +900,7 @@ impl TryFrom<&Fetch> for Msg { attachments, flags, envelope, - body: Body::from(body), + body: Body::new_with_text(body), uid, date, raw, @@ -1035,7 +1035,7 @@ mod tests { ..Envelope::default() }, // The signature should be added automatically - body: Body::from("\n"), + body: Body::new_with_text("\n"), ..Msg::default() }; @@ -1068,7 +1068,7 @@ mod tests { signature: Some(String::from("\n-- \nSignature")), ..Envelope::default() }, - body: Body::from("\n\n-- \nSignature"), + body: Body::new_with_text("\n\n-- \nSignature"), ..Msg::default() }; @@ -1109,7 +1109,7 @@ mod tests { message_id: Some("<1234@local.machine.example>".to_string()), ..Envelope::default() }, - body: Body::from(concat![ + body: Body::new_with_text(concat![ "This is a message just to say hello.\n", "So, \"Hello\".", ]), @@ -1141,7 +1141,7 @@ mod tests { subject: Some("Have you heard of himalaya?".to_string()), ..Envelope::default() }, - body: Body::from(concat!["A body test\n", "\n", "Sincerely",]), + body: Body::new_with_text(concat!["A body test\n", "\n", "Sincerely",]), ..Msg::default() }; @@ -1160,7 +1160,7 @@ mod tests { in_reply_to: Some("<1234@local.machine.example>".to_string()), ..Envelope::default() }, - body: Body::from(concat![ + body: Body::new_with_text(concat![ "> This is a message just to say hello.\n", "> So, \"Hello\".", ]), @@ -1177,7 +1177,7 @@ mod tests { in_reply_to: Some("<3456@example.net>".to_string()), ..Envelope::default() }, - body: Body::from(concat![ + body: Body::new_with_text(concat![ ">> This is a message just to say hello.\n", ">> So, \"Hello\".", ]), @@ -1201,7 +1201,7 @@ mod tests { subject: Some("Re: Have you heard of himalaya?".to_string()), ..Envelope::default() }, - body: Body::from(concat!["> A body test\n", "> \n", "> Sincerely"]), + body: Body::new_with_text(concat!["> A body test\n", "> \n", "> Sincerely"]), ..Msg::default() }; @@ -1276,7 +1276,7 @@ mod tests { }, ); - msg.body = Body::from(concat!["The body text, nice!\n", "Himalaya is nice!",]); + msg.body = Body::new_with_text(concat!["The body text, nice!\n", "Himalaya is nice!",]); // == Expected Results == let expected_msg = Msg { @@ -1287,7 +1287,7 @@ mod tests { subject: Some(String::from("Fwd: Test subject")), ..Envelope::default() }, - body: Body::from(concat![ + body: Body::new_with_text(concat![ "\n-- \nlol\n", "\n", "---------- Forwarded Message ----------\n", @@ -1340,7 +1340,7 @@ mod tests { cc: Some(vec![String::from("")]), ..Envelope::default() }, - body: Body::from("\n\n-- \nAccount Signature"), + body: Body::new_with_text("\n\n-- \nAccount Signature"), ..Msg::default() }; @@ -1402,7 +1402,7 @@ mod tests { to: vec![String::from("To ")], ..Envelope::default() }, - body: Body::from("Account Signature\n"), + body: Body::new_with_text("Account Signature\n"), ..Msg::default() }; @@ -1423,7 +1423,7 @@ mod tests { custom_headers: Some(custom_headers), ..Envelope::default() }, - body: Body::from("Account Signature\n"), + body: Body::new_with_text("Account Signature\n"), ..Msg::default() }; From 6c85348805f514e220804228bb1bf3703987f4aa Mon Sep 17 00:00:00 2001 From: TornaxO7 Date: Sun, 22 Aug 2021 21:07:31 +0200 Subject: [PATCH 3/8] Fixes - Removed suspicious println macro in serializer of msg... *cough cough* - Fixed output in the "read" command - othe small fixes --- src/msg/cli.rs | 6 +- src/msg/model.rs | 159 ++++++++++++++++++++++++----------------------- 2 files changed, 81 insertions(+), 84 deletions(-) diff --git a/src/msg/cli.rs b/src/msg/cli.rs index 3dbd2778..0fb7188a 100644 --- a/src/msg/cli.rs +++ b/src/msg/cli.rs @@ -348,11 +348,7 @@ fn msg_matches_read(ctx: &Ctx, matches: &clap::ArgMatches) -> Result { if raw { ctx.output.print(msg.get_raw()?); } else { - if ctx.output.is_json() { - ctx.output.print(msg); - } else { - ctx.output.print(msg.body); - } + ctx.output.print(msg); } imap_conn.logout(); diff --git a/src/msg/model.rs b/src/msg/model.rs index 0bc207d2..197ed54b 100644 --- a/src/msg/model.rs +++ b/src/msg/model.rs @@ -17,8 +17,8 @@ use crate::{ #[cfg(not(test))] use crate::input; -use serde::{Serialize, ser}; use serde::ser::SerializeStruct; +use serde::{ser, Serialize}; use lettre::message::{ header::ContentTransferEncoding, header::ContentType, Attachment as lettre_Attachment, Mailbox, @@ -36,7 +36,7 @@ use colorful::Colorful; error_chain::error_chain! { errors { ParseBody (err: String) { - description("An error appeared, when it tried to parse the body of the msg!"), + description("An error appeared, when trying to parse the body of the msg!"), display("Couldn't get the body of the parsed msg: {}", err), } @@ -225,7 +225,7 @@ impl Msg { format!("Re: {}", sub) } }) - .unwrap_or_default(); + .unwrap_or_default(); // The new fields let mut to: Vec = Vec::new(); @@ -271,14 +271,17 @@ impl Msg { // comment "out" the body of the msg, by adding the `>` characters to // each line which includes a string. - let mut new_body = self.body.text.clone() - .unwrap_or(String::new()) + let mut new_body = self + .body + .text + .clone() + .unwrap_or_default() .lines() .map(|line| { let space = if line.starts_with(">") { "" } else { " " }; format!(">{}{}", space, line) }) - .collect::>() + .collect::>() .join("\n"); // also add the the signature in the end @@ -347,9 +350,9 @@ impl Msg { // -- Body -- // apply a line which should indicate where the forwarded message begins body.push_str(&format!( - "\n\n---------- Forwarded Message ----------\n{}", - self.body.text.clone().unwrap_or_default().replace("\r", ""), - )); + "\n\n---------- Forwarded Message ----------\n{}", + self.body.text.clone().unwrap_or_default().replace("\r", ""), + )); self.body = Body::new_with_text(body); } @@ -547,7 +550,7 @@ impl Msg { Err(err) => { return Err( ErrorKind::Header(err.to_string(), "From", mailaddress.to_string()).into(), - ) + ) } }); } @@ -559,7 +562,7 @@ impl Msg { Err(err) => { return Err( ErrorKind::Header(err.to_string(), "To", mailaddress.to_string()).into(), - ) + ) } }); } @@ -572,11 +575,11 @@ impl Msg { Ok(bcc) => bcc, Err(err) => { return Err(ErrorKind::Header( - err.to_string(), - "Bcc", - mailaddress.to_string(), - ) - .into()) + err.to_string(), + "Bcc", + mailaddress.to_string(), + ) + .into()) } }); } @@ -589,11 +592,11 @@ impl Msg { Ok(cc) => cc, Err(err) => { return Err(ErrorKind::Header( - err.to_string(), - "Cc", - mailaddress.to_string(), - ) - .into()) + err.to_string(), + "Cc", + mailaddress.to_string(), + ) + .into()) } }); } @@ -605,11 +608,11 @@ impl Msg { Ok(in_reply_to) => in_reply_to, Err(err) => { return Err(ErrorKind::Header( - err.to_string(), - "In-Reply-To", - in_reply_to.to_string(), - ) - .into()) + err.to_string(), + "In-Reply-To", + in_reply_to.to_string(), + ) + .into()) } }); } @@ -636,11 +639,11 @@ impl Msg { Ok(reply_to) => reply_to, Err(err) => { return Err(ErrorKind::Header( - err.to_string(), - "Reply-to", - mailaddress.to_string(), - ) - .into()) + err.to_string(), + "Reply-to", + mailaddress.to_string(), + ) + .into()) } }); } @@ -653,7 +656,7 @@ impl Msg { Err(err) => { return Err( ErrorKind::Header(err.to_string(), "Sender", sender.to_string()).into(), - ) + ) } }); } @@ -673,9 +676,9 @@ impl Msg { // -- Body -- if self.body.text.is_some() && self.body.html.is_some() { msg_parts = msg_parts.multipart(MultiPart::alternative_plain_html( - self.body.text.clone().unwrap(), - self.body.html.clone().unwrap() - )); + self.body.text.clone().unwrap(), + self.body.html.clone().unwrap(), + )); } else { let msg_body = SinglePart::builder() .header(ContentType::TEXT_PLAIN) @@ -695,10 +698,10 @@ impl Msg { } Ok(msg - .multipart(msg_parts) - // whenever an error appears, print out the messge as well to see what might be the - // error - .chain_err(|| format!("-- Current Message --\n{}", self))?) + .multipart(msg_parts) + // whenever an error appears, print out the messge as well to see what might be the + // error + .chain_err(|| format!("-- Current Message --\n{}", self))?) } /// Returns the uid of the msg. @@ -719,7 +722,7 @@ impl Msg { format!( "[{}]: Couldn't get the raw body of the msg/msg.", "Error".red() - ) + ) })?; Ok(raw_message) @@ -733,11 +736,10 @@ impl Msg { // -- Traits -- impl ser::Serialize for Msg { - fn serialize (&self, serializer: S) -> core::result::Result + fn serialize(&self, serializer: S) -> core::result::Result where - S: ser::Serializer + S: ser::Serializer, { - println!("ÖLKJASFÖLKJ"); let mut state = serializer.serialize_struct("Msg", 6)?; state.serialize_field("hasAttachment", &(self.attachments.len() > 0))?; state.serialize_field("flags", &self.flags)?; @@ -772,7 +774,7 @@ impl fmt::Display for Msg { "{}\n{}", self.envelope.get_header_as_string(), self.body, - ) + ) } } @@ -878,7 +880,6 @@ impl TryFrom<&Fetch> for Msg { } else if body.html.is_none() && subpart.ctype.mimetype == "text/html" { body.html = subpart.get_body().ok(); } - // otherise it's a normal attachment, like a PNG file or // something like that else if let Some(attachment) = Attachment::from_parsed_mail(subpart) { @@ -891,7 +892,7 @@ impl TryFrom<&Fetch> for Msg { "[{}] Unknown attachment with the following mime-type: {}\n", "Warning".yellow(), subpart.ctype.mimetype, - ); + ); } } } @@ -1025,7 +1026,7 @@ mod tests { from: vec![String::from("Account Name ")], ..Envelope::default() }, - ); + ); let expected_with_custom_from = Msg { envelope: Envelope { // the Msg::new_with_envelope function should use the from @@ -1045,7 +1046,7 @@ mod tests { "Left: {:?}, Right: {:?}", dbg!(&msg_with_custom_from), dbg!(&expected_with_custom_from) - ); + ); } #[test] @@ -1078,7 +1079,7 @@ mod tests { "Left: {:?}, Right: {:?}", dbg!(&msg_with_custom_signature), dbg!(&expected_with_custom_signature) - ); + ); } #[test] @@ -1110,8 +1111,8 @@ mod tests { ..Envelope::default() }, body: Body::new_with_text(concat![ - "This is a message just to say hello.\n", - "So, \"Hello\".", + "This is a message just to say hello.\n", + "So, \"Hello\".", ]), ..Msg::default() }; @@ -1133,8 +1134,8 @@ mod tests { "Name ".to_string(), ], cc: Some(vec![ - "test@testing".to_string(), - "test2@testing".to_string(), + "test@testing".to_string(), + "test2@testing".to_string(), ]), message_id: Some("RandomID123".to_string()), reply_to: Some(vec!["Reply@Mail.rofl".to_string()]), @@ -1153,7 +1154,7 @@ mod tests { from: vec!["Mary Smith ".to_string()], to: vec!["John Doe ".to_string()], reply_to: Some(vec![ - "\"Mary Smith: Personal Account\" ".to_string(), + "\"Mary Smith: Personal Account\" ".to_string(), ]), subject: Some("Re: Saying Hello".to_string()), message_id: Some("<3456@example.net>".to_string()), @@ -1161,8 +1162,8 @@ mod tests { ..Envelope::default() }, body: Body::new_with_text(concat![ - "> This is a message just to say hello.\n", - "> So, \"Hello\".", + "> This is a message just to say hello.\n", + "> So, \"Hello\".", ]), ..Msg::default() }; @@ -1178,8 +1179,8 @@ mod tests { ..Envelope::default() }, body: Body::new_with_text(concat![ - ">> This is a message just to say hello.\n", - ">> So, \"Hello\".", + ">> This is a message just to say hello.\n", + ">> So, \"Hello\".", ]), ..Msg::default() }; @@ -1194,8 +1195,8 @@ mod tests { "Reply@Mail.rofl".to_string(), ], cc: Some(vec![ - "test@testing".to_string(), - "test2@testing".to_string(), + "test@testing".to_string(), + "test2@testing".to_string(), ]), in_reply_to: Some("RandomID123".to_string()), subject: Some("Re: Have you heard of himalaya?".to_string()), @@ -1215,7 +1216,7 @@ mod tests { rfc_reply_1.envelope = Envelope { message_id: Some("<3456@example.net>".to_string()), reply_to: Some(vec![ - "\"Mary Smith: Personal Account\" ".to_string(), + "\"Mary Smith: Personal Account\" ".to_string(), ]), ..rfc_reply_1.envelope.clone() }; @@ -1234,7 +1235,7 @@ mod tests { "Left: {:?}, Right: {:?}", dbg!(&rfc_reply_1), dbg!(&expected_rfc1) - ); + ); assert_eq!( rfc_reply_2, @@ -1242,7 +1243,7 @@ mod tests { "Left: {:?}, Right: {:?}", dbg!(&rfc_reply_2), dbg!(&expected_rfc2) - ); + ); // -- custom tests -— msg_reply_all.change_to_reply(&ctx, true).unwrap(); @@ -1252,7 +1253,7 @@ mod tests { "Left: {:?}, Right: {:?}", dbg!(&msg_reply_all), dbg!(&expected_reply_all) - ); + ); } #[test] @@ -1274,7 +1275,7 @@ mod tests { subject: Some(String::from("Test subject")), ..Envelope::default() }, - ); + ); msg.body = Body::new_with_text(concat!["The body text, nice!\n", "Himalaya is nice!",]); @@ -1288,11 +1289,11 @@ mod tests { ..Envelope::default() }, body: Body::new_with_text(concat![ - "\n-- \nlol\n", - "\n", - "---------- Forwarded Message ----------\n", - "The body text, nice!\n", - "Himalaya is nice!", + "\n-- \nlol\n", + "\n", + "---------- Forwarded Message ----------\n", + "The body text, nice!\n", + "Himalaya is nice!", ]), ..Msg::default() }; @@ -1305,7 +1306,7 @@ mod tests { "Left: {:?}, Right: {:?}", dbg!(&msg), dbg!(&expected_msg) - ); + ); } #[test] @@ -1327,7 +1328,7 @@ mod tests { subject: Some(String::new()), ..Envelope::default() }, - ); + ); // == Expected Results == let expected_msg = Msg { @@ -1352,7 +1353,7 @@ mod tests { "Left: {:?}, Right: {:?}", dbg!(&msg), dbg!(&expected_msg) - ); + ); } #[test] @@ -1396,8 +1397,8 @@ mod tests { from: vec![String::from("Some ")], subject: Some(String::from("Awesome Subject")), bcc: Some(vec![ - String::from("name "), - String::from("mail1@rofl.lol"), + String::from("name "), + String::from("mail1@rofl.lol"), ]), to: vec![String::from("To ")], ..Envelope::default() @@ -1416,8 +1417,8 @@ mod tests { from: vec![String::from("Some ")], subject: Some(String::from("Awesome Subject")), bcc: Some(vec![ - String::from("name "), - String::from("mail1@rofl.lol"), + String::from("name "), + String::from("mail1@rofl.lol"), ]), to: vec![String::from("To ")], custom_headers: Some(custom_headers), @@ -1440,7 +1441,7 @@ mod tests { "Left: {:?}, Right: {:?}", dbg!(&msg1), dbg!(&expect) - ); + ); assert_eq!( msg2, @@ -1448,6 +1449,6 @@ mod tests { "Left: {:?}, Right: {:?}", dbg!(&msg2), dbg!(&expect_custom_header) - ); + ); } } From ff15e0e96081a7cb202fe95c17f515791a77eab4 Mon Sep 17 00:00:00 2001 From: TornaxO7 Date: Sun, 22 Aug 2021 21:09:53 +0200 Subject: [PATCH 4/8] Formatting Formatted all files --- src/ctx.rs | 1 - src/msg/body.rs | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ctx.rs b/src/ctx.rs index 1ce8af5b..dc8c71e5 100644 --- a/src/ctx.rs +++ b/src/ctx.rs @@ -22,7 +22,6 @@ impl<'a> Ctx<'a> { mbox: S, arg_matches: clap::ArgMatches<'a>, ) -> Self { - let mbox = mbox.to_string(); Self { diff --git a/src/msg/body.rs b/src/msg/body.rs index e41e9b87..185335ce 100644 --- a/src/msg/body.rs +++ b/src/msg/body.rs @@ -32,7 +32,6 @@ pub struct Body { } impl Body { - /// Returns a new instance of `Body` without any attributes set. (Same as `Body::default()`) /// /// # Example @@ -53,7 +52,7 @@ impl Body { pub fn new() -> Self { Self::default() } - + /// Returns a new instance of `Body` with `text` set. /// /// # Example @@ -83,7 +82,7 @@ impl Body { /// # Example /// ```rust /// use himalaya::msg::body::Body; - /// + /// /// fn main() { /// let body = Body::new_with_html("Html body"); /// From e615c05d9299b30f08760f3f421d7713e627b180 Mon Sep 17 00:00:00 2001 From: TornaxO7 Date: Sun, 22 Aug 2021 21:47:54 +0200 Subject: [PATCH 5/8] Msg - Adding 'get_full_message' method which prints out all information of the message in a string --- src/msg/model.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/msg/model.rs b/src/msg/model.rs index 197ed54b..7e4e8cd9 100644 --- a/src/msg/model.rs +++ b/src/msg/model.rs @@ -732,6 +732,11 @@ impl Msg { pub fn get_encoding(&self) -> ContentTransferEncoding { self.envelope.encoding } + + /// Returns the whole message: Header + Body as a String + pub fn get_full_message(&self) -> String { + format!("{}\n{}", self.envelope.get_header_as_string(), self.body) + } } // -- Traits -- @@ -769,12 +774,7 @@ impl Default for Msg { impl fmt::Display for Msg { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!( - formatter, - "{}\n{}", - self.envelope.get_header_as_string(), - self.body, - ) + write!(formatter, "{}", self.body) } } From 229fbbe3fb6bb29d544566bba390c22b7eb0bf19 Mon Sep 17 00:00:00 2001 From: TornaxO7 Date: Tue, 24 Aug 2021 22:28:41 +0200 Subject: [PATCH 6/8] New Msg-Struct Adding MsgSerialized, a struct, which represents the "correct" serialized version of a message because it includes another attribute: `has_attachment`. --- src/msg/cli.rs | 11 +++--- src/msg/model.rs | 87 +++++++++++++++++++++++++++++++----------------- 2 files changed, 62 insertions(+), 36 deletions(-) diff --git a/src/msg/cli.rs b/src/msg/cli.rs index 0fb7188a..a27d329b 100644 --- a/src/msg/cli.rs +++ b/src/msg/cli.rs @@ -1,6 +1,6 @@ use super::body::Body; use super::envelope::Envelope; -use super::model::{Msg, Msgs}; +use super::model::{Msg, Msgs, MsgSerialized}; use url::Url; use atty::Stream; @@ -348,9 +348,8 @@ fn msg_matches_read(ctx: &Ctx, matches: &clap::ArgMatches) -> Result { if raw { ctx.output.print(msg.get_raw()?); } else { - ctx.output.print(msg); + ctx.output.print(MsgSerialized::from(&msg)); } - imap_conn.logout(); Ok(true) } @@ -779,7 +778,7 @@ fn tpl_matches_new(ctx: &Ctx, matches: &clap::ArgMatches) -> Result { override_msg_with_args(&mut msg, &matches); trace!("Message: {:?}", msg); - ctx.output.print(msg); + ctx.output.print(MsgSerialized::from(&msg)); Ok(true) } @@ -797,7 +796,7 @@ fn tpl_matches_reply(ctx: &Ctx, matches: &clap::ArgMatches) -> Result { override_msg_with_args(&mut msg, &matches); trace!("Message: {:?}", msg); - ctx.output.print(msg); + ctx.output.print(MsgSerialized::from(&msg)); Ok(true) } @@ -815,7 +814,7 @@ fn tpl_matches_forward(ctx: &Ctx, matches: &clap::ArgMatches) -> Result { override_msg_with_args(&mut msg, &matches); trace!("Message: {:?}", msg); - ctx.output.print(msg); + ctx.output.print(MsgSerialized::from(&msg)); Ok(true) } diff --git a/src/msg/model.rs b/src/msg/model.rs index 7e4e8cd9..c25215d1 100644 --- a/src/msg/model.rs +++ b/src/msg/model.rs @@ -17,8 +17,7 @@ use crate::{ #[cfg(not(test))] use crate::input; -use serde::ser::SerializeStruct; -use serde::{ser, Serialize}; +use serde::Serialize; use lettre::message::{ header::ContentTransferEncoding, header::ContentType, Attachment as lettre_Attachment, Mailbox, @@ -70,9 +69,37 @@ error_chain::error_chain! { } // == Msg == +/// Represents the msg in a serializeable form with additional values. +#[derive(Serialize, Clone, Debug, Eq, PartialEq)] +pub struct MsgSerialized { + /// First of all, the messge in general + #[serde(flatten)] + pub msg: Msg, + + /// A bool which indicates if the current msg includes attachments or not. + pub has_attachment: bool, +} + +impl From<&Msg> for MsgSerialized { + fn from(msg: &Msg) -> Self { + let has_attachment = msg.attachments.len() > 0; + + Self { + msg: msg.clone(), + has_attachment, + } + } +} + +impl fmt::Display for MsgSerialized { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "{}", self.msg.body) + } +} + /// This struct represents a whole msg with its attachments, body-content /// and its envelope. -#[derive(Debug, PartialEq, Eq, Clone)] +#[derive(Debug, PartialEq, Eq, Clone, Serialize)] pub struct Msg { /// All added attachments are listed in this vector. pub attachments: Vec, @@ -740,21 +767,21 @@ impl Msg { } // -- Traits -- -impl ser::Serialize for Msg { - fn serialize(&self, serializer: S) -> core::result::Result - where - S: ser::Serializer, - { - let mut state = serializer.serialize_struct("Msg", 6)?; - state.serialize_field("hasAttachment", &(self.attachments.len() > 0))?; - state.serialize_field("flags", &self.flags)?; - state.serialize_field("envelope", &self.envelope)?; - state.serialize_field("body", &self.body)?; - state.serialize_field("uid", &self.uid)?; - state.serialize_field("date", &self.date)?; - state.end() - } -} +// impl ser::Serialize for Msg { +// fn serialize(&self, serializer: S) -> core::result::Result +// where +// S: ser::Serializer, +// { +// let mut state = serializer.serialize_struct("Msg", 6)?; +// state.serialize_field("hasAttachment", &(self.attachments.len() > 0))?; +// state.serialize_field("flags", &self.flags)?; +// state.serialize_field("envelope", &self.envelope)?; +// state.serialize_field("body", &self.body)?; +// state.serialize_field("uid", &self.uid)?; +// state.serialize_field("date", &self.date)?; +// state.end() +// } +// } impl Default for Msg { fn default() -> Self { @@ -846,18 +873,18 @@ impl TryFrom<&Fetch> for Msg { // the fetch even includes a body or not, since the `BODY[]` query is // only *optional*! let parsed = - // the empty array represents an invalid body, so we can enter the - // `Err` arm if the body-query wasn't applied - match mailparse::parse_mail(raw.as_slice()) { - Ok(parsed) => { - debug!("Fetch has a body to parse."); - Some(parsed) - }, - Err(_) => { - debug!("Fetch hasn't a body to parse."); - None - }, - }; + // the empty array represents an invalid body, so we can enter the + // `Err` arm if the body-query wasn't applied + match mailparse::parse_mail(raw.as_slice()) { + Ok(parsed) => { + debug!("Fetch has a body to parse."); + Some(parsed) + }, + Err(_) => { + debug!("Fetch hasn't a body to parse."); + None + }, + }; // -- Storing the information (body) -- let mut body = Body::new(); From 783dc147ea605eb811ba9bd7d50b3e43a82fb7a3 Mon Sep 17 00:00:00 2001 From: TornaxO7 Date: Tue, 24 Aug 2021 22:31:34 +0200 Subject: [PATCH 7/8] Cleanup Removed the manual serialize implementation of `Msg` and added a little more info about the MsgSerialized. --- src/msg/model.rs | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/src/msg/model.rs b/src/msg/model.rs index c25215d1..af5cdc2e 100644 --- a/src/msg/model.rs +++ b/src/msg/model.rs @@ -70,6 +70,8 @@ error_chain::error_chain! { // == Msg == /// Represents the msg in a serializeable form with additional values. +/// This struct-type makes it also possible to print the msg in a serialized form or in a normal +/// form. #[derive(Serialize, Clone, Debug, Eq, PartialEq)] pub struct MsgSerialized { /// First of all, the messge in general @@ -767,22 +769,6 @@ impl Msg { } // -- Traits -- -// impl ser::Serialize for Msg { -// fn serialize(&self, serializer: S) -> core::result::Result -// where -// S: ser::Serializer, -// { -// let mut state = serializer.serialize_struct("Msg", 6)?; -// state.serialize_field("hasAttachment", &(self.attachments.len() > 0))?; -// state.serialize_field("flags", &self.flags)?; -// state.serialize_field("envelope", &self.envelope)?; -// state.serialize_field("body", &self.body)?; -// state.serialize_field("uid", &self.uid)?; -// state.serialize_field("date", &self.date)?; -// state.end() -// } -// } - impl Default for Msg { fn default() -> Self { Self { From b79705ec9cd32d6aafcadffd5c0af8b57a092d3a Mon Sep 17 00:00:00 2001 From: TornaxO7 Date: Wed, 25 Aug 2021 21:44:26 +0200 Subject: [PATCH 8/8] Little changes - Used a better condition for checking if the message includes attachments or not - format fixes --- src/msg/model.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/msg/model.rs b/src/msg/model.rs index af5cdc2e..b80ab744 100644 --- a/src/msg/model.rs +++ b/src/msg/model.rs @@ -84,7 +84,7 @@ pub struct MsgSerialized { impl From<&Msg> for MsgSerialized { fn from(msg: &Msg) -> Self { - let has_attachment = msg.attachments.len() > 0; + let has_attachment = msg.attachments.is_empty(); Self { msg: msg.clone(), @@ -859,18 +859,18 @@ impl TryFrom<&Fetch> for Msg { // the fetch even includes a body or not, since the `BODY[]` query is // only *optional*! let parsed = - // the empty array represents an invalid body, so we can enter the - // `Err` arm if the body-query wasn't applied - match mailparse::parse_mail(raw.as_slice()) { - Ok(parsed) => { - debug!("Fetch has a body to parse."); - Some(parsed) - }, - Err(_) => { - debug!("Fetch hasn't a body to parse."); - None - }, - }; + // the empty array represents an invalid body, so we can enter the + // `Err` arm if the body-query wasn't applied + match mailparse::parse_mail(raw.as_slice()) { + Ok(parsed) => { + debug!("Fetch has a body to parse."); + Some(parsed) + }, + Err(_) => { + debug!("Fetch hasn't a body to parse."); + None + }, + }; // -- Storing the information (body) -- let mut body = Body::new();