diff --git a/Cargo.toml b/Cargo.toml index ddded87..d71096f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ fastrand = { version = "1.4", optional = true } quoted_printable = { version = "0.4", optional = true } base64 = { version = "0.13", optional = true } regex = { version = "1", default-features = false, features = ["std", "unicode-case"] } -email-encoding = { git = "https://github.com/lettre/email-encoding.git", rev = "9b55bae0ed02ca52f6fb86a82b4814baa712e45a", optional = true } +email-encoding = { git = "https://github.com/lettre/email-encoding.git", rev = "9703887cc41cb1c7a8ff820f963622dd212e97d8", optional = true } # file transport uuid = { version = "0.8", features = ["v4"], optional = true } diff --git a/src/message/header/mailbox.rs b/src/message/header/mailbox.rs index f39ad85..9c17e13 100644 --- a/src/message/header/mailbox.rs +++ b/src/message/header/mailbox.rs @@ -1,3 +1,5 @@ +use email_encoding::headers::EmailWriter; + use super::{Header, HeaderName, HeaderValue}; use crate::{ message::mailbox::{Mailbox, Mailboxes}, @@ -26,7 +28,12 @@ macro_rules! mailbox_header { } fn display(&self) -> HeaderValue { - HeaderValue::new(Self::name(),self.0.to_string()) + let mut encoded_value = String::new(); + let line_len = $header_name.len() + ": ".len(); + let mut w = EmailWriter::new(&mut encoded_value, line_len, false); + self.0.encode(&mut w).expect("writing `Mailbox` returned an error"); + + HeaderValue::dangerous_new_pre_encoded(Self::name(), self.0.to_string(), encoded_value) } } @@ -69,8 +76,13 @@ macro_rules! mailboxes_header { } fn display(&self) -> HeaderValue { - HeaderValue::new(Self::name(),self.0.to_string()) - } + let mut encoded_value = String::new(); + let line_len = $header_name.len() + ": ".len(); + let mut w = EmailWriter::new(&mut encoded_value, line_len, false); + self.0.encode(&mut w).expect("writing `Mailboxes` returned an error"); + + HeaderValue::dangerous_new_pre_encoded(Self::name(), self.0.to_string(), encoded_value) + } } impl std::convert::From for $type_name { diff --git a/src/message/mailbox/types.rs b/src/message/mailbox/types.rs index 74b4acb..b2aa8dc 100644 --- a/src/message/mailbox/types.rs +++ b/src/message/mailbox/types.rs @@ -1,10 +1,13 @@ use std::{ convert::TryFrom, fmt::{Display, Formatter, Result as FmtResult, Write}, + mem, slice::Iter, str::FromStr, }; +use email_encoding::headers::EmailWriter; + use crate::address::{Address, AddressError}; /// Represents an email address with an optional name for the sender/recipient. @@ -64,6 +67,22 @@ impl Mailbox { pub fn new(name: Option, email: Address) -> Self { Mailbox { name, email } } + + pub(crate) fn encode(&self, w: &mut EmailWriter<'_>) -> FmtResult { + if let Some(name) = &self.name { + email_encoding::headers::quoted_string::encode(name, w)?; + w.space(); + w.write_char('<')?; + } + + w.write_str(self.email.as_ref())?; + + if self.name.is_some() { + w.write_char('>')?; + } + + Ok(()) + } } impl Display for Mailbox { @@ -251,6 +270,20 @@ impl Mailboxes { pub fn iter(&self) -> Iter<'_, Mailbox> { self.0.iter() } + + pub(crate) fn encode(&self, w: &mut EmailWriter<'_>) -> FmtResult { + let mut first = true; + for mailbox in self.iter() { + if !mem::take(&mut first) { + w.write_char(',')?; + w.space(); + } + + mailbox.encode(w)?; + } + + Ok(()) + } } impl Default for Mailboxes {