diff --git a/email-manager/src/config/account_entity.rs b/email-manager/src/config/account_entity.rs index fae37bb..a952daf 100644 --- a/email-manager/src/config/account_entity.rs +++ b/email-manager/src/config/account_entity.rs @@ -51,7 +51,7 @@ impl Account { let has_special_chars = "()<>[]:;@.,".contains(|special_char| name.contains(special_char)); if name.is_empty() { - format!("{}", self.email) + self.email.clone() } else if has_special_chars { // so the name has special characters => Wrap it with '"' format!("\"{}\" <{}>", name, self.email) @@ -112,7 +112,7 @@ impl<'a> TryFrom<(&'a Config, Option<&str>)> for Account { .and_then(|dir| shellexpand::full(dir).ok()) .map(|dir| PathBuf::from(dir.to_string())) }) - .unwrap_or_else(|| env::temp_dir()); + .unwrap_or_else(env::temp_dir); let default_page_size = account .default_page_size @@ -146,24 +146,21 @@ impl<'a> TryFrom<(&'a Config, Option<&str>)> for Account { default_page_size, inbox_folder: account .inbox_folder - .as_ref() - .map(|s| s.as_str()) - .or(config.inbox_folder.as_ref().map(|s| s.as_str())) - .unwrap_or(&DEFAULT_INBOX_FOLDER) + .as_deref() + .or_else(|| config.inbox_folder.as_deref()) + .unwrap_or(DEFAULT_INBOX_FOLDER) .to_string(), sent_folder: account .sent_folder - .as_ref() - .map(|s| s.as_str()) - .or(config.sent_folder.as_ref().map(|s| s.as_str())) - .unwrap_or(&DEFAULT_SENT_FOLDER) + .as_deref() + .or_else(|| config.sent_folder.as_deref()) + .unwrap_or(DEFAULT_SENT_FOLDER) .to_string(), draft_folder: account .draft_folder - .as_ref() - .map(|s| s.as_str()) - .or(config.draft_folder.as_ref().map(|s| s.as_str())) - .unwrap_or(&DEFAULT_DRAFT_FOLDER) + .as_deref() + .or_else(|| config.draft_folder.as_deref()) + .unwrap_or(DEFAULT_DRAFT_FOLDER) .to_string(), watch_cmds: account .watch_cmds diff --git a/email-manager/src/domain/imap/imap_handler.rs b/email-manager/src/domain/imap/imap_handler.rs index 2a43684..6f7b132 100644 --- a/email-manager/src/domain/imap/imap_handler.rs +++ b/email-manager/src/domain/imap/imap_handler.rs @@ -12,7 +12,7 @@ pub fn notify<'a, ImapService: ImapServiceInterface<'a>>( config: &Config, imap: &mut ImapService, ) -> Result<()> { - imap.notify(&config, keepalive) + imap.notify(config, keepalive) } /// Watch handler. diff --git a/email-manager/src/domain/imap/imap_service.rs b/email-manager/src/domain/imap/imap_service.rs index d51bb21..01b4560 100644 --- a/email-manager/src/domain/imap/imap_service.rs +++ b/email-manager/src/domain/imap/imap_service.rs @@ -8,7 +8,6 @@ use native_tls::{TlsConnector, TlsStream}; use std::{ collections::HashSet, convert::{TryFrom, TryInto}, - iter::FromIterator, net::TcpStream, }; @@ -58,7 +57,7 @@ pub struct ImapService<'a> { impl<'a> ImapService<'a> { fn sess(&mut self) -> Result<&mut ImapSession> { - if let None = self.sess { + if self.sess.is_none() { debug!("create TLS builder"); debug!("insecure: {}", self.account.imap_insecure); let builder = TlsConnector::builder() @@ -148,7 +147,7 @@ impl<'a> ImapServiceInterface<'a> for ImapService<'a> { .fetch(range, "(ENVELOPE FLAGS INTERNALDATE)") .context(r#"cannot fetch messages within range "{}""#)?; self._raw_msgs_cache = Some(fetches); - Ok(Envelopes::try_from(self._raw_msgs_cache.as_ref().unwrap())?) + Envelopes::try_from(self._raw_msgs_cache.as_ref().unwrap()) } fn fetch_envelopes_with( @@ -186,7 +185,7 @@ impl<'a> ImapServiceInterface<'a> for ImapService<'a> { .fetch(&range, "(ENVELOPE FLAGS INTERNALDATE)") .context(r#"cannot fetch messages within range "{}""#)?; self._raw_msgs_cache = Some(fetches); - Ok(Envelopes::try_from(self._raw_msgs_cache.as_ref().unwrap())?) + Envelopes::try_from(self._raw_msgs_cache.as_ref().unwrap()) } /// Find a message by sequence number. @@ -201,9 +200,9 @@ impl<'a> ImapServiceInterface<'a> for ImapService<'a> { .context(r#"cannot fetch messages "{}""#)?; let fetch = fetches .first() - .ok_or(anyhow!(r#"cannot find message "{}"#, seq))?; + .ok_or_else(|| anyhow!(r#"cannot find message "{}"#, seq))?; - Ok(Msg::try_from(fetch)?) + Msg::try_from(fetch) } fn find_raw_msg(&mut self, seq: &str) -> Result> { @@ -217,14 +216,14 @@ impl<'a> ImapServiceInterface<'a> for ImapService<'a> { .context(r#"cannot fetch raw messages "{}""#)?; let fetch = fetches .first() - .ok_or(anyhow!(r#"cannot find raw message "{}"#, seq))?; + .ok_or_else(|| anyhow!(r#"cannot find raw message "{}"#, seq))?; Ok(fetch.body().map(Vec::from).unwrap_or_default()) } fn append_raw_msg_with_flags(&mut self, mbox: &Mbox, msg: &[u8], flags: Flags) -> Result<()> { self.sess()? - .append(&mbox.name, &msg) + .append(&mbox.name, msg) .flags(flags.0) .finish() .context(format!(r#"cannot append message to "{}""#, mbox.name))?; @@ -250,8 +249,11 @@ impl<'a> ImapServiceInterface<'a> for ImapService<'a> { .context(format!("cannot examine mailbox `{}`", &self.mbox.name))?; debug!("init messages hashset"); - let mut msgs_set: HashSet = - HashSet::from_iter(self.search_new_msgs()?.iter().cloned()); + let mut msgs_set: HashSet = self + .search_new_msgs()? + .iter() + .cloned() + .collect::>(); trace!("messages hashset: {:?}", msgs_set); loop { @@ -271,7 +273,7 @@ impl<'a> ImapServiceInterface<'a> for ImapService<'a> { let uids: Vec = self .search_new_msgs()? .into_iter() - .filter(|uid| msgs_set.get(&uid).is_none()) + .filter(|uid| -> bool { msgs_set.get(uid).is_none() }) .collect(); debug!("found {} new messages not in hashset", uids.len()); trace!("messages hashet: {:?}", msgs_set); diff --git a/email-manager/src/domain/mbox/mboxes_entity.rs b/email-manager/src/domain/mbox/mboxes_entity.rs index 4c437f0..e5a0130 100644 --- a/email-manager/src/domain/mbox/mboxes_entity.rs +++ b/email-manager/src/domain/mbox/mboxes_entity.rs @@ -32,7 +32,7 @@ impl<'a> Deref for Mboxes<'a> { impl<'a> PrintTable for Mboxes<'a> { fn print_table(&self, writter: &mut dyn WriteColor, opts: PrintTableOpts) -> Result<()> { writeln!(writter)?; - Table::print(writter, &self, opts)?; + Table::print(writter, self, opts)?; writeln!(writter)?; Ok(()) } diff --git a/email-manager/src/domain/msg/envelope_entity.rs b/email-manager/src/domain/msg/envelope_entity.rs index 013e760..c3384f5 100644 --- a/email-manager/src/domain/msg/envelope_entity.rs +++ b/email-manager/src/domain/msg/envelope_entity.rs @@ -39,7 +39,7 @@ impl<'a> TryFrom<&'a RawEnvelope> for Envelope<'a> { fn try_from(fetch: &'a RawEnvelope) -> Result { let envelope = fetch .envelope() - .ok_or(anyhow!("cannot get envelope of message {}", fetch.message))?; + .ok_or_else(|| anyhow!("cannot get envelope of message {}", fetch.message))?; // Get the sequence number let id = fetch.message; @@ -57,7 +57,7 @@ impl<'a> TryFrom<&'a RawEnvelope> for Envelope<'a> { fetch.message )) }) - .unwrap_or(Ok(String::default()))? + .unwrap_or_else(|| Ok(String::default()))? .into(); // Get the sender @@ -66,7 +66,7 @@ impl<'a> TryFrom<&'a RawEnvelope> for Envelope<'a> { .as_ref() .and_then(|addrs| addrs.get(0)) .or_else(|| envelope.from.as_ref().and_then(|addrs| addrs.get(0))) - .ok_or(anyhow!("cannot get sender of message {}", fetch.message))?; + .ok_or_else(|| anyhow!("cannot get sender of message {}", fetch.message))?; let sender = if let Some(ref name) = sender.name { rfc2047_decoder::decode(&name.to_vec()).context(format!( "cannot decode sender's name of message {}", @@ -76,10 +76,7 @@ impl<'a> TryFrom<&'a RawEnvelope> for Envelope<'a> { let mbox = sender .mailbox .as_ref() - .ok_or(anyhow!( - "cannot get sender's mailbox of message {}", - fetch.message - )) + .ok_or_else(|| anyhow!("cannot get sender's mailbox of message {}", fetch.message)) .and_then(|mbox| { rfc2047_decoder::decode(&mbox.to_vec()).context(format!( "cannot decode sender's mailbox of message {}", @@ -89,10 +86,7 @@ impl<'a> TryFrom<&'a RawEnvelope> for Envelope<'a> { let host = sender .host .as_ref() - .ok_or(anyhow!( - "cannot get sender's host of message {}", - fetch.message - )) + .ok_or_else(|| anyhow!("cannot get sender's host of message {}", fetch.message)) .and_then(|host| { rfc2047_decoder::decode(&host.to_vec()).context(format!( "cannot decode sender's host of message {}", @@ -133,11 +127,7 @@ impl<'a> Table for Envelope<'a> { let unseen = !self.flags.contains(&Flag::Seen); let subject = &self.subject; let sender = &self.sender; - let date = self - .date - .as_ref() - .map(|date| date.as_str()) - .unwrap_or_default(); + let date = self.date.as_deref().unwrap_or_default(); Row::new() .cell(Cell::new(id).bold_if(unseen).red()) .cell(Cell::new(flags).bold_if(unseen).white()) diff --git a/email-manager/src/domain/msg/envelopes_entity.rs b/email-manager/src/domain/msg/envelopes_entity.rs index 6402317..802153f 100644 --- a/email-manager/src/domain/msg/envelopes_entity.rs +++ b/email-manager/src/domain/msg/envelopes_entity.rs @@ -39,7 +39,7 @@ impl<'a> TryFrom<&'a RawEnvelopes> for Envelopes<'a> { impl<'a> PrintTable for Envelopes<'a> { fn print_table(&self, writter: &mut dyn WriteColor, opts: PrintTableOpts) -> Result<()> { writeln!(writter)?; - Table::print(writter, &self, opts)?; + Table::print(writter, self, opts)?; writeln!(writter)?; Ok(()) } diff --git a/email-manager/src/domain/msg/flags_entity.rs b/email-manager/src/domain/msg/flags_entity.rs index 2ed3872..bc8590b 100644 --- a/email-manager/src/domain/msg/flags_entity.rs +++ b/email-manager/src/domain/msg/flags_entity.rs @@ -126,16 +126,14 @@ impl<'a> From> for Flags { let mut map: HashSet> = HashSet::new(); for f in flags { - match f { - "Answered" | _ if f.eq_ignore_ascii_case("answered") => map.insert(Flag::Answered), - "Deleted" | _ if f.eq_ignore_ascii_case("deleted") => map.insert(Flag::Deleted), - "Draft" | _ if f.eq_ignore_ascii_case("draft") => map.insert(Flag::Draft), - "Flagged" | _ if f.eq_ignore_ascii_case("flagged") => map.insert(Flag::Flagged), - "MayCreate" | _ if f.eq_ignore_ascii_case("maycreate") => { - map.insert(Flag::MayCreate) - } - "Recent" | _ if f.eq_ignore_ascii_case("recent") => map.insert(Flag::Recent), - "Seen" | _ if f.eq_ignore_ascii_case("seen") => map.insert(Flag::Seen), + match f.to_lowercase().as_str() { + "answered" => map.insert(Flag::Answered), + "deleted" => map.insert(Flag::Deleted), + "draft" => map.insert(Flag::Draft), + "flagged" => map.insert(Flag::Flagged), + "maycreate" => map.insert(Flag::MayCreate), + "recent" => map.insert(Flag::Recent), + "seen" => map.insert(Flag::Seen), custom => map.insert(Flag::Custom(Cow::Owned(custom.into()))), }; } diff --git a/email-manager/src/domain/msg/msg_arg.rs b/email-manager/src/domain/msg/msg_arg.rs index 989a8f4..4f91eac 100644 --- a/email-manager/src/domain/msg/msg_arg.rs +++ b/email-manager/src/domain/msg/msg_arg.rs @@ -200,11 +200,11 @@ pub fn matches<'a>(m: &'a ArgMatches) -> Result>> { } if let Some(m) = m.subcommand_matches("template") { - return Ok(Some(Command::Tpl(tpl_arg::matches(&m)?))); + return Ok(Some(Command::Tpl(tpl_arg::matches(m)?))); } if let Some(m) = m.subcommand_matches("flag") { - return Ok(Some(Command::Flag(flag_arg::matches(&m)?))); + return Ok(Some(Command::Flag(flag_arg::matches(m)?))); } debug!("default list command matched"); diff --git a/email-manager/src/domain/msg/msg_entity.rs b/email-manager/src/domain/msg/msg_entity.rs index d051dae..13f2ec1 100644 --- a/email-manager/src/domain/msg/msg_entity.rs +++ b/email-manager/src/domain/msg/msg_entity.rs @@ -194,14 +194,18 @@ impl Msg { .date .as_ref() .map(|date| date.format("%d %b %Y, at %H:%M").to_string()) - .unwrap_or("unknown date".into()); + .unwrap_or_else(|| "unknown date".into()); let sender = self .reply_to .as_ref() - .or(self.from.as_ref()) + .or_else(|| self.from.as_ref()) .and_then(|addrs| addrs.first()) - .map(|addr| addr.name.to_owned().unwrap_or(addr.email.to_string())) - .unwrap_or("unknown sender".into()); + .map(|addr| { + addr.name + .to_owned() + .unwrap_or_else(|| addr.email.to_string()) + }) + .unwrap_or_else(|| "unknown sender".into()); let mut content = format!("\n\nOn {}, {} wrote:\n", date, sender); let mut glue = ""; @@ -210,8 +214,8 @@ impl Msg { break; } content.push_str(glue); - content.push_str(">"); - content.push_str(if line.starts_with(">") { "" } else { " " }); + content.push('>'); + content.push_str(if line.starts_with('>') { "" } else { " " }); content.push_str(line); glue = "\n"; } @@ -239,7 +243,7 @@ impl Msg { self.in_reply_to = None; // From - self.from = Some(vec![account_addr.to_owned()]); + self.from = Some(vec![account_addr]); // To self.to = Some(vec![]); @@ -270,7 +274,7 @@ impl Msg { content.push_str(&addr.to_string()); glue = ", "; } - content.push_str("\n"); + content.push('\n'); } if let Some(addrs) = prev_to.as_ref() { content.push_str("To: "); @@ -280,9 +284,9 @@ impl Msg { content.push_str(&addr.to_string()); glue = ", "; } - content.push_str("\n"); + content.push('\n'); } - content.push_str("\n"); + content.push('\n'); content.push_str(&self.fold_text_parts("plain")); self.parts .replace_text_plain_parts_with(TextPlainPart { content }); @@ -386,7 +390,7 @@ impl Msg { let path = PathBuf::from(path.to_string()); let filename: String = path .file_name() - .ok_or(anyhow!("cannot get file name of attachment {:?}", path))? + .ok_or_else(|| anyhow!("cannot get file name of attachment {:?}", path))? .to_string_lossy() .into(); let content = fs::read(&path).context(format!("cannot read attachment {:?}", path))?; @@ -427,17 +431,11 @@ impl Msg { match part { Part::Binary(_) => self.parts.push(part), Part::TextPlain(_) => { - self.parts.retain(|p| match p { - Part::TextPlain(_) => false, - _ => true, - }); + self.parts.retain(|p| !matches!(p, Part::TextPlain(_))); self.parts.push(part); } Part::TextHtml(_) => { - self.parts.retain(|p| match p { - Part::TextHtml(_) => false, - _ => true, - }); + self.parts.retain(|p| !matches!(p, Part::TextHtml(_))); self.parts.push(part); } } @@ -507,7 +505,7 @@ impl Msg { )); // Headers <=> body separator - tpl.push_str("\n"); + tpl.push('\n'); // Body if let Some(body) = opts.body { @@ -525,7 +523,7 @@ impl Msg { tpl.push_str(sig); } - tpl.push_str("\n"); + tpl.push('\n'); trace!("template: {:#?}", tpl); tpl @@ -542,49 +540,45 @@ impl Msg { let val = String::from_utf8(header.get_value_raw().to_vec()) .map(|val| val.trim().to_string())?; - match key.as_str() { - "Message-Id" | _ if key.eq_ignore_ascii_case("message-id") => { - msg.message_id = Some(val.to_owned()) - } - "From" | _ if key.eq_ignore_ascii_case("from") => { + match key.to_lowercase().as_str() { + "message-id" => msg.message_id = Some(val.to_owned()), + "from" => { msg.from = Some( val.split(',') .filter_map(|addr| addr.parse().ok()) .collect::>(), ); } - "To" | _ if key.eq_ignore_ascii_case("to") => { + "to" => { msg.to = Some( val.split(',') .filter_map(|addr| addr.parse().ok()) .collect::>(), ); } - "Reply-To" | _ if key.eq_ignore_ascii_case("reply-to") => { + "reply-to" => { msg.reply_to = Some( val.split(',') .filter_map(|addr| addr.parse().ok()) .collect::>(), ); } - "In-Reply-To" | _ if key.eq_ignore_ascii_case("in-reply-to") => { - msg.in_reply_to = Some(val.to_owned()) - } - "Cc" | _ if key.eq_ignore_ascii_case("cc") => { + "in-reply-to" => msg.in_reply_to = Some(val.to_owned()), + "cc" => { msg.cc = Some( val.split(',') .filter_map(|addr| addr.parse().ok()) .collect::>(), ); } - "Bcc" | _ if key.eq_ignore_ascii_case("bcc") => { + "bcc" => { msg.bcc = Some( val.split(',') .filter_map(|addr| addr.parse().ok()) .collect::>(), ); } - "Subject" | _ if key.eq_ignore_ascii_case("subject") => { + "subject" => { msg.subject = val; } _ => (), @@ -696,7 +690,7 @@ impl<'a> TryFrom<&'a imap::types::Fetch> for Msg { fn try_from(fetch: &'a imap::types::Fetch) -> Result { let envelope = fetch .envelope() - .ok_or(anyhow!("cannot get envelope of message {}", fetch.message))?; + .ok_or_else(|| anyhow!("cannot get envelope of message {}", fetch.message))?; // Get the sequence number let id = fetch.message; @@ -714,13 +708,13 @@ impl<'a> TryFrom<&'a imap::types::Fetch> for Msg { fetch.message )) }) - .unwrap_or(Ok(String::default()))?; + .unwrap_or_else(|| Ok(String::default()))?; // Get the sender(s) address(es) let from = match envelope .sender - .as_ref() - .or_else(|| envelope.from.as_ref()) + .as_deref() + .or_else(|| envelope.from.as_deref()) .map(parse_addrs) { Some(addrs) => Some(addrs?), @@ -773,7 +767,7 @@ impl<'a> TryFrom<&'a imap::types::Fetch> for Msg { &mailparse::parse_mail( fetch .body() - .ok_or(anyhow!("cannot get body of message {}", id))?, + .ok_or_else(|| anyhow!("cannot get body of message {}", id))?, ) .context(format!("cannot parse body of message {}", id))?, ); @@ -782,13 +776,13 @@ impl<'a> TryFrom<&'a imap::types::Fetch> for Msg { id, flags, subject, - message_id, from, reply_to, - in_reply_to, to, cc, bcc, + in_reply_to, + message_id, date, parts, }) @@ -802,20 +796,20 @@ pub fn parse_addr(addr: &imap_proto::Address) -> Result { .map(|name| { rfc2047_decoder::decode(&name.to_vec()) .context("cannot decode address name") - .map(|name| Some(name)) + .map(Some) }) .unwrap_or(Ok(None))?; let mbox = addr .mailbox .as_ref() - .ok_or(anyhow!("cannot get address mailbox")) + .ok_or_else(|| anyhow!("cannot get address mailbox")) .and_then(|mbox| { rfc2047_decoder::decode(&mbox.to_vec()).context("cannot decode address mailbox") })?; let host = addr .host .as_ref() - .ok_or(anyhow!("cannot get address host")) + .ok_or_else(|| anyhow!("cannot get address host")) .and_then(|host| { rfc2047_decoder::decode(&host.to_vec()).context("cannot decode address host") })?; @@ -823,7 +817,7 @@ pub fn parse_addr(addr: &imap_proto::Address) -> Result { Ok(Addr::new(name, lettre::Address::new(mbox, host)?)) } -pub fn parse_addrs(addrs: &Vec) -> Result> { +pub fn parse_addrs(addrs: &[imap_proto::Address]) -> Result> { let mut parsed_addrs = vec![]; for addr in addrs { parsed_addrs @@ -833,7 +827,7 @@ pub fn parse_addrs(addrs: &Vec) -> Result> { } pub fn parse_some_addrs(addrs: &Option>) -> Result>> { - Ok(match addrs.as_ref().map(parse_addrs) { + Ok(match addrs.as_deref().map(parse_addrs) { Some(addrs) => Some(addrs?), None => None, }) diff --git a/email-manager/src/domain/msg/msg_handler.rs b/email-manager/src/domain/msg/msg_handler.rs index 41c70ba..c93a5e4 100644 --- a/email-manager/src/domain/msg/msg_handler.rs +++ b/email-manager/src/domain/msg/msg_handler.rs @@ -21,6 +21,7 @@ use crate::{ mbox::Mbox, msg::{Flags, Msg, Part, TextPlainPart}, smtp::SmtpServiceInterface, + Parts, }, output::{PrintTableOpts, PrinterService}, }; @@ -32,7 +33,7 @@ pub fn attachments<'a, Printer: PrinterService, ImapService: ImapServiceInterfac printer: &mut Printer, imap: &mut ImapService, ) -> Result<()> { - let attachments = imap.find_msg(&seq)?.attachments(); + let attachments = imap.find_msg(seq)?.attachments(); let attachments_len = attachments.len(); debug!( r#"{} attachment(s) found for message "{}""#, @@ -60,7 +61,7 @@ pub fn copy<'a, Printer: PrinterService, ImapService: ImapServiceInterface<'a>>( imap: &mut ImapService, ) -> Result<()> { let mbox = Mbox::new(mbox); - let msg = imap.find_raw_msg(&seq)?; + let msg = imap.find_raw_msg(seq)?; let flags = Flags::try_from(vec![Flag::Seen])?; imap.append_raw_msg_with_flags(&mbox, &msg, flags)?; printer.print(format!( @@ -135,7 +136,7 @@ pub fn mailto< ) -> Result<()> { let to: Vec = url .path() - .split(";") + .split(';') .filter_map(|s| s.parse().ok()) .collect(); let mut cc = Vec::new(); @@ -161,16 +162,18 @@ pub fn mailto< } } - let mut msg = Msg::default(); + let msg = Msg { + from: Some(vec![account.address().parse()?]), + to: if to.is_empty() { None } else { Some(to) }, + cc: if cc.is_empty() { None } else { Some(cc) }, + bcc: if bcc.is_empty() { None } else { Some(bcc) }, + subject: subject.into(), + parts: Parts(vec![Part::TextPlain(TextPlainPart { + content: body.into(), + })]), + ..Msg::default() + }; - msg.from = Some(vec![account.address().parse()?]); - msg.to = if to.is_empty() { None } else { Some(to) }; - msg.cc = if cc.is_empty() { None } else { Some(cc) }; - msg.bcc = if bcc.is_empty() { None } else { Some(bcc) }; - msg.subject = subject.into(); - msg.parts.push(Part::TextPlain(TextPlainPart { - content: body.into(), - })); msg.edit_with_editor(account, printer, imap, smtp) } @@ -185,7 +188,7 @@ pub fn move_<'a, Printer: PrinterService, ImapService: ImapServiceInterface<'a>> ) -> Result<()> { // Copy the message to targetted mailbox let mbox = Mbox::new(mbox); - let msg = imap.find_raw_msg(&seq)?; + let msg = imap.find_raw_msg(seq)?; let flags = Flags::try_from(vec![Flag::Seen])?; imap.append_raw_msg_with_flags(&mbox, &msg, flags)?; @@ -210,9 +213,9 @@ pub fn read<'a, Printer: PrinterService, ImapService: ImapServiceInterface<'a>>( ) -> Result<()> { let msg = if raw { // Emails don't always have valid utf8. Using "lossy" to display what we can. - String::from_utf8_lossy(&imap.find_raw_msg(&seq)?).into_owned() + String::from_utf8_lossy(&imap.find_raw_msg(seq)?).into_owned() } else { - imap.find_msg(&seq)?.fold_text_parts(text_mime) + imap.find_msg(seq)?.fold_text_parts(text_mime) }; printer.print(msg) @@ -254,8 +257,7 @@ pub fn save<'a, Printer: PrinterService, ImapService: ImapServiceInterface<'a>>( io::stdin() .lock() .lines() - .filter_map(|ln| ln.ok()) - .map(|ln| ln.to_string()) + .filter_map(Result::ok) .collect::>() .join("\r\n") }; @@ -301,13 +303,12 @@ pub fn send< io::stdin() .lock() .lines() - .filter_map(|ln| ln.ok()) - .map(|ln| ln.to_string()) + .filter_map(Result::ok) .collect::>() .join("\r\n") }; - let msg = Msg::from_tpl(&raw_msg.to_string())?; + let msg = Msg::from_tpl(&raw_msg)?; let envelope: lettre::address::Envelope = msg.try_into()?; smtp.send_raw_msg(&envelope, raw_msg.as_bytes())?; debug!("message sent!"); diff --git a/email-manager/src/domain/msg/parts_entity.rs b/email-manager/src/domain/msg/parts_entity.rs index cc8d6e1..51e80be 100644 --- a/email-manager/src/domain/msg/parts_entity.rs +++ b/email-manager/src/domain/msg/parts_entity.rs @@ -39,24 +39,12 @@ pub struct Parts(pub Vec); impl Parts { pub fn replace_text_plain_parts_with(&mut self, part: TextPlainPart) { - self.retain(|part| { - if let Part::TextPlain(_) = part { - false - } else { - true - } - }); + self.retain(|part| !matches!(part, Part::TextPlain(_))); self.push(Part::TextPlain(part)); } pub fn replace_text_html_parts_with(&mut self, part: TextHtmlPart) { - self.retain(|part| { - if let Part::TextHtml(_) = part { - false - } else { - true - } - }); + self.retain(|part| !matches!(part, Part::TextHtml(_))); self.push(Part::TextHtml(part)); } } @@ -92,7 +80,7 @@ fn build_parts_map_rec(part: &mailparse::ParsedMail, parts: &mut Vec) { .params .get("filename") .map(String::from) - .unwrap_or(String::from("noname")); + .unwrap_or_else(|| String::from("noname")); let content = part.get_body_raw().unwrap_or_default(); let mime = tree_magic::from_u8(&content); parts.push(Part::Binary(BinaryPart { @@ -103,16 +91,14 @@ fn build_parts_map_rec(part: &mailparse::ParsedMail, parts: &mut Vec) { } // TODO: manage other use cases _ => { - part.get_headers() - .get_first_value("content-type") - .map(|ctype| { - let content = part.get_body().unwrap_or_default(); - if ctype.starts_with("text/plain") { - parts.push(Part::TextPlain(TextPlainPart { content })) - } else if ctype.starts_with("text/html") { - parts.push(Part::TextHtml(TextHtmlPart { content })) - } - }); + if let Some(ctype) = part.get_headers().get_first_value("content-type") { + let content = part.get_body().unwrap_or_default(); + if ctype.starts_with("text/plain") { + parts.push(Part::TextPlain(TextPlainPart { content })) + } else if ctype.starts_with("text/html") { + parts.push(Part::TextHtml(TextHtmlPart { content })) + } + }; } }; } else { diff --git a/email-manager/src/main.rs b/email-manager/src/main.rs index 142d202..4d0d279 100644 --- a/email-manager/src/main.rs +++ b/email-manager/src/main.rs @@ -1,6 +1,4 @@ use anyhow::Result; -use clap; -use env_logger; use output::StdoutPrinter; use std::{convert::TryFrom, env}; use url::Url; @@ -36,6 +34,7 @@ fn create_app<'a>() -> clap::App<'a, 'a> { .subcommands(msg_arg::subcmds()) } +#[allow(clippy::single_match)] fn main() -> Result<()> { // Init env logger env_logger::init_from_env( diff --git a/email-manager/src/output/output_entity.rs b/email-manager/src/output/output_entity.rs index e92b488..0accfe0 100644 --- a/email-manager/src/output/output_entity.rs +++ b/email-manager/src/output/output_entity.rs @@ -36,9 +36,9 @@ impl TryFrom> for OutputFmt { impl Display for OutputFmt { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let fmt = match self { - &OutputFmt::Json => "JSON", - &OutputFmt::Plain => "Plain", + let fmt = match *self { + OutputFmt::Json => "JSON", + OutputFmt::Plain => "Plain", }; write!(f, "{}", fmt) } diff --git a/email-manager/src/ui/table.rs b/email-manager/src/ui/table.rs index b1739d7..3763b18 100644 --- a/email-manager/src/ui/table.rs +++ b/email-manager/src/ui/table.rs @@ -227,13 +227,11 @@ where trace!("number of spaces added to shrinked value: {}", spaces_count); value.push_str(&" ".repeat(spaces_count)); cell.value = value; - cell.print(writter)?; } else { trace!("cell is not overflowing"); let spaces_count = cell_width - cell.unicode_width() + 1; trace!("number of spaces added to value: {}", spaces_count); cell.value.push_str(&" ".repeat(spaces_count)); - cell.print(writter)?; } } else { trace!("table is not overflowing or cell is not shrinkable"); @@ -242,8 +240,8 @@ where let spaces_count = cell_widths[i] - cell.unicode_width() + 1; trace!("number of spaces added to value: {}", spaces_count); cell.value.push_str(&" ".repeat(spaces_count)); - cell.print(writter)?; } + cell.print(writter)?; glue = Cell::new("│").ansi_256(8); } writeln!(writter)?;