Skip to content

Commit

Permalink
Added mail_parser::Message to Message conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
soywod committed Feb 23, 2024
1 parent 17a45f5 commit 43895ab
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 1 deletion.
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ doctest = false
smtp-proto = { version = "0.1" }
mail-auth = { version = "0.3", optional = true }
mail-builder = { version = "0.3", optional = true }
mail-parser = { version = "0.9", optional = true }
base64 = "0.21"
rand = { version = "0.8.5", optional = true }
md5 = { version = "0.7.0", optional = true }
Expand All @@ -33,8 +34,9 @@ tokio = { version = "1.16", features = ["net", "io-util", "time", "rt-multi-thre
env_logger = "0.10.0"

[features]
default = ["digest-md5", "cram-md5", "builder", "dkim"]
default = ["digest-md5", "cram-md5", "builder", "parser", "dkim"]
builder = ["mail-builder"]
parser = ["mail-parser"]
dkim = ["mail-auth"]
digest-md5 = ["md5", "rand"]
cram-md5 = ["md5"]
67 changes: 67 additions & 0 deletions src/smtp/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use mail_builder::{
headers::{address, HeaderType},
MessageBuilder,
};
#[cfg(feature = "parser")]
use mail_parser::{HeaderName, HeaderValue};
use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt};

use crate::SmtpClient;
Expand Down Expand Up @@ -348,3 +350,68 @@ impl<'x, 'y> IntoMessage<'x> for MessageBuilder<'y> {
})
}
}

#[cfg(feature = "parser")]
impl<'x> IntoMessage<'x> for mail_parser::Message<'x> {
fn into_message(self) -> crate::Result<Message<'x>> {
let mut mail_from = None;
let mut rcpt_to = std::collections::HashSet::new();

let find_address = |addr: &mail_parser::Addr| -> Option<String> {
addr.address
.as_ref()
.filter(|address| !address.trim().is_empty())
.map(|address| address.trim().to_string())
};

for header in self.headers() {
match &header.name {
HeaderName::From => match header.value() {
HeaderValue::Address(mail_parser::Address::List(addrs)) => {
if let Some(email) = addrs.iter().find_map(find_address) {
mail_from = email.to_string().into();
}
}
HeaderValue::Address(mail_parser::Address::Group(groups)) => {
if let Some(grps) = groups.first() {
if let Some(email) = grps.addresses.iter().find_map(find_address) {
mail_from = email.to_string().into();
}
}
}
_ => (),
},
HeaderName::To | HeaderName::Cc | HeaderName::Bcc => match header.value() {
HeaderValue::Address(mail_parser::Address::List(addrs)) => {
rcpt_to.extend(addrs.iter().filter_map(find_address));
}
HeaderValue::Address(mail_parser::Address::Group(grps)) => {
rcpt_to.extend(
grps.iter()
.flat_map(|grp| grp.addresses.iter())
.filter_map(find_address),
);
}
_ => (),
},
_ => (),
};
}

if rcpt_to.is_empty() {
return Err(crate::Error::MissingRcptTo);
}

Ok(Message {
mail_from: mail_from.ok_or(crate::Error::MissingMailFrom)?.into(),
rcpt_to: rcpt_to
.into_iter()
.map(|email| Address {
email: email.into(),
parameters: Parameters::default(),
})
.collect(),
body: self.raw_message,
})
}
}

0 comments on commit 43895ab

Please sign in to comment.