feat(transport): Use command types for mail and rcpt
This commit is contained in:
@@ -24,7 +24,6 @@ rust-crypto = "^0.2"
|
||||
serde = "^1.0"
|
||||
serde_json = "^1.0"
|
||||
serde_derive = "^1.0"
|
||||
emailaddress = "^0.4"
|
||||
|
||||
[dev-dependencies]
|
||||
env_logger = "^0.4"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
extern crate lettre;
|
||||
|
||||
use lettre::{EmailTransport, SimpleSendableEmail};
|
||||
use lettre::{EmailAddress, EmailTransport, SimpleSendableEmail};
|
||||
use lettre::smtp::{SecurityLevel, SmtpTransportBuilder};
|
||||
|
||||
fn main() {
|
||||
let email = SimpleSendableEmail::new(
|
||||
"user@localhost",
|
||||
vec!["root@localhost"],
|
||||
"file_id",
|
||||
"Hello ß☺ example",
|
||||
EmailAddress::new("user@localhost".to_string()),
|
||||
vec![EmailAddress::new("root@localhost".to_string())],
|
||||
"file_id".to_string(),
|
||||
"Hello ß☺ example".to_string(),
|
||||
);
|
||||
|
||||
// Open a local connection on port 25
|
||||
|
||||
@@ -6,15 +6,15 @@
|
||||
//! use std::env::temp_dir;
|
||||
//!
|
||||
//! use lettre::file::FileEmailTransport;
|
||||
//! use lettre::{SimpleSendableEmail, EmailTransport};
|
||||
//! use lettre::{SimpleSendableEmail, EmailTransport, EmailAddress};
|
||||
//!
|
||||
//! // Write to the local temp directory
|
||||
//! let mut sender = FileEmailTransport::new(temp_dir());
|
||||
//! let email = SimpleSendableEmail::new(
|
||||
//! "user@localhost",
|
||||
//! vec!["root@localhost"],
|
||||
//! "message_id",
|
||||
//! "Hello world"
|
||||
//! EmailAddress::new("user@localhost".to_string()),
|
||||
//! vec![EmailAddress::new("root@localhost".to_string())],
|
||||
//! "message_id".to_string(),
|
||||
//! "Hello world".to_string(),
|
||||
//! );
|
||||
//!
|
||||
//! let result = sender.send(email);
|
||||
@@ -68,10 +68,10 @@ impl EmailTransport<FileResult> for FileEmailTransport {
|
||||
let mut f = try!(File::create(file.as_path()));
|
||||
|
||||
let simple_email = SimpleSendableEmail::new(
|
||||
&email.from(),
|
||||
email.to().iter().map(String::as_str).collect(),
|
||||
&email.message_id(),
|
||||
&email.message(),
|
||||
email.from().clone(),
|
||||
email.to().clone(),
|
||||
email.message_id().clone(),
|
||||
email.message(),
|
||||
);
|
||||
|
||||
try!(f.write_all(
|
||||
|
||||
@@ -13,7 +13,6 @@ extern crate hex;
|
||||
extern crate crypto;
|
||||
extern crate bufstream;
|
||||
extern crate native_tls;
|
||||
extern crate emailaddress;
|
||||
extern crate serde_json;
|
||||
extern crate serde;
|
||||
#[macro_use]
|
||||
@@ -23,13 +22,32 @@ pub mod smtp;
|
||||
pub mod sendmail;
|
||||
pub mod stub;
|
||||
pub mod file;
|
||||
use std::fmt;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
/// Email address
|
||||
#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct EmailAddress(pub String);
|
||||
|
||||
impl Display for EmailAddress {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
f.write_str(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl EmailAddress {
|
||||
/// Creates a new email address
|
||||
pub fn new(address: String) -> EmailAddress {
|
||||
EmailAddress(address)
|
||||
}
|
||||
}
|
||||
|
||||
/// Email sendable by an SMTP client
|
||||
pub trait SendableEmail {
|
||||
/// To
|
||||
fn to(&self) -> Vec<String>;
|
||||
fn to(&self) -> Vec<EmailAddress>;
|
||||
/// From
|
||||
fn from(&self) -> String;
|
||||
fn from(&self) -> EmailAddress;
|
||||
/// Message ID, used for logging
|
||||
fn message_id(&self) -> String;
|
||||
/// Message content
|
||||
@@ -48,9 +66,9 @@ pub trait EmailTransport<U> {
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct SimpleSendableEmail {
|
||||
/// To
|
||||
to: Vec<String>,
|
||||
to: Vec<EmailAddress>,
|
||||
/// From
|
||||
from: String,
|
||||
from: EmailAddress,
|
||||
/// Message ID
|
||||
message_id: String,
|
||||
/// Message content
|
||||
@@ -60,26 +78,26 @@ pub struct SimpleSendableEmail {
|
||||
impl SimpleSendableEmail {
|
||||
/// Returns a new email
|
||||
pub fn new(
|
||||
from_address: &str,
|
||||
to_addresses: Vec<&str>,
|
||||
message_id: &str,
|
||||
message: &str,
|
||||
from_address: EmailAddress,
|
||||
to_addresses: Vec<EmailAddress>,
|
||||
message_id: String,
|
||||
message: String,
|
||||
) -> SimpleSendableEmail {
|
||||
SimpleSendableEmail {
|
||||
from: from_address.to_string(),
|
||||
to: to_addresses.iter().map(|s| s.to_string()).collect(),
|
||||
message_id: message_id.to_string(),
|
||||
message: message.to_string(),
|
||||
from: from_address,
|
||||
to: to_addresses,
|
||||
message_id: message_id,
|
||||
message: message,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SendableEmail for SimpleSendableEmail {
|
||||
fn to(&self) -> Vec<String> {
|
||||
fn to(&self) -> Vec<EmailAddress> {
|
||||
self.to.clone()
|
||||
}
|
||||
|
||||
fn from(&self) -> String {
|
||||
fn from(&self) -> EmailAddress {
|
||||
self.from.clone()
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
//!
|
||||
//! ```rust
|
||||
//! use lettre::sendmail::SendmailTransport;
|
||||
//! use lettre::{SimpleSendableEmail, EmailTransport};
|
||||
//! use lettre::{SimpleSendableEmail, EmailTransport, EmailAddress};
|
||||
//!
|
||||
//! let email = SimpleSendableEmail::new(
|
||||
//! "user@localhost",
|
||||
//! vec!["root@localhost"],
|
||||
//! "message_id",
|
||||
//! "Hello world"
|
||||
//! EmailAddress::new("user@localhost".to_string()),
|
||||
//! vec![EmailAddress::new("root@localhost".to_string())],
|
||||
//! "message_id".to_string(),
|
||||
//! "Hello world".to_string(),
|
||||
//! );
|
||||
//!
|
||||
//! let mut sender = SendmailTransport::new();
|
||||
@@ -45,9 +45,17 @@ impl SendmailTransport {
|
||||
impl EmailTransport<SendmailResult> for SendmailTransport {
|
||||
fn send<T: SendableEmail>(&mut self, email: T) -> SendmailResult {
|
||||
// Spawn the sendmail command
|
||||
let to_addresses: Vec<String> = email.to().iter().map(|x| x.to_string()).collect();
|
||||
let mut process = try!(
|
||||
Command::new(&self.command)
|
||||
.args(&["-i", "-f", &email.from(), &email.to().join(" ")])
|
||||
.args(
|
||||
&[
|
||||
"-i",
|
||||
"-f",
|
||||
&email.from().to_string(),
|
||||
&to_addresses.join(" "),
|
||||
],
|
||||
)
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
|
||||
@@ -151,19 +151,6 @@ impl<S: Connector + Write + Read + Timeout + Debug> Client<S> {
|
||||
self.send_server(&command.to_string(), "")
|
||||
}
|
||||
|
||||
/// Sends a MAIL command
|
||||
pub fn mail(&mut self, address: &str, options: Option<&str>) -> SmtpResult {
|
||||
match options {
|
||||
Some(options) => self.command(&format!("MAIL FROM:<{}> {}", address, options)),
|
||||
None => self.command(&format!("MAIL FROM:<{}>", address)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Sends a RCPT command
|
||||
pub fn rcpt(&mut self, address: &str) -> SmtpResult {
|
||||
self.command(&format!("RCPT TO:<{}>", address))
|
||||
}
|
||||
|
||||
/// Sends an AUTH command with the given mechanism, and handles challenge if needed
|
||||
pub fn auth(&mut self, mechanism: Mechanism, credentials: &Credentials) -> SmtpResult {
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! SMTP commands
|
||||
|
||||
use EmailAddress;
|
||||
use base64;
|
||||
use emailaddress::EmailAddress;
|
||||
use smtp::CRLF;
|
||||
use smtp::authentication::{Credentials, Mechanism};
|
||||
use smtp::error::Error;
|
||||
@@ -323,7 +323,7 @@ mod test {
|
||||
#[test]
|
||||
fn test_display() {
|
||||
let id = ClientId::Domain("localhost".to_string());
|
||||
let email = EmailAddress::new("test@example.com").unwrap();
|
||||
let email = EmailAddress::new("test@example.com".to_string());
|
||||
let mail_parameter = MailParameter::Other {
|
||||
keyword: "TEST".to_string(),
|
||||
value: Some("value".to_string()),
|
||||
|
||||
@@ -165,6 +165,8 @@ pub enum MailParameter {
|
||||
Body(MailBodyParameter),
|
||||
/// `SIZE` parameter
|
||||
Size(usize),
|
||||
/// `SMTPUTF8` parameter
|
||||
SmtpUtfEight,
|
||||
/// Custom parameter
|
||||
Other {
|
||||
/// Parameter keyword
|
||||
@@ -179,6 +181,7 @@ impl Display for MailParameter {
|
||||
match *self {
|
||||
MailParameter::Body(ref value) => write!(f, "BODY={}", value),
|
||||
MailParameter::Size(size) => write!(f, "SIZE={}", size),
|
||||
MailParameter::SmtpUtfEight => f.write_str("SMTPUTF8"),
|
||||
MailParameter::Other {
|
||||
ref keyword,
|
||||
value: Some(ref value),
|
||||
|
||||
@@ -18,15 +18,15 @@
|
||||
//! This is the most basic example of usage:
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! use lettre::{SimpleSendableEmail, EmailTransport};
|
||||
//! use lettre::{SimpleSendableEmail, EmailTransport, EmailAddress};
|
||||
//! use lettre::smtp::SmtpTransportBuilder;
|
||||
//! use lettre::smtp::SecurityLevel;
|
||||
//!
|
||||
//! let email = SimpleSendableEmail::new(
|
||||
//! "user@localhost",
|
||||
//! vec!["root@localhost"],
|
||||
//! "message_id",
|
||||
//! "Hello world"
|
||||
//! EmailAddress::new("user@localhost".to_string()),
|
||||
//! vec![EmailAddress::new("root@localhost".to_string())],
|
||||
//! "message_id".to_string(),
|
||||
//! "Hello world".to_string(),
|
||||
//! );
|
||||
//!
|
||||
//! // Open a local connection on port 25
|
||||
@@ -45,14 +45,14 @@
|
||||
//! SmtpTransportBuilder};
|
||||
//! use lettre::smtp::authentication::{Credentials, Mechanism};
|
||||
//! use lettre::smtp::SUBMISSION_PORT;
|
||||
//! use lettre::{SimpleSendableEmail, EmailTransport};
|
||||
//! use lettre::{SimpleSendableEmail, EmailTransport, EmailAddress};
|
||||
//! use lettre::smtp::extension::ClientId;
|
||||
//!
|
||||
//! let email = SimpleSendableEmail::new(
|
||||
//! "user@localhost",
|
||||
//! vec!["root@localhost"],
|
||||
//! "message_id",
|
||||
//! "Hello world"
|
||||
//! EmailAddress::new("user@localhost".to_string()),
|
||||
//! vec![EmailAddress::new("root@localhost".to_string())],
|
||||
//! "message_id".to_string(),
|
||||
//! "Hello world".to_string(),
|
||||
//! );
|
||||
//!
|
||||
//! // Connect to a remote server on a custom port
|
||||
@@ -89,6 +89,7 @@
|
||||
//! error handling:
|
||||
//!
|
||||
//! ```rust
|
||||
//! use lettre::EmailAddress;
|
||||
//! use lettre::smtp::SMTP_PORT;
|
||||
//! use lettre::smtp::client::Client;
|
||||
//! use lettre::smtp::client::net::NetworkStream;
|
||||
@@ -98,8 +99,8 @@
|
||||
//! let mut email_client: Client<NetworkStream> = Client::new();
|
||||
//! let _ = email_client.connect(&("localhost", SMTP_PORT), None);
|
||||
//! let _ = email_client.smtp_command(EhloCommand::new(ClientId::new("my_hostname".to_string())));
|
||||
//! let _ = email_client.mail("user@example.com", None);
|
||||
//! let _ = email_client.rcpt("user@example.org");
|
||||
//! let _ = email_client.smtp_command(MailCommand::new(Some(EmailAddress::new("user@example.com".to_string())), vec![]));
|
||||
//! let _ = email_client.smtp_command(RcptCommand::new(EmailAddress::new("user@example.org".to_string()), vec![]));
|
||||
//! let _ = email_client.smtp_command(DataCommand);
|
||||
//! let _ = email_client.message("Test email");
|
||||
//! let _ = email_client.smtp_command(QuitCommand);
|
||||
@@ -113,7 +114,7 @@ use smtp::authentication::{Credentials, Mechanism};
|
||||
use smtp::client::Client;
|
||||
use smtp::commands::*;
|
||||
use smtp::error::{Error, SmtpResult};
|
||||
use smtp::extension::{ClientId, Extension, ServerInfo};
|
||||
use smtp::extension::{ClientId, Extension, MailBodyParameter, MailParameter, ServerInfo};
|
||||
use std::net::{SocketAddr, ToSocketAddrs};
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -492,27 +493,41 @@ impl EmailTransport<SmtpResult> for SmtpTransport {
|
||||
}
|
||||
|
||||
// Mail
|
||||
let mail_options = match (
|
||||
self.server_info.as_ref().unwrap().supports_feature(
|
||||
Extension::EightBitMime,
|
||||
),
|
||||
self.server_info.as_ref().unwrap().supports_feature(
|
||||
Extension::SmtpUtfEight,
|
||||
),
|
||||
) {
|
||||
(true, true) => Some("BODY=8BITMIME SMTPUTF8"),
|
||||
(true, false) => Some("BODY=8BITMIME"),
|
||||
(false, _) => None,
|
||||
};
|
||||
let mut mail_options = vec![];
|
||||
|
||||
try_smtp!(self.client.mail(&email.from(), mail_options), self);
|
||||
if self.server_info.as_ref().unwrap().supports_feature(
|
||||
Extension::EightBitMime,
|
||||
)
|
||||
{
|
||||
mail_options.push(MailParameter::Body(MailBodyParameter::EightBitMime));
|
||||
}
|
||||
|
||||
if self.server_info.as_ref().unwrap().supports_feature(
|
||||
Extension::SmtpUtfEight,
|
||||
)
|
||||
{
|
||||
mail_options.push(MailParameter::SmtpUtfEight);
|
||||
}
|
||||
|
||||
try_smtp!(
|
||||
self.client.smtp_command(MailCommand::new(
|
||||
Some(email.from().clone()),
|
||||
mail_options,
|
||||
)),
|
||||
self
|
||||
);
|
||||
|
||||
// Log the mail command
|
||||
info!("{}: from=<{}>", message_id, email.from());
|
||||
|
||||
// Recipient
|
||||
for to_address in &email.to() {
|
||||
try_smtp!(self.client.rcpt(to_address), self);
|
||||
try_smtp!(
|
||||
self.client.smtp_command(
|
||||
RcptCommand::new(to_address.clone(), vec![]),
|
||||
),
|
||||
self
|
||||
);
|
||||
// Log the rcpt command
|
||||
info!("{}: to=<{}>", message_id, to_address);
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
//!
|
||||
//! ```rust
|
||||
//! use lettre::stub::StubEmailTransport;
|
||||
//! use lettre::{SimpleSendableEmail, EmailTransport};
|
||||
//! use lettre::{SimpleSendableEmail, EmailTransport, EmailAddress};
|
||||
//!
|
||||
//! let email = SimpleSendableEmail::new(
|
||||
//! "user@localhost",
|
||||
//! vec!["root@localhost"],
|
||||
//! "message_id",
|
||||
//! "Hello world"
|
||||
//! EmailAddress::new("user@localhost".to_string()),
|
||||
//! vec![EmailAddress::new("root@localhost".to_string())],
|
||||
//! "message_id".to_string(),
|
||||
//! "Hello world".to_string(),
|
||||
//! );
|
||||
//!
|
||||
//! let mut sender = StubEmailTransport::new_positive();
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
use EmailTransport;
|
||||
use SendableEmail;
|
||||
use smtp::response::{Code, Response};
|
||||
use smtp::error::{Error, SmtpResult};
|
||||
use smtp::response::{Code, Response};
|
||||
use std::str::FromStr;
|
||||
|
||||
/// This transport logs the message envelope and returns the given response
|
||||
@@ -38,15 +38,13 @@ pub struct StubEmailTransport {
|
||||
impl StubEmailTransport {
|
||||
/// Creates a new transport that always returns the given response
|
||||
pub fn new(response: Response) -> StubEmailTransport {
|
||||
StubEmailTransport {
|
||||
response: response,
|
||||
}
|
||||
StubEmailTransport { response: response }
|
||||
}
|
||||
|
||||
/// Creates a new transport that always returns a success response
|
||||
pub fn new_positive() -> StubEmailTransport {
|
||||
StubEmailTransport {
|
||||
response: Response::new(Code::from_str("200").unwrap(), vec!["ok".to_string()])
|
||||
response: Response::new(Code::from_str("200").unwrap(), vec!["ok".to_string()]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
extern crate lettre;
|
||||
|
||||
use lettre::{EmailTransport, SendableEmail, SimpleSendableEmail};
|
||||
use lettre::{EmailAddress, EmailTransport, SendableEmail, SimpleSendableEmail};
|
||||
|
||||
use lettre::file::FileEmailTransport;
|
||||
use std::env::temp_dir;
|
||||
@@ -12,10 +12,10 @@ use std::io::Read;
|
||||
fn file_transport() {
|
||||
let mut sender = FileEmailTransport::new(temp_dir());
|
||||
let email = SimpleSendableEmail::new(
|
||||
"user@localhost",
|
||||
vec!["root@localhost"],
|
||||
"file_id",
|
||||
"Hello file",
|
||||
EmailAddress::new("user@localhost".to_string()),
|
||||
vec![EmailAddress::new("root@localhost".to_string())],
|
||||
"file_id".to_string(),
|
||||
"Hello file".to_string(),
|
||||
);
|
||||
let result = sender.send(email.clone());
|
||||
assert!(result.is_ok());
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
extern crate lettre;
|
||||
|
||||
use lettre::{EmailTransport, SimpleSendableEmail};
|
||||
use lettre::{EmailAddress, EmailTransport, SimpleSendableEmail};
|
||||
use lettre::sendmail::SendmailTransport;
|
||||
|
||||
#[test]
|
||||
fn sendmail_transport_simple() {
|
||||
let mut sender = SendmailTransport::new();
|
||||
let email = SimpleSendableEmail::new(
|
||||
"user@localhost",
|
||||
vec!["root@localhost"],
|
||||
"sendmail_id",
|
||||
"Hello sendmail",
|
||||
EmailAddress::new("user@localhost".to_string()),
|
||||
vec![EmailAddress::new("root@localhost".to_string())],
|
||||
"sendmail_id".to_string(),
|
||||
"Hello sendmail".to_string(),
|
||||
);
|
||||
|
||||
let result = sender.send(email);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
extern crate lettre;
|
||||
|
||||
use lettre::{EmailTransport, SimpleSendableEmail};
|
||||
use lettre::{EmailAddress, EmailTransport, SimpleSendableEmail};
|
||||
use lettre::smtp::SecurityLevel;
|
||||
use lettre::smtp::SmtpTransportBuilder;
|
||||
|
||||
@@ -11,10 +11,10 @@ fn smtp_transport_simple() {
|
||||
.security_level(SecurityLevel::Opportunistic)
|
||||
.build();
|
||||
let email = SimpleSendableEmail::new(
|
||||
"user@localhost",
|
||||
vec!["root@localhost"],
|
||||
"smtp_id",
|
||||
"Hello smtp",
|
||||
EmailAddress::new("user@localhost".to_string()),
|
||||
vec![EmailAddress::new("root@localhost".to_string())],
|
||||
"smtp_id".to_string(),
|
||||
"Hello smtp".to_string(),
|
||||
);
|
||||
|
||||
let result = sender.send(email);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
extern crate lettre;
|
||||
|
||||
use lettre::{EmailTransport, SimpleSendableEmail};
|
||||
use lettre::stub::StubEmailTransport;
|
||||
use lettre::{EmailAddress, EmailTransport, SimpleSendableEmail};
|
||||
use lettre::smtp::response::{Code, Response};
|
||||
use lettre::stub::StubEmailTransport;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[test]
|
||||
@@ -13,10 +13,10 @@ fn stub_transport() {
|
||||
let mut sender_ko = StubEmailTransport::new(response_ko);
|
||||
|
||||
let email = SimpleSendableEmail::new(
|
||||
"user@localhost",
|
||||
vec!["root@localhost"],
|
||||
"stub_id",
|
||||
"Hello stub",
|
||||
EmailAddress::new("user@localhost".to_string()),
|
||||
vec![EmailAddress::new("root@localhost".to_string())],
|
||||
"stub_id".to_string(),
|
||||
"Hello stub".to_string(),
|
||||
);
|
||||
|
||||
let result_ok = sender_ok.send(email.clone()).unwrap();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use email_format::{Address, Header, Mailbox, MimeMessage, MimeMultipartType};
|
||||
use error::Error;
|
||||
use lettre::SendableEmail;
|
||||
use lettre::{EmailAddress, SendableEmail};
|
||||
use mime;
|
||||
use mime::Mime;
|
||||
use std::fmt;
|
||||
@@ -765,12 +765,12 @@ impl EmailBuilder {
|
||||
}
|
||||
|
||||
impl SendableEmail for Email {
|
||||
fn to(&self) -> Vec<String> {
|
||||
self.envelope.to.clone()
|
||||
fn to(&self) -> Vec<EmailAddress> {
|
||||
self.envelope.to.iter().map(|x| EmailAddress::new(x.clone())).collect()
|
||||
}
|
||||
|
||||
fn from(&self) -> String {
|
||||
self.envelope.from.clone()
|
||||
fn from(&self) -> EmailAddress {
|
||||
EmailAddress::new(self.envelope.from.clone())
|
||||
}
|
||||
|
||||
fn message_id(&self) -> String {
|
||||
@@ -812,7 +812,7 @@ mod test {
|
||||
|
||||
use super::{Email, EmailBuilder, Envelope, IntoEmail, SimpleEmail};
|
||||
use email_format::{Header, MimeMessage};
|
||||
use lettre::SendableEmail;
|
||||
use lettre::{EmailAddress, SendableEmail};
|
||||
use time::now;
|
||||
|
||||
use uuid::Uuid;
|
||||
@@ -962,13 +962,13 @@ mod test {
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(email.from(), "sender@localhost".to_string());
|
||||
assert_eq!(email.from().to_string(), "sender@localhost".to_string());
|
||||
assert_eq!(
|
||||
email.to(),
|
||||
vec![
|
||||
"user@localhost".to_string(),
|
||||
"cc@localhost".to_string(),
|
||||
"bcc@localhost".to_string(),
|
||||
EmailAddress::new("user@localhost".to_string()),
|
||||
EmailAddress::new("cc@localhost".to_string()),
|
||||
EmailAddress::new("bcc@localhost".to_string()),
|
||||
]
|
||||
);
|
||||
let content = format!("{}", email);
|
||||
|
||||
Reference in New Issue
Block a user