feat(all): Merge Email and SendableEmail into lettre::Email

This commit is contained in:
Alexis Mousset
2019-12-18 16:51:04 +01:00
parent 5e521b0c82
commit ce37464050
22 changed files with 70 additions and 92 deletions

View File

@@ -1,7 +1,7 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use lettre::{
smtp::ConnectionReuseParameters, ClientSecurity, EmailAddress, Envelope, SendableEmail,
SmtpClient, Transport,
smtp::ConnectionReuseParameters, ClientSecurity, Email, EmailAddress, Envelope, SmtpClient,
Transport,
};
fn bench_simple_send(c: &mut Criterion) {
@@ -11,7 +11,7 @@ fn bench_simple_send(c: &mut Criterion) {
c.bench_function("send email", move |b| {
b.iter(|| {
let email = SendableEmail::new(
let email = Email::new(
Envelope::new(
Some(EmailAddress::new("user@localhost".to_string()).unwrap()),
vec![EmailAddress::new("root@localhost".to_string()).unwrap()],
@@ -33,7 +33,7 @@ fn bench_reuse_send(c: &mut Criterion) {
.transport();
c.bench_function("send email with connection reuse", move |b| {
b.iter(|| {
let email = SendableEmail::new(
let email = Email::new(
Envelope::new(
Some(EmailAddress::new("user@localhost".to_string()).unwrap()),
vec![EmailAddress::new("root@localhost".to_string()).unwrap()],

View File

@@ -1,4 +1,4 @@
use lettre::builder::Email;
use lettre::Email;
use lettre::{SmtpClient, Transport};
use std::path::Path;

View File

@@ -1,12 +1,12 @@
extern crate env_logger;
extern crate lettre;
use lettre::{EmailAddress, Envelope, SendableEmail, SmtpClient, Transport};
use lettre::{Email, EmailAddress, Envelope, SmtpClient, Transport};
fn main() {
env_logger::init();
let email = SendableEmail::new(
let email = Email::new(
Envelope::new(
Some(EmailAddress::new("user@localhost".to_string()).unwrap()),
vec![EmailAddress::new("root@localhost".to_string()).unwrap()],

View File

@@ -1,10 +1,10 @@
extern crate lettre;
use lettre::smtp::authentication::Credentials;
use lettre::{EmailAddress, Envelope, SendableEmail, SmtpClient, Transport};
use lettre::{Email, EmailAddress, Envelope, SmtpClient, Transport};
fn main() {
let email = SendableEmail::new(
let email = Email::new(
Envelope::new(
Some(EmailAddress::new("from@gmail.com".to_string()).unwrap()),
vec![EmailAddress::new("to@example.com".to_string()).unwrap()],

View File

@@ -1,4 +1,4 @@
use crate::{error::Error as LettreError, EmailAddress, Envelope, SendableEmail};
use crate::{error::Error as LettreError, Email, EmailAddress, Envelope};
pub use email::{Address, Header, Mailbox, MimeMessage, MimeMultipartType};
use error::Error;
pub use mime;
@@ -63,34 +63,6 @@ pub struct EmailBuilder {
message_id: Option<String>,
}
/// Simple email representation
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Email {
/// Message
message: Vec<u8>,
/// Envelope
envelope: Envelope,
/// Message-ID
message_id: String,
}
impl Into<SendableEmail> for Email {
fn into(self) -> SendableEmail {
SendableEmail::new(
self.envelope.clone(),
self.message_id.to_string(),
self.message,
)
}
}
impl Email {
/// Creates a new email builder
pub fn builder() -> EmailBuilder {
EmailBuilder::new()
}
}
impl PartBuilder {
/// Creates a new empty part
pub fn new() -> PartBuilder {
@@ -471,17 +443,17 @@ impl EmailBuilder {
}
};
Ok(Email {
message: self.message.build().as_string().into_bytes(),
Ok(Email::new(
envelope,
message_id,
})
self.message.build().as_string().into_bytes(),
))
}
}
#[cfg(test)]
mod test {
use super::{EmailBuilder, SendableEmail};
use super::{Email, EmailBuilder};
use crate::EmailAddress;
use time::now;
@@ -489,7 +461,7 @@ mod test {
fn test_multiple_from() {
let email_builder = EmailBuilder::new();
let date_now = now();
let email: SendableEmail = email_builder
let email: Email = email_builder
.to("anna@example.com")
.from("dieter@example.com")
.from("joachim@example.com")
@@ -518,7 +490,7 @@ mod test {
let email_builder = EmailBuilder::new();
let date_now = now();
let email: SendableEmail = email_builder
let email: Email = email_builder
.to("user@localhost")
.from("user@localhost")
.cc(("cc@localhost", "Alias"))
@@ -554,7 +526,7 @@ mod test {
let email_builder = EmailBuilder::new();
let date_now = now();
let email: SendableEmail = email_builder
let email: Email = email_builder
.to("user@localhost")
.from("user@localhost")
.cc(("cc@localhost", "Alias"))
@@ -605,7 +577,7 @@ mod test {
let email_builder = EmailBuilder::new();
let date_now = now();
let email: SendableEmail = email_builder
let email: Email = email_builder
.to("user@localhost")
.from("user@localhost")
.cc(("cc@localhost", "Alias"))

View File

@@ -4,8 +4,8 @@
//!
use crate::file::error::FileResult;
use crate::Email;
use crate::Envelope;
use crate::SendableEmail;
use crate::Transport;
use serde_json;
use std::fs::File;
@@ -41,7 +41,7 @@ struct SerializableEmail {
impl<'a> Transport<'a> for FileTransport {
type Result = FileResult;
fn send<E: Into<SendableEmail>>(&mut self, email: E) -> FileResult {
fn send<E: Into<Email>>(&mut self, email: E) -> FileResult {
let email = email.into();
let message_id = email.message_id().to_string();

View File

@@ -25,7 +25,7 @@ pub mod smtp;
pub mod stub;
#[cfg(feature = "builder")]
pub use crate::builder::Email;
use crate::builder::EmailBuilder;
use crate::error::EmailResult;
use crate::error::Error;
#[cfg(feature = "file-transport")]
@@ -146,15 +146,21 @@ impl Read for Message {
}
/// Sendable email structure
pub struct SendableEmail {
pub struct Email {
envelope: Envelope,
message_id: String,
message: Message,
}
impl SendableEmail {
pub fn new(envelope: Envelope, message_id: String, message: Vec<u8>) -> SendableEmail {
SendableEmail {
impl Email {
/// Creates a new email builder
#[cfg(feature = "builder")]
pub fn builder() -> EmailBuilder {
EmailBuilder::new()
}
pub fn new(envelope: Envelope, message_id: String, message: Vec<u8>) -> Email {
Email {
envelope,
message_id,
message: Message::Bytes(Cursor::new(message)),
@@ -165,8 +171,8 @@ impl SendableEmail {
envelope: Envelope,
message_id: String,
message: Box<dyn Read + Send>,
) -> SendableEmail {
SendableEmail {
) -> Email {
Email {
envelope,
message_id,
message: Message::Reader(message),
@@ -198,5 +204,5 @@ pub trait Transport<'a> {
type Result;
/// Sends the email
fn send<E: Into<SendableEmail>>(&mut self, email: E) -> Self::Result;
fn send<E: Into<Email>>(&mut self, email: E) -> Self::Result;
}

View File

@@ -2,7 +2,7 @@
//!
use crate::sendmail::error::SendmailResult;
use crate::SendableEmail;
use crate::Email;
use crate::Transport;
use log::info;
use std::convert::AsRef;
@@ -38,7 +38,7 @@ impl SendmailTransport {
impl<'a> Transport<'a> for SendmailTransport {
type Result = SendmailResult;
fn send<E: Into<SendableEmail>>(&mut self, email: E) -> SendmailResult {
fn send<E: Into<Email>>(&mut self, email: E) -> SendmailResult {
let email = email.into();
let message_id = email.message_id().to_string();

View File

@@ -21,7 +21,7 @@ use crate::smtp::client::InnerClient;
use crate::smtp::commands::*;
use crate::smtp::error::{Error, SmtpResult};
use crate::smtp::extension::{ClientId, Extension, MailBodyParameter, MailParameter, ServerInfo};
use crate::{SendableEmail, Transport};
use crate::{Email, Transport};
use log::{debug, info};
#[cfg(feature = "native-tls")]
use native_tls::{Protocol, TlsConnector};
@@ -428,7 +428,7 @@ impl<'a> Transport<'a> for SmtpTransport {
feature = "cargo-clippy",
allow(clippy::match_same_arms, clippy::cyclomatic_complexity)
)]
fn send<E: Into<SendableEmail>>(&mut self, email: E) -> SmtpResult {
fn send<E: Into<Email>>(&mut self, email: E) -> SmtpResult {
let email = email.into();
let message_id = email.message_id().to_string();

View File

@@ -2,7 +2,7 @@
//! testing purposes.
//!
use crate::SendableEmail;
use crate::Email;
use crate::Transport;
use log::info;
@@ -30,7 +30,7 @@ pub type StubResult = Result<(), ()>;
impl<'a> Transport<'a> for StubTransport {
type Result = StubResult;
fn send<E: Into<SendableEmail>>(&mut self, email: E) -> StubResult {
fn send<E: Into<Email>>(&mut self, email: E) -> StubResult {
let email = email.into();
info!(

View File

@@ -23,10 +23,10 @@ fn build_with_envelope_without_from_test() {
vec![EmailAddress::new("to@example.org".to_string()).unwrap()],
)
.unwrap();
let _email = EmailBuilder::new()
assert!(EmailBuilder::new()
.envelope(e)
.subject("subject")
.text("message")
.build()
.unwrap_err();
.is_err());
}

View File

@@ -1,13 +1,13 @@
#[cfg(all(test, feature = "smtp-transport", feature = "connection-pool"))]
mod test {
use lettre::{ClientSecurity, EmailAddress, Envelope, SendableEmail, SmtpClient};
use lettre::{ClientSecurity, Email, EmailAddress, Envelope, SmtpClient};
use lettre::{SmtpConnectionManager, Transport};
use r2d2::Pool;
use std::sync::mpsc;
use std::thread;
fn email(message: &str) -> SendableEmail {
SendableEmail::new(
fn email(message: &str) -> Email {
Email::new(
Envelope::new(
Some(EmailAddress::new("user@localhost".to_string()).unwrap()),
vec![EmailAddress::new("root@localhost".to_string()).unwrap()],

View File

@@ -2,7 +2,7 @@
#[cfg(feature = "file-transport")]
mod test {
use lettre::file::FileTransport;
use lettre::{EmailAddress, Envelope, SendableEmail, Transport};
use lettre::{Email, EmailAddress, Envelope, Transport};
use std::env::temp_dir;
use std::fs::remove_file;
use std::fs::File;
@@ -11,7 +11,7 @@ mod test {
#[test]
fn file_transport() {
let mut sender = FileTransport::new(temp_dir());
let email = SendableEmail::new(
let email = Email::new(
Envelope::new(
Some(EmailAddress::new("user@localhost".to_string()).unwrap()),
vec![EmailAddress::new("root@localhost".to_string()).unwrap()],

View File

@@ -2,12 +2,12 @@
#[cfg(feature = "sendmail-transport")]
mod test {
use lettre::sendmail::SendmailTransport;
use lettre::{EmailAddress, Envelope, SendableEmail, Transport};
use lettre::{Email, EmailAddress, Envelope, Transport};
#[test]
fn sendmail_transport_simple() {
let mut sender = SendmailTransport::new();
let email = SendableEmail::new(
let email = Email::new(
Envelope::new(
Some(EmailAddress::new("user@localhost".to_string()).unwrap()),
vec![EmailAddress::new("root@localhost".to_string()).unwrap()],

View File

@@ -1,11 +1,11 @@
#[cfg(test)]
#[cfg(feature = "smtp-transport")]
mod test {
use lettre::{ClientSecurity, EmailAddress, Envelope, SendableEmail, SmtpClient, Transport};
use lettre::{ClientSecurity, Email, EmailAddress, Envelope, SmtpClient, Transport};
#[test]
fn smtp_transport_simple() {
let email = SendableEmail::new(
let email = Email::new(
Envelope::new(
Some(EmailAddress::new("user@localhost".to_string()).unwrap()),
vec![EmailAddress::new("root@localhost".to_string()).unwrap()],

View File

@@ -1,11 +1,11 @@
use lettre::stub::StubTransport;
use lettre::{EmailAddress, Envelope, SendableEmail, Transport};
use lettre::{Email, EmailAddress, Envelope, Transport};
#[test]
fn stub_transport() {
let mut sender_ok = StubTransport::new_positive();
let mut sender_ko = StubTransport::new(Err(()));
let email_ok = SendableEmail::new(
let email_ok = Email::new(
Envelope::new(
Some(EmailAddress::new("user@localhost".to_string()).unwrap()),
vec![EmailAddress::new("root@localhost".to_string()).unwrap()],
@@ -14,7 +14,7 @@ fn stub_transport() {
"id".to_string(),
"Hello ß☺ example".to_string().into_bytes(),
);
let email_ko = SendableEmail::new(
let email_ko = Email::new(
Envelope::new(
Some(EmailAddress::new("user@localhost".to_string()).unwrap()),
vec![EmailAddress::new("root@localhost".to_string()).unwrap()],

View File

@@ -5,7 +5,7 @@ This section explains how to create emails.
#### Simple example
The `email` part builds email messages. For now, it does not support attachments.
An email is built using an `EmailBuilder`. The simplest email could be:
An email is built using an `Email` builder. The simplest email could be:
```rust
# #[cfg(feature = "builder")]
@@ -30,7 +30,7 @@ fn main() {
# }
```
When the `build` method is called, the `EmailBuilder` will add the missing headers (like
When the `build` method is called, the builder will add the missing headers (like
`Message-ID` or `Date`) and check for missing necessary ones (like `From` or `To`). It will
then generate an `Email` that can be sent.

View File

@@ -3,7 +3,7 @@
This section explains how to manipulate emails you have created.
This mailer contains several different transports for your emails. To be sendable, the
emails have to implement `SendableEmail`, which is the case for emails created with `lettre::builder`.
emails have to implement `Email`, which is the case for emails created with `lettre::builder`.
The following transports are available:

View File

@@ -12,12 +12,12 @@ extern crate lettre;
use std::env::temp_dir;
use lettre::file::FileTransport;
use lettre::{Transport, Envelope, EmailAddress, SendableEmail};
use lettre::{Transport, Envelope, EmailAddress, Email};
fn main() {
// Write to the local temp directory
let mut sender = FileTransport::new(temp_dir());
let email = SendableEmail::new(
let email = Email::new(
Envelope::new(
Some(EmailAddress::new("user@localhost".to_string()).unwrap()),
vec![EmailAddress::new("root@localhost".to_string()).unwrap()],

View File

@@ -8,10 +8,10 @@ The sendmail transport sends the email using the local sendmail command.
extern crate lettre;
use lettre::sendmail::SendmailTransport;
use lettre::{SendableEmail, Envelope, EmailAddress, Transport};
use lettre::{Email, Envelope, EmailAddress, Transport};
fn main() {
let email = SendableEmail::new(
let email = Email::new(
Envelope::new(
Some(EmailAddress::new("user@localhost".to_string()).unwrap()),
vec![EmailAddress::new("root@localhost".to_string()).unwrap()],

View File

@@ -22,10 +22,10 @@ This is the most basic example of usage:
# {
extern crate lettre;
use lettre::{SendableEmail, EmailAddress, Transport, Envelope, SmtpClient};
use lettre::{Email, EmailAddress, Transport, Envelope, SmtpClient};
fn main() {
let email = SendableEmail::new(
let email = Email::new(
Envelope::new(
Some(EmailAddress::new("user@localhost".to_string()).unwrap()),
vec![EmailAddress::new("root@localhost".to_string()).unwrap()],
@@ -53,12 +53,12 @@ fn main() {
extern crate lettre;
use lettre::smtp::authentication::{Credentials, Mechanism};
use lettre::{SendableEmail, Envelope, EmailAddress, Transport, SmtpClient};
use lettre::{Email, Envelope, EmailAddress, Transport, SmtpClient};
use lettre::smtp::extension::ClientId;
use lettre::smtp::ConnectionReuseParameters;
fn main() {
let email_1 = SendableEmail::new(
let email_1 = Email::new(
Envelope::new(
Some(EmailAddress::new("user@localhost".to_string()).unwrap()),
vec![EmailAddress::new("root@localhost".to_string()).unwrap()],
@@ -67,7 +67,7 @@ fn main() {
"Hello world".to_string().into_bytes(),
);
let email_2 = SendableEmail::new(
let email_2 = Email::new(
Envelope::new(
Some(EmailAddress::new("user@localhost".to_string()).unwrap()),
vec![EmailAddress::new("root@localhost".to_string()).unwrap()],
@@ -112,14 +112,14 @@ extern crate lettre;
use lettre::{
ClientSecurity, ClientTlsParameters, EmailAddress, Envelope,
SendableEmail, SmtpClient, Transport,
Email, SmtpClient, Transport,
};
use lettre::smtp::authentication::{Credentials, Mechanism};
use lettre::smtp::ConnectionReuseParameters;
use native_tls::{Protocol, TlsConnector};
fn main() {
let email = SendableEmail::new(
let email = Email::new(
Envelope::new(
Some(EmailAddress::new("user@localhost".to_string()).unwrap()),
vec![EmailAddress::new("root@localhost".to_string()).unwrap()],

View File

@@ -7,10 +7,10 @@ testing purposes.
extern crate lettre;
use lettre::stub::StubTransport;
use lettre::{SendableEmail, Envelope, EmailAddress, Transport};
use lettre::{Email, Envelope, EmailAddress, Transport};
fn main() {
let email = SendableEmail::new(
let email = Email::new(
Envelope::new(
Some(EmailAddress::new("user@localhost".to_string()).unwrap()),
vec![EmailAddress::new("root@localhost".to_string()).unwrap()],