Merge pull request #116 from amousset/master

feat(email): Use Enveloppe directly
This commit is contained in:
Alexis Mousset
2017-02-18 17:54:30 +01:00
committed by GitHub
6 changed files with 53 additions and 40 deletions

View File

@@ -22,7 +22,7 @@ time = "^0.1"
uuid = { version = "^0.3", features = ["v4"] }
[dev-dependencies]
env_logger = "^0.3"
env_logger = "^0.4"
[features]
unstable = []

View File

@@ -270,9 +270,9 @@ pub struct EmailBuilder {
#[derive(PartialEq,Eq,Clone,Debug,Default)]
pub struct Envelope {
/// The envelope recipients' addresses
to: Vec<String>,
pub to: Vec<String>,
/// The envelope sender address
from: String,
pub from: String,
}
impl Envelope {
@@ -728,10 +728,8 @@ impl EmailBuilder {
/// Email sendable by an SMTP client
pub trait SendableEmail {
/// From address
fn from_address(&self) -> String;
/// To addresses
fn to_addresses(&self) -> Vec<String>;
/// Envelope
fn envelope(&self) -> &Envelope;
/// Message ID
fn message_id(&self) -> String;
/// Message content
@@ -741,35 +739,31 @@ pub trait SendableEmail {
/// Minimal email structure
#[derive(Debug)]
pub struct SimpleSendableEmail {
/// From address
from: String,
/// To addresses
to: Vec<String>,
/// Message
/// Message envelope
envelope: Envelope,
/// Message content
message: String,
}
impl SimpleSendableEmail {
/// Returns a new email
pub fn new(from_address: String,
to_address: Vec<String>,
to_addresses: Vec<String>,
message: String)
-> SimpleSendableEmail {
SimpleSendableEmail {
from: from_address,
to: to_address,
envelope: Envelope {
from: from_address,
to: to_addresses,
},
message: message,
}
}
}
impl SendableEmail for SimpleSendableEmail {
fn from_address(&self) -> String {
self.from.clone()
}
fn to_addresses(&self) -> Vec<String> {
self.to.clone()
fn envelope(&self) -> &Envelope {
&self.envelope
}
fn message_id(&self) -> String {
@@ -782,12 +776,8 @@ impl SendableEmail for SimpleSendableEmail {
}
impl SendableEmail for Email {
fn to_addresses(&self) -> Vec<String> {
self.envelope.to.clone()
}
fn from_address(&self) -> String {
self.envelope.from.clone()
fn envelope(&self) -> &Envelope {
&self.envelope
}
fn message_id(&self) -> String {
@@ -799,6 +789,31 @@ impl SendableEmail for Email {
}
}
/// Email sendable by any type of client, giving access to all fields
pub trait ExtractableEmail {
/// From address
fn from_address(&self) -> Option<String>;
/// To addresses
fn to_addresses(&self) -> Vec<String>;
/// Cc addresses
fn cc_addresses(&self) -> Vec<String>;
/// Bcc addresses
fn bcc_addresses(&self) -> Vec<String>;
/// Replay-To addresses
fn reply_to_address(&self) -> String;
/// Subject
fn subject(&self) -> String;
/// Message ID
fn message_id(&self) -> String;
/// Other Headers
fn headers(&self) -> Vec<String>;
/// html content
fn html(self) -> String;
/// text content
fn text(self) -> String;
}
#[cfg(test)]
mod test {
use email_format::{Header, MimeMessage};
@@ -931,8 +946,8 @@ mod test {
.build()
.unwrap();
assert_eq!(email.from_address(), "sender@localhost".to_string());
assert_eq!(email.to_addresses(),
assert_eq!(email.envelope().from, "sender@localhost".to_string());
assert_eq!(email.envelope().to,
vec!["user@localhost".to_string(),
"cc@localhost".to_string(),
"bcc@localhost".to_string()]);

View File

@@ -34,8 +34,8 @@ impl EmailTransport<FileResult> for FileEmailTransport {
let log_line = format!("{}: from=<{}> to=<{}>\n",
email.message_id(),
email.from_address(),
email.to_addresses().join("> to=<"));
email.envelope().from,
email.envelope().to.join("> to=<"));
try!(f.write_all(log_line.as_bytes()));
try!(f.write_all(email.message().as_bytes()));

View File

@@ -31,7 +31,7 @@ impl EmailTransport<SendmailResult> for SendmailTransport {
fn send<T: SendableEmail>(&mut self, email: T) -> SendmailResult {
// Spawn the sendmail command
let mut process = try!(Command::new(&self.command)
.args(&["-i", "-f", &email.from_address(), &email.to_addresses().join(" ")])
.args(&["-i", "-f", &email.envelope().from, &email.envelope().to.join(" ")])
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn());

View File

@@ -290,9 +290,6 @@ impl EmailTransport<SmtpResult> for SmtpTransport {
// Extract email information
let message_id = email.message_id();
let from_address = email.from_address();
let to_addresses = email.to_addresses();
let message = email.message();
// Check if the connection is still available
if (self.state.connection_reuse_count > 0) && (!self.client.is_connected()) {
@@ -383,13 +380,13 @@ impl EmailTransport<SmtpResult> for SmtpTransport {
(false, _) => None,
};
try_smtp!(self.client.mail(&from_address, mail_options), self);
try_smtp!(self.client.mail(&email.envelope().from, mail_options), self);
// Log the mail command
info!("{}: from=<{}>", message_id, from_address);
info!("{}: from=<{}>", message_id, email.envelope().from);
// Recipient
for to_address in &to_addresses {
for to_address in &email.envelope().to {
try_smtp!(self.client.rcpt(&to_address), self);
// Log the rcpt command
info!("{}: to=<{}>", message_id, to_address);
@@ -399,6 +396,7 @@ impl EmailTransport<SmtpResult> for SmtpTransport {
try_smtp!(self.client.data(), self);
// Message content
let message = email.message();
let result = self.client.message(&message);
if result.is_ok() {

View File

@@ -18,8 +18,8 @@ impl EmailTransport<StubResult> for StubEmailTransport {
info!("{}: from=<{}> to=<{:?}>",
email.message_id(),
email.from_address(),
email.to_addresses());
email.envelope().from,
email.envelope().to);
Ok(())
}