feat(all): Rust 2018
This commit is contained in:
@@ -3,7 +3,7 @@ rust:
|
|||||||
- stable
|
- stable
|
||||||
- beta
|
- beta
|
||||||
- nightly
|
- nightly
|
||||||
- 1.26.0
|
- 1.31.0
|
||||||
matrix:
|
matrix:
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- rust: nightly
|
- rust: nightly
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ Lettre provides the following features:
|
|||||||
|
|
||||||
## Example
|
## 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`:
|
To use this library, add the following to your `Cargo.toml`:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ license = "MIT"
|
|||||||
authors = ["Alexis Mousset <contact@amousset.me>"]
|
authors = ["Alexis Mousset <contact@amousset.me>"]
|
||||||
categories = ["email"]
|
categories = ["email"]
|
||||||
keywords = ["email", "smtp", "mailer"]
|
keywords = ["email", "smtp", "mailer"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
[badges]
|
[badges]
|
||||||
travis-ci = { repository = "lettre/lettre" }
|
travis-ci = { repository = "lettre/lettre" }
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
use self::Error::*;
|
||||||
use std::{
|
use std::{
|
||||||
error::Error as StdError,
|
error::Error as StdError,
|
||||||
fmt::{self, Display, Formatter},
|
fmt::{self, Display, Formatter},
|
||||||
};
|
};
|
||||||
use self::Error::*;
|
|
||||||
|
|
||||||
/// Error type for email content
|
/// Error type for email content
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
//! Error and result type for file transport
|
//! Error and result type for file transport
|
||||||
|
|
||||||
|
use self::Error::*;
|
||||||
|
use serde_json;
|
||||||
|
use std::io;
|
||||||
use std::{
|
use std::{
|
||||||
error::Error as StdError,
|
error::Error as StdError,
|
||||||
fmt::{self, Display, Formatter},
|
fmt::{self, Display, Formatter},
|
||||||
};
|
};
|
||||||
use serde_json;
|
|
||||||
use std::io;
|
|
||||||
use self::Error::*;
|
|
||||||
|
|
||||||
/// An enum of all error kinds.
|
/// An enum of all error kinds.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
@@ -4,19 +4,22 @@
|
|||||||
//!
|
//!
|
||||||
|
|
||||||
use crate::file::error::FileResult;
|
use crate::file::error::FileResult;
|
||||||
|
use crate::Envelope;
|
||||||
|
use crate::SendableEmail;
|
||||||
|
use crate::Transport;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use crate::Envelope;
|
|
||||||
use crate::SendableEmail;
|
|
||||||
use crate::Transport;
|
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
|
||||||
/// Writes the content and the envelope information to a file
|
/// Writes the content and the envelope information to a file
|
||||||
#[derive(Debug)]
|
#[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 {
|
pub struct FileTransport {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
}
|
}
|
||||||
@@ -31,7 +34,10 @@ impl FileTransport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
#[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 {
|
struct SerializableEmail {
|
||||||
envelope: Envelope,
|
envelope: Envelope,
|
||||||
message_id: String,
|
message_id: String,
|
||||||
|
|||||||
@@ -12,29 +12,6 @@
|
|||||||
unstable_features,
|
unstable_features,
|
||||||
unused_import_braces
|
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;
|
pub mod error;
|
||||||
#[cfg(feature = "file-transport")]
|
#[cfg(feature = "file-transport")]
|
||||||
@@ -47,17 +24,17 @@ pub mod stub;
|
|||||||
|
|
||||||
use crate::error::EmailResult;
|
use crate::error::EmailResult;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use fast_chemail::is_valid_email;
|
|
||||||
#[cfg(feature = "file-transport")]
|
#[cfg(feature = "file-transport")]
|
||||||
pub use crate::file::FileTransport;
|
pub use crate::file::FileTransport;
|
||||||
#[cfg(feature = "sendmail-transport")]
|
#[cfg(feature = "sendmail-transport")]
|
||||||
pub use crate::sendmail::SendmailTransport;
|
pub use crate::sendmail::SendmailTransport;
|
||||||
#[cfg(feature = "smtp-transport")]
|
#[cfg(feature = "smtp-transport")]
|
||||||
pub use crate::smtp::client::net::ClientTlsParameters;
|
pub use crate::smtp::client::net::ClientTlsParameters;
|
||||||
#[cfg(all(feature = "smtp-transport", feature = "connection-pool"))]
|
|
||||||
pub use smtp::r2d2::SmtpConnectionManager;
|
|
||||||
#[cfg(feature = "smtp-transport")]
|
#[cfg(feature = "smtp-transport")]
|
||||||
pub use crate::smtp::{ClientSecurity, SmtpClient, SmtpTransport};
|
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::ffi::OsStr;
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
use std::io;
|
use std::io;
|
||||||
@@ -67,7 +44,10 @@ use std::str::FromStr;
|
|||||||
|
|
||||||
/// Email address
|
/// Email address
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
#[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);
|
pub struct EmailAddress(String);
|
||||||
|
|
||||||
impl EmailAddress {
|
impl EmailAddress {
|
||||||
@@ -109,7 +89,10 @@ impl AsRef<OsStr> for EmailAddress {
|
|||||||
///
|
///
|
||||||
/// We only accept mailboxes, and do not support source routes (as per RFC).
|
/// We only accept mailboxes, and do not support source routes (as per RFC).
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
#[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 {
|
pub struct Envelope {
|
||||||
/// The envelope recipients' addresses
|
/// The envelope recipients' addresses
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
//! Error and result type for sendmail transport
|
//! Error and result type for sendmail transport
|
||||||
|
|
||||||
|
use self::Error::*;
|
||||||
|
use std::io;
|
||||||
use std::{
|
use std::{
|
||||||
error::Error as StdError,
|
error::Error as StdError,
|
||||||
fmt::{self, Display, Formatter},
|
fmt::{self, Display, Formatter},
|
||||||
};
|
};
|
||||||
use self::Error::*;
|
|
||||||
use std::io;
|
|
||||||
|
|
||||||
/// An enum of all error kinds.
|
/// An enum of all error kinds.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
@@ -2,17 +2,21 @@
|
|||||||
//!
|
//!
|
||||||
|
|
||||||
use crate::sendmail::error::SendmailResult;
|
use crate::sendmail::error::SendmailResult;
|
||||||
|
use crate::SendableEmail;
|
||||||
|
use crate::Transport;
|
||||||
|
use log::info;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
use crate::SendableEmail;
|
|
||||||
use crate::Transport;
|
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
|
||||||
/// Sends an email using the `sendmail` command
|
/// Sends an email using the `sendmail` command
|
||||||
#[derive(Debug, Default)]
|
#[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 {
|
pub struct SendmailTransport {
|
||||||
command: String,
|
command: String,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,10 @@ impl<S: Into<String>, T: Into<String>> IntoCredentials for (S, T) {
|
|||||||
|
|
||||||
/// Contains user credentials
|
/// Contains user credentials
|
||||||
#[derive(PartialEq, Eq, Clone, Hash, Debug)]
|
#[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 {
|
pub struct Credentials {
|
||||||
authentication_identity: String,
|
authentication_identity: String,
|
||||||
secret: String,
|
secret: String,
|
||||||
@@ -49,7 +52,10 @@ impl Credentials {
|
|||||||
|
|
||||||
/// Represents authentication mechanisms
|
/// Represents authentication mechanisms
|
||||||
#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)]
|
#[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 {
|
pub enum Mechanism {
|
||||||
/// PLAIN authentication mechanism
|
/// PLAIN authentication mechanism
|
||||||
/// RFC 4616: https://tools.ietf.org/html/rfc4616
|
/// RFC 4616: https://tools.ietf.org/html/rfc4616
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
//! SMTP client
|
//! SMTP client
|
||||||
|
|
||||||
use bufstream::BufStream;
|
|
||||||
use nom::ErrorKind as NomErrorKind;
|
|
||||||
use crate::smtp::authentication::{Credentials, Mechanism};
|
use crate::smtp::authentication::{Credentials, Mechanism};
|
||||||
use crate::smtp::client::net::{ClientTlsParameters, Connector, NetworkStream, Timeout};
|
use crate::smtp::client::net::{ClientTlsParameters, Connector, NetworkStream, Timeout};
|
||||||
use crate::smtp::commands::*;
|
use crate::smtp::commands::*;
|
||||||
use crate::smtp::error::{Error, SmtpResult};
|
use crate::smtp::error::{Error, SmtpResult};
|
||||||
use crate::smtp::response::Response;
|
use crate::smtp::response::Response;
|
||||||
|
use bufstream::BufStream;
|
||||||
|
use log::debug;
|
||||||
|
use nom::ErrorKind as NomErrorKind;
|
||||||
use std::fmt::{Debug, Display};
|
use std::fmt::{Debug, Display};
|
||||||
use std::io::{self, BufRead, BufReader, Read, Write};
|
use std::io::{self, BufRead, BufReader, Read, Write};
|
||||||
use std::net::ToSocketAddrs;
|
use std::net::ToSocketAddrs;
|
||||||
@@ -18,7 +19,10 @@ pub mod net;
|
|||||||
|
|
||||||
/// The codec used for transparency
|
/// The codec used for transparency
|
||||||
#[derive(Default, Clone, Copy, Debug)]
|
#[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 {
|
pub struct ClientCodec {
|
||||||
escape_count: u8,
|
escape_count: u8,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//! A trait to represent a stream
|
//! A trait to represent a stream
|
||||||
|
|
||||||
use native_tls::{Protocol, TlsConnector, TlsStream};
|
|
||||||
use crate::smtp::client::mock::MockStream;
|
use crate::smtp::client::mock::MockStream;
|
||||||
|
use native_tls::{Protocol, TlsConnector, TlsStream};
|
||||||
use std::io::{self, ErrorKind, Read, Write};
|
use std::io::{self, ErrorKind, Read, Write};
|
||||||
use std::net::{Ipv4Addr, Shutdown, SocketAddr, SocketAddrV4, TcpStream};
|
use std::net::{Ipv4Addr, Shutdown, SocketAddr, SocketAddrV4, TcpStream};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|||||||
@@ -2,18 +2,22 @@
|
|||||||
|
|
||||||
//! SMTP commands
|
//! SMTP commands
|
||||||
|
|
||||||
use base64;
|
|
||||||
use crate::smtp::authentication::{Credentials, Mechanism};
|
use crate::smtp::authentication::{Credentials, Mechanism};
|
||||||
use crate::smtp::error::Error;
|
use crate::smtp::error::Error;
|
||||||
use crate::smtp::extension::ClientId;
|
use crate::smtp::extension::ClientId;
|
||||||
use crate::smtp::extension::{MailParameter, RcptParameter};
|
use crate::smtp::extension::{MailParameter, RcptParameter};
|
||||||
use crate::smtp::response::Response;
|
use crate::smtp::response::Response;
|
||||||
use std::fmt::{self, Display, Formatter};
|
|
||||||
use crate::EmailAddress;
|
use crate::EmailAddress;
|
||||||
|
use base64;
|
||||||
|
use log::debug;
|
||||||
|
use std::fmt::{self, Display, Formatter};
|
||||||
|
|
||||||
/// EHLO command
|
/// EHLO command
|
||||||
#[derive(PartialEq, Clone, Debug)]
|
#[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 {
|
pub struct EhloCommand {
|
||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
}
|
}
|
||||||
@@ -33,7 +37,10 @@ impl EhloCommand {
|
|||||||
|
|
||||||
/// STARTTLS command
|
/// STARTTLS command
|
||||||
#[derive(PartialEq, Clone, Debug, Copy)]
|
#[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;
|
pub struct StarttlsCommand;
|
||||||
|
|
||||||
impl Display for StarttlsCommand {
|
impl Display for StarttlsCommand {
|
||||||
@@ -44,7 +51,10 @@ impl Display for StarttlsCommand {
|
|||||||
|
|
||||||
/// MAIL command
|
/// MAIL command
|
||||||
#[derive(PartialEq, Clone, Debug)]
|
#[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 {
|
pub struct MailCommand {
|
||||||
sender: Option<EmailAddress>,
|
sender: Option<EmailAddress>,
|
||||||
parameters: Vec<MailParameter>,
|
parameters: Vec<MailParameter>,
|
||||||
@@ -73,7 +83,10 @@ impl MailCommand {
|
|||||||
|
|
||||||
/// RCPT command
|
/// RCPT command
|
||||||
#[derive(PartialEq, Clone, Debug)]
|
#[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 {
|
pub struct RcptCommand {
|
||||||
recipient: EmailAddress,
|
recipient: EmailAddress,
|
||||||
parameters: Vec<RcptParameter>,
|
parameters: Vec<RcptParameter>,
|
||||||
@@ -101,7 +114,10 @@ impl RcptCommand {
|
|||||||
|
|
||||||
/// DATA command
|
/// DATA command
|
||||||
#[derive(PartialEq, Clone, Debug, Copy)]
|
#[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;
|
pub struct DataCommand;
|
||||||
|
|
||||||
impl Display for DataCommand {
|
impl Display for DataCommand {
|
||||||
@@ -112,7 +128,10 @@ impl Display for DataCommand {
|
|||||||
|
|
||||||
/// QUIT command
|
/// QUIT command
|
||||||
#[derive(PartialEq, Clone, Debug, Copy)]
|
#[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;
|
pub struct QuitCommand;
|
||||||
|
|
||||||
impl Display for QuitCommand {
|
impl Display for QuitCommand {
|
||||||
@@ -123,7 +142,10 @@ impl Display for QuitCommand {
|
|||||||
|
|
||||||
/// NOOP command
|
/// NOOP command
|
||||||
#[derive(PartialEq, Clone, Debug, Copy)]
|
#[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;
|
pub struct NoopCommand;
|
||||||
|
|
||||||
impl Display for NoopCommand {
|
impl Display for NoopCommand {
|
||||||
@@ -134,7 +156,10 @@ impl Display for NoopCommand {
|
|||||||
|
|
||||||
/// HELP command
|
/// HELP command
|
||||||
#[derive(PartialEq, Clone, Debug)]
|
#[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 {
|
pub struct HelpCommand {
|
||||||
argument: Option<String>,
|
argument: Option<String>,
|
||||||
}
|
}
|
||||||
@@ -158,7 +183,10 @@ impl HelpCommand {
|
|||||||
|
|
||||||
/// VRFY command
|
/// VRFY command
|
||||||
#[derive(PartialEq, Clone, Debug)]
|
#[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 {
|
pub struct VrfyCommand {
|
||||||
argument: String,
|
argument: String,
|
||||||
}
|
}
|
||||||
@@ -179,7 +207,10 @@ impl VrfyCommand {
|
|||||||
|
|
||||||
/// EXPN command
|
/// EXPN command
|
||||||
#[derive(PartialEq, Clone, Debug)]
|
#[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 {
|
pub struct ExpnCommand {
|
||||||
argument: String,
|
argument: String,
|
||||||
}
|
}
|
||||||
@@ -199,7 +230,10 @@ impl ExpnCommand {
|
|||||||
|
|
||||||
/// RSET command
|
/// RSET command
|
||||||
#[derive(PartialEq, Clone, Debug, Copy)]
|
#[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;
|
pub struct RsetCommand;
|
||||||
|
|
||||||
impl Display for RsetCommand {
|
impl Display for RsetCommand {
|
||||||
@@ -210,7 +244,10 @@ impl Display for RsetCommand {
|
|||||||
|
|
||||||
/// AUTH command
|
/// AUTH command
|
||||||
#[derive(PartialEq, Clone, Debug)]
|
#[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 {
|
pub struct AuthCommand {
|
||||||
mechanism: Mechanism,
|
mechanism: Mechanism,
|
||||||
credentials: Credentials,
|
credentials: Credentials,
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
//! Error and result type for SMTP clients
|
//! Error and result type for SMTP clients
|
||||||
|
|
||||||
use self::Error::*;
|
use self::Error::*;
|
||||||
|
use crate::smtp::response::{Response, Severity};
|
||||||
use base64::DecodeError;
|
use base64::DecodeError;
|
||||||
use native_tls;
|
use native_tls;
|
||||||
use nom;
|
use nom;
|
||||||
use crate::smtp::response::{Response, Severity};
|
|
||||||
use std::error::Error as StdError;
|
use std::error::Error as StdError;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
//! ESMTP features
|
//! ESMTP features
|
||||||
|
|
||||||
use hostname::get_hostname;
|
|
||||||
use crate::smtp::authentication::Mechanism;
|
use crate::smtp::authentication::Mechanism;
|
||||||
use crate::smtp::error::Error;
|
use crate::smtp::error::Error;
|
||||||
use crate::smtp::response::Response;
|
use crate::smtp::response::Response;
|
||||||
use crate::smtp::util::XText;
|
use crate::smtp::util::XText;
|
||||||
|
use hostname::get_hostname;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||||
@@ -15,7 +15,10 @@ pub const DEFAULT_DOMAIN_CLIENT_ID: &str = "localhost";
|
|||||||
|
|
||||||
/// Client identifier, the parameter to `EHLO`
|
/// Client identifier, the parameter to `EHLO`
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
#[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 {
|
pub enum ClientId {
|
||||||
/// A fully-qualified domain name
|
/// A fully-qualified domain name
|
||||||
Domain(String),
|
Domain(String),
|
||||||
@@ -50,7 +53,10 @@ impl ClientId {
|
|||||||
|
|
||||||
/// Supported ESMTP keywords
|
/// Supported ESMTP keywords
|
||||||
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
|
#[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 {
|
pub enum Extension {
|
||||||
/// 8BITMIME keyword
|
/// 8BITMIME keyword
|
||||||
///
|
///
|
||||||
@@ -81,7 +87,10 @@ impl Display for Extension {
|
|||||||
|
|
||||||
/// Contains information about an SMTP server
|
/// Contains information about an SMTP server
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[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 {
|
pub struct ServerInfo {
|
||||||
/// Server name
|
/// Server name
|
||||||
///
|
///
|
||||||
@@ -174,7 +183,10 @@ impl ServerInfo {
|
|||||||
|
|
||||||
/// A `MAIL FROM` extension parameter
|
/// A `MAIL FROM` extension parameter
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
#[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 {
|
pub enum MailParameter {
|
||||||
/// `BODY` parameter
|
/// `BODY` parameter
|
||||||
Body(MailBodyParameter),
|
Body(MailBodyParameter),
|
||||||
@@ -211,7 +223,10 @@ impl Display for MailParameter {
|
|||||||
|
|
||||||
/// Values for the `BODY` parameter to `MAIL FROM`
|
/// Values for the `BODY` parameter to `MAIL FROM`
|
||||||
#[derive(PartialEq, Eq, Clone, Debug, Copy)]
|
#[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 {
|
pub enum MailBodyParameter {
|
||||||
/// `7BIT`
|
/// `7BIT`
|
||||||
SevenBit,
|
SevenBit,
|
||||||
@@ -230,7 +245,10 @@ impl Display for MailBodyParameter {
|
|||||||
|
|
||||||
/// A `RCPT TO` extension parameter
|
/// A `RCPT TO` extension parameter
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
#[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 {
|
pub enum RcptParameter {
|
||||||
/// Custom parameter
|
/// Custom parameter
|
||||||
Other {
|
Other {
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
//! * SMTPUTF8 ([RFC 6531](http://tools.ietf.org/html/rfc6531))
|
//! * SMTPUTF8 ([RFC 6531](http://tools.ietf.org/html/rfc6531))
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use native_tls::TlsConnector;
|
|
||||||
use crate::smtp::authentication::{
|
use crate::smtp::authentication::{
|
||||||
Credentials, Mechanism, DEFAULT_ENCRYPTED_MECHANISMS, DEFAULT_UNENCRYPTED_MECHANISMS,
|
Credentials, Mechanism, DEFAULT_ENCRYPTED_MECHANISMS, DEFAULT_UNENCRYPTED_MECHANISMS,
|
||||||
};
|
};
|
||||||
@@ -23,9 +22,11 @@ use crate::smtp::client::InnerClient;
|
|||||||
use crate::smtp::commands::*;
|
use crate::smtp::commands::*;
|
||||||
use crate::smtp::error::{Error, SmtpResult};
|
use crate::smtp::error::{Error, SmtpResult};
|
||||||
use crate::smtp::extension::{ClientId, Extension, MailBodyParameter, MailParameter, ServerInfo};
|
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::net::{SocketAddr, ToSocketAddrs};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use crate::{SendableEmail, Transport};
|
|
||||||
|
|
||||||
pub mod authentication;
|
pub mod authentication;
|
||||||
pub mod client;
|
pub mod client;
|
||||||
@@ -64,7 +65,10 @@ pub enum ClientSecurity {
|
|||||||
|
|
||||||
/// Configures connection reuse behavior
|
/// Configures connection reuse behavior
|
||||||
#[derive(Clone, Debug, Copy)]
|
#[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 {
|
pub enum ConnectionReuseParameters {
|
||||||
/// Unlimited connection reuse
|
/// Unlimited connection reuse
|
||||||
ReuseUnlimited,
|
ReuseUnlimited,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
//! SMTP response, containing a mandatory return code and an optional text
|
//! SMTP response, containing a mandatory return code and an optional text
|
||||||
//! message
|
//! message
|
||||||
|
|
||||||
|
use nom::*;
|
||||||
use nom::{crlf, ErrorKind as NomErrorKind};
|
use nom::{crlf, ErrorKind as NomErrorKind};
|
||||||
use std::fmt::{Display, Formatter, Result};
|
use std::fmt::{Display, Formatter, Result};
|
||||||
use std::result;
|
use std::result;
|
||||||
@@ -8,7 +9,10 @@ use std::str::{from_utf8, FromStr};
|
|||||||
|
|
||||||
/// First digit indicates severity
|
/// First digit indicates severity
|
||||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
#[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 {
|
pub enum Severity {
|
||||||
/// 2yx
|
/// 2yx
|
||||||
PositiveCompletion = 2,
|
PositiveCompletion = 2,
|
||||||
@@ -28,7 +32,10 @@ impl Display for Severity {
|
|||||||
|
|
||||||
/// Second digit
|
/// Second digit
|
||||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
#[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 {
|
pub enum Category {
|
||||||
/// x0z
|
/// x0z
|
||||||
Syntax = 0,
|
Syntax = 0,
|
||||||
@@ -52,7 +59,10 @@ impl Display for Category {
|
|||||||
|
|
||||||
/// The detail digit of a response code (third digit)
|
/// The detail digit of a response code (third digit)
|
||||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
#[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 {
|
pub enum Detail {
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
Zero = 0,
|
Zero = 0,
|
||||||
@@ -84,7 +94,10 @@ impl Display for Detail {
|
|||||||
|
|
||||||
/// Represents a 3 digit SMTP response code
|
/// Represents a 3 digit SMTP response code
|
||||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
#[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 {
|
pub struct Code {
|
||||||
/// First digit of the response code
|
/// First digit of the response code
|
||||||
pub severity: Severity,
|
pub severity: Severity,
|
||||||
@@ -115,7 +128,10 @@ impl Code {
|
|||||||
///
|
///
|
||||||
/// The text message is optional, only the code is mandatory
|
/// The text message is optional, only the code is mandatory
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
#[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 {
|
pub struct Response {
|
||||||
/// Response code
|
/// Response code
|
||||||
pub code: Code,
|
pub code: Code,
|
||||||
|
|||||||
@@ -4,7 +4,10 @@ use std::fmt::{Display, Formatter, Result as FmtResult};
|
|||||||
|
|
||||||
/// Encode a string as xtext
|
/// Encode a string as xtext
|
||||||
#[derive(Debug)]
|
#[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);
|
pub struct XText<'a>(pub &'a str);
|
||||||
|
|
||||||
impl<'a> Display for XText<'a> {
|
impl<'a> Display for XText<'a> {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
use crate::SendableEmail;
|
use crate::SendableEmail;
|
||||||
use crate::Transport;
|
use crate::Transport;
|
||||||
|
use log::info;
|
||||||
|
|
||||||
/// This transport logs the message envelope and returns the given response
|
/// This transport logs the message envelope and returns the given response
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ license = "MIT"
|
|||||||
authors = ["Alexis Mousset <contact@amousset.me>"]
|
authors = ["Alexis Mousset <contact@amousset.me>"]
|
||||||
categories = ["email"]
|
categories = ["email"]
|
||||||
keywords = ["email", "mailer"]
|
keywords = ["email", "mailer"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
[badges]
|
[badges]
|
||||||
travis-ci = { repository = "lettre/lettre_email" }
|
travis-ci = { repository = "lettre/lettre_email" }
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
//! Error and result type for emails
|
//! Error and result type for emails
|
||||||
|
|
||||||
|
use self::Error::*;
|
||||||
use lettre;
|
use lettre;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::{
|
use std::{
|
||||||
error::Error as StdError,
|
error::Error as StdError,
|
||||||
fmt::{self, Display, Formatter},
|
fmt::{self, Display, Formatter},
|
||||||
};
|
};
|
||||||
use self::Error::*;
|
|
||||||
|
|
||||||
/// An enum of all error kinds.
|
/// An enum of all error kinds.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -42,7 +42,6 @@ impl StdError for Error {
|
|||||||
impl From<io::Error> for Error {
|
impl From<io::Error> for Error {
|
||||||
fn from(err: io::Error) -> Error {
|
fn from(err: io::Error) -> Error {
|
||||||
Error::Io(err)
|
Error::Io(err)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,17 +13,10 @@
|
|||||||
unused_import_braces
|
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 mod error;
|
||||||
|
|
||||||
pub use crate::email_format::{Address, Header, Mailbox, MimeMessage, MimeMultipartType};
|
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
|
pub use email::{Address, Header, Mailbox, MimeMessage, MimeMultipartType};
|
||||||
use lettre::{error::Error as LettreError, EmailAddress, Envelope, SendableEmail};
|
use lettre::{error::Error as LettreError, EmailAddress, Envelope, SendableEmail};
|
||||||
use mime::Mime;
|
use mime::Mime;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
@@ -411,15 +404,11 @@ impl EmailBuilder {
|
|||||||
// if it's an author group, use the first author
|
// if it's an author group, use the first author
|
||||||
Some(mailbox) => Ok(mailbox.address.clone()),
|
Some(mailbox) => Ok(mailbox.address.clone()),
|
||||||
// for an empty author group (the rarest of the rare cases)
|
// for an empty author group (the rarest of the rare cases)
|
||||||
None => Err(Error::Envelope(
|
None => Err(Error::Envelope(LettreError::MissingFrom)), // empty envelope sender
|
||||||
LettreError::MissingFrom,
|
|
||||||
)), // empty envelope sender
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// if we don't have a from header
|
// if we don't have a from header
|
||||||
None => Err(Error::Envelope(
|
None => Err(Error::Envelope(LettreError::MissingFrom)), // empty envelope sender
|
||||||
LettreError::MissingFrom,
|
|
||||||
)), // empty envelope sender
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}?)?);
|
}?)?);
|
||||||
@@ -443,9 +432,7 @@ impl EmailBuilder {
|
|||||||
.message
|
.message
|
||||||
.header(Header::new_with_value("From".into(), from).unwrap());
|
.header(Header::new_with_value("From".into(), from).unwrap());
|
||||||
} else {
|
} else {
|
||||||
Err(Error::Envelope(
|
Err(Error::Envelope(LettreError::MissingFrom))?;
|
||||||
LettreError::MissingFrom,
|
|
||||||
))?;
|
|
||||||
}
|
}
|
||||||
if !self.cc.is_empty() {
|
if !self.cc.is_empty() {
|
||||||
self.message = self
|
self.message = self
|
||||||
|
|||||||
@@ -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`
|
The `lettre_email` crate allows you to compose messages, and the `lettre`
|
||||||
provide transports to send them.
|
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
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
Reference in New Issue
Block a user