feat(all): Rust 2018

This commit is contained in:
Alexis Mousset
2019-03-23 13:25:01 +01:00
parent d5e9ebc0db
commit 9db66ce8e8
23 changed files with 171 additions and 101 deletions

View File

@@ -3,7 +3,7 @@ rust:
- stable
- beta
- nightly
- 1.26.0
- 1.31.0
matrix:
allow_failures:
- rust: nightly

View File

@@ -34,7 +34,7 @@ Lettre provides the following features:
## Example
This library requires Rust 1.26 or newer.
This library requires Rust 1.31 or newer.
To use this library, add the following to your `Cargo.toml`:
```toml

View File

@@ -10,6 +10,7 @@ license = "MIT"
authors = ["Alexis Mousset <contact@amousset.me>"]
categories = ["email"]
keywords = ["email", "smtp", "mailer"]
edition = "2018"
[badges]
travis-ci = { repository = "lettre/lettre" }

View File

@@ -1,8 +1,8 @@
use self::Error::*;
use std::{
error::Error as StdError,
fmt::{self, Display, Formatter},
};
use self::Error::*;
/// Error type for email content
#[derive(Debug, Clone, Copy)]

View File

@@ -1,12 +1,12 @@
//! Error and result type for file transport
use self::Error::*;
use serde_json;
use std::io;
use std::{
error::Error as StdError,
fmt::{self, Display, Formatter},
};
use serde_json;
use std::io;
use self::Error::*;
/// An enum of all error kinds.
#[derive(Debug)]

View File

@@ -4,19 +4,22 @@
//!
use crate::file::error::FileResult;
use crate::Envelope;
use crate::SendableEmail;
use crate::Transport;
use serde_json;
use std::fs::File;
use std::io::prelude::*;
use std::path::{Path, PathBuf};
use crate::Envelope;
use crate::SendableEmail;
use crate::Transport;
pub mod error;
/// Writes the content and the envelope information to a file
#[derive(Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct FileTransport {
path: PathBuf,
}
@@ -31,7 +34,10 @@ impl FileTransport {
}
#[derive(PartialEq, Eq, Clone, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
struct SerializableEmail {
envelope: Envelope,
message_id: String,

View File

@@ -12,29 +12,6 @@
unstable_features,
unused_import_braces
)]
#[cfg(feature = "smtp-transport")]
extern crate base64;
#[cfg(feature = "smtp-transport")]
extern crate bufstream;
#[cfg(feature = "smtp-transport")]
extern crate hostname;
#[macro_use]
extern crate log;
#[cfg(feature = "smtp-transport")]
extern crate native_tls;
#[cfg(feature = "smtp-transport")]
#[macro_use]
extern crate nom;
#[cfg(feature = "serde-impls")]
extern crate serde;
#[cfg(feature = "serde-impls")]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "file-transport")]
extern crate serde_json;
extern crate fast_chemail;
#[cfg(feature = "connection-pool")]
extern crate r2d2;
pub mod error;
#[cfg(feature = "file-transport")]
@@ -47,17 +24,17 @@ pub mod stub;
use crate::error::EmailResult;
use crate::error::Error;
use fast_chemail::is_valid_email;
#[cfg(feature = "file-transport")]
pub use crate::file::FileTransport;
#[cfg(feature = "sendmail-transport")]
pub use crate::sendmail::SendmailTransport;
#[cfg(feature = "smtp-transport")]
pub use crate::smtp::client::net::ClientTlsParameters;
#[cfg(all(feature = "smtp-transport", feature = "connection-pool"))]
pub use smtp::r2d2::SmtpConnectionManager;
#[cfg(feature = "smtp-transport")]
pub use crate::smtp::{ClientSecurity, SmtpClient, SmtpTransport};
use fast_chemail::is_valid_email;
#[cfg(all(feature = "smtp-transport", feature = "connection-pool"))]
pub use smtp::r2d2::SmtpConnectionManager;
use std::ffi::OsStr;
use std::fmt::{self, Display, Formatter};
use std::io;
@@ -67,7 +44,10 @@ use std::str::FromStr;
/// Email address
#[derive(PartialEq, Eq, Clone, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct EmailAddress(String);
impl EmailAddress {
@@ -109,7 +89,10 @@ impl AsRef<OsStr> for EmailAddress {
///
/// We only accept mailboxes, and do not support source routes (as per RFC).
#[derive(PartialEq, Eq, Clone, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct Envelope {
/// The envelope recipients' addresses
///

View File

@@ -1,11 +1,11 @@
//! Error and result type for sendmail transport
use self::Error::*;
use std::io;
use std::{
error::Error as StdError,
fmt::{self, Display, Formatter},
};
use self::Error::*;
use std::io;
/// An enum of all error kinds.
#[derive(Debug)]

View File

@@ -2,17 +2,21 @@
//!
use crate::sendmail::error::SendmailResult;
use crate::SendableEmail;
use crate::Transport;
use log::info;
use std::io::prelude::*;
use std::io::Read;
use std::process::{Command, Stdio};
use crate::SendableEmail;
use crate::Transport;
pub mod error;
/// Sends an email using the `sendmail` command
#[derive(Debug, Default)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct SendmailTransport {
command: String,
}

View File

@@ -31,7 +31,10 @@ impl<S: Into<String>, T: Into<String>> IntoCredentials for (S, T) {
/// Contains user credentials
#[derive(PartialEq, Eq, Clone, Hash, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct Credentials {
authentication_identity: String,
secret: String,
@@ -49,7 +52,10 @@ impl Credentials {
/// Represents authentication mechanisms
#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub enum Mechanism {
/// PLAIN authentication mechanism
/// RFC 4616: https://tools.ietf.org/html/rfc4616

View File

@@ -1,12 +1,13 @@
//! SMTP client
use bufstream::BufStream;
use nom::ErrorKind as NomErrorKind;
use crate::smtp::authentication::{Credentials, Mechanism};
use crate::smtp::client::net::{ClientTlsParameters, Connector, NetworkStream, Timeout};
use crate::smtp::commands::*;
use crate::smtp::error::{Error, SmtpResult};
use crate::smtp::response::Response;
use bufstream::BufStream;
use log::debug;
use nom::ErrorKind as NomErrorKind;
use std::fmt::{Debug, Display};
use std::io::{self, BufRead, BufReader, Read, Write};
use std::net::ToSocketAddrs;
@@ -18,7 +19,10 @@ pub mod net;
/// The codec used for transparency
#[derive(Default, Clone, Copy, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct ClientCodec {
escape_count: u8,
}

View File

@@ -1,7 +1,7 @@
//! A trait to represent a stream
use native_tls::{Protocol, TlsConnector, TlsStream};
use crate::smtp::client::mock::MockStream;
use native_tls::{Protocol, TlsConnector, TlsStream};
use std::io::{self, ErrorKind, Read, Write};
use std::net::{Ipv4Addr, Shutdown, SocketAddr, SocketAddrV4, TcpStream};
use std::time::Duration;

View File

@@ -2,18 +2,22 @@
//! SMTP commands
use base64;
use crate::smtp::authentication::{Credentials, Mechanism};
use crate::smtp::error::Error;
use crate::smtp::extension::ClientId;
use crate::smtp::extension::{MailParameter, RcptParameter};
use crate::smtp::response::Response;
use std::fmt::{self, Display, Formatter};
use crate::EmailAddress;
use base64;
use log::debug;
use std::fmt::{self, Display, Formatter};
/// EHLO command
#[derive(PartialEq, Clone, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct EhloCommand {
client_id: ClientId,
}
@@ -33,7 +37,10 @@ impl EhloCommand {
/// STARTTLS command
#[derive(PartialEq, Clone, Debug, Copy)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct StarttlsCommand;
impl Display for StarttlsCommand {
@@ -44,7 +51,10 @@ impl Display for StarttlsCommand {
/// MAIL command
#[derive(PartialEq, Clone, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct MailCommand {
sender: Option<EmailAddress>,
parameters: Vec<MailParameter>,
@@ -73,7 +83,10 @@ impl MailCommand {
/// RCPT command
#[derive(PartialEq, Clone, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct RcptCommand {
recipient: EmailAddress,
parameters: Vec<RcptParameter>,
@@ -101,7 +114,10 @@ impl RcptCommand {
/// DATA command
#[derive(PartialEq, Clone, Debug, Copy)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct DataCommand;
impl Display for DataCommand {
@@ -112,7 +128,10 @@ impl Display for DataCommand {
/// QUIT command
#[derive(PartialEq, Clone, Debug, Copy)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct QuitCommand;
impl Display for QuitCommand {
@@ -123,7 +142,10 @@ impl Display for QuitCommand {
/// NOOP command
#[derive(PartialEq, Clone, Debug, Copy)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct NoopCommand;
impl Display for NoopCommand {
@@ -134,7 +156,10 @@ impl Display for NoopCommand {
/// HELP command
#[derive(PartialEq, Clone, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct HelpCommand {
argument: Option<String>,
}
@@ -158,7 +183,10 @@ impl HelpCommand {
/// VRFY command
#[derive(PartialEq, Clone, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct VrfyCommand {
argument: String,
}
@@ -179,7 +207,10 @@ impl VrfyCommand {
/// EXPN command
#[derive(PartialEq, Clone, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct ExpnCommand {
argument: String,
}
@@ -199,7 +230,10 @@ impl ExpnCommand {
/// RSET command
#[derive(PartialEq, Clone, Debug, Copy)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct RsetCommand;
impl Display for RsetCommand {
@@ -210,7 +244,10 @@ impl Display for RsetCommand {
/// AUTH command
#[derive(PartialEq, Clone, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct AuthCommand {
mechanism: Mechanism,
credentials: Credentials,

View File

@@ -1,10 +1,10 @@
//! Error and result type for SMTP clients
use self::Error::*;
use crate::smtp::response::{Response, Severity};
use base64::DecodeError;
use native_tls;
use nom;
use crate::smtp::response::{Response, Severity};
use std::error::Error as StdError;
use std::fmt;
use std::fmt::{Display, Formatter};

View File

@@ -1,10 +1,10 @@
//! ESMTP features
use hostname::get_hostname;
use crate::smtp::authentication::Mechanism;
use crate::smtp::error::Error;
use crate::smtp::response::Response;
use crate::smtp::util::XText;
use hostname::get_hostname;
use std::collections::HashSet;
use std::fmt::{self, Display, Formatter};
use std::net::{Ipv4Addr, Ipv6Addr};
@@ -15,7 +15,10 @@ pub const DEFAULT_DOMAIN_CLIENT_ID: &str = "localhost";
/// Client identifier, the parameter to `EHLO`
#[derive(PartialEq, Eq, Clone, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub enum ClientId {
/// A fully-qualified domain name
Domain(String),
@@ -50,7 +53,10 @@ impl ClientId {
/// Supported ESMTP keywords
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub enum Extension {
/// 8BITMIME keyword
///
@@ -81,7 +87,10 @@ impl Display for Extension {
/// Contains information about an SMTP server
#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct ServerInfo {
/// Server name
///
@@ -174,7 +183,10 @@ impl ServerInfo {
/// A `MAIL FROM` extension parameter
#[derive(PartialEq, Eq, Clone, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub enum MailParameter {
/// `BODY` parameter
Body(MailBodyParameter),
@@ -211,7 +223,10 @@ impl Display for MailParameter {
/// Values for the `BODY` parameter to `MAIL FROM`
#[derive(PartialEq, Eq, Clone, Debug, Copy)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub enum MailBodyParameter {
/// `7BIT`
SevenBit,
@@ -230,7 +245,10 @@ impl Display for MailBodyParameter {
/// A `RCPT TO` extension parameter
#[derive(PartialEq, Eq, Clone, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub enum RcptParameter {
/// Custom parameter
Other {

View File

@@ -13,7 +13,6 @@
//! * SMTPUTF8 ([RFC 6531](http://tools.ietf.org/html/rfc6531))
//!
use native_tls::TlsConnector;
use crate::smtp::authentication::{
Credentials, Mechanism, DEFAULT_ENCRYPTED_MECHANISMS, DEFAULT_UNENCRYPTED_MECHANISMS,
};
@@ -23,9 +22,11 @@ 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 log::{debug, info};
use native_tls::TlsConnector;
use std::net::{SocketAddr, ToSocketAddrs};
use std::time::Duration;
use crate::{SendableEmail, Transport};
pub mod authentication;
pub mod client;
@@ -64,7 +65,10 @@ pub enum ClientSecurity {
/// Configures connection reuse behavior
#[derive(Clone, Debug, Copy)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub enum ConnectionReuseParameters {
/// Unlimited connection reuse
ReuseUnlimited,

View File

@@ -1,6 +1,7 @@
//! SMTP response, containing a mandatory return code and an optional text
//! message
use nom::*;
use nom::{crlf, ErrorKind as NomErrorKind};
use std::fmt::{Display, Formatter, Result};
use std::result;
@@ -8,7 +9,10 @@ use std::str::{from_utf8, FromStr};
/// First digit indicates severity
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub enum Severity {
/// 2yx
PositiveCompletion = 2,
@@ -28,7 +32,10 @@ impl Display for Severity {
/// Second digit
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub enum Category {
/// x0z
Syntax = 0,
@@ -52,7 +59,10 @@ impl Display for Category {
/// The detail digit of a response code (third digit)
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub enum Detail {
#[allow(missing_docs)]
Zero = 0,
@@ -84,7 +94,10 @@ impl Display for Detail {
/// Represents a 3 digit SMTP response code
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct Code {
/// First digit of the response code
pub severity: Severity,
@@ -115,7 +128,10 @@ impl Code {
///
/// The text message is optional, only the code is mandatory
#[derive(PartialEq, Eq, Clone, Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct Response {
/// Response code
pub code: Code,

View File

@@ -4,7 +4,10 @@ use std::fmt::{Display, Formatter, Result as FmtResult};
/// Encode a string as xtext
#[derive(Debug)]
#[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-impls",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct XText<'a>(pub &'a str);
impl<'a> Display for XText<'a> {

View File

@@ -4,6 +4,7 @@
use crate::SendableEmail;
use crate::Transport;
use log::info;
/// This transport logs the message envelope and returns the given response
#[derive(Debug, Clone, Copy)]

View File

@@ -10,6 +10,7 @@ license = "MIT"
authors = ["Alexis Mousset <contact@amousset.me>"]
categories = ["email"]
keywords = ["email", "mailer"]
edition = "2018"
[badges]
travis-ci = { repository = "lettre/lettre_email" }

View File

@@ -1,12 +1,12 @@
//! Error and result type for emails
use self::Error::*;
use lettre;
use std::io;
use std::{
error::Error as StdError,
fmt::{self, Display, Formatter},
};
use self::Error::*;
/// An enum of all error kinds.
#[derive(Debug)]
@@ -42,7 +42,6 @@ impl StdError for Error {
impl From<io::Error> for Error {
fn from(err: io::Error) -> Error {
Error::Io(err)
}
}

View File

@@ -13,17 +13,10 @@
unused_import_braces
)]
extern crate base64;
extern crate email as email_format;
extern crate lettre;
extern crate mime;
extern crate time;
extern crate uuid;
pub mod error;
pub use crate::email_format::{Address, Header, Mailbox, MimeMessage, MimeMultipartType};
use crate::error::Error;
pub use email::{Address, Header, Mailbox, MimeMessage, MimeMultipartType};
use lettre::{error::Error as LettreError, EmailAddress, Envelope, SendableEmail};
use mime::Mime;
use std::fs;
@@ -411,15 +404,11 @@ impl EmailBuilder {
// if it's an author group, use the first author
Some(mailbox) => Ok(mailbox.address.clone()),
// for an empty author group (the rarest of the rare cases)
None => Err(Error::Envelope(
LettreError::MissingFrom,
)), // empty envelope sender
None => Err(Error::Envelope(LettreError::MissingFrom)), // empty envelope sender
},
},
// if we don't have a from header
None => Err(Error::Envelope(
LettreError::MissingFrom,
)), // empty envelope sender
None => Err(Error::Envelope(LettreError::MissingFrom)), // empty envelope sender
}
}
}?)?);
@@ -443,9 +432,7 @@ impl EmailBuilder {
.message
.header(Header::new_with_value("From".into(), from).unwrap());
} else {
Err(Error::Envelope(
LettreError::MissingFrom,
))?;
Err(Error::Envelope(LettreError::MissingFrom))?;
}
if !self.cc.is_empty() {
self.message = self

View File

@@ -10,7 +10,7 @@ Lettre is an email library that allows creating and sending messages. It provide
The `lettre_email` crate allows you to compose messages, and the `lettre`
provide transports to send them.
Lettre requires Rust 1.26 or newer. Add the following to your `Cargo.toml`:
Lettre requires Rust 1.31 or newer. Add the following to your `Cargo.toml`:
```toml
[dependencies]