Drop tokio 0.2 support (#617)
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
Several breaking changes were made between 0.9 and 0.10, but changes should be straightforward:
|
Several breaking changes were made between 0.9 and 0.10, but changes should be straightforward:
|
||||||
|
|
||||||
* MSRV is now 1.45.2
|
* MSRV is now 1.46
|
||||||
* The `lettre_email` crate has been merged into `lettre`. To migrate, replace `lettre_email` with `lettre::message`
|
* The `lettre_email` crate has been merged into `lettre`. To migrate, replace `lettre_email` with `lettre::message`
|
||||||
and make sure to enable the `builder` feature (it's enabled by default).
|
and make sure to enable the `builder` feature (it's enabled by default).
|
||||||
* `SendableEmail` has been renamed to `Email` and `EmailBuilder::build()` produces it directly. To migrate,
|
* `SendableEmail` has been renamed to `Email` and `EmailBuilder::build()` produces it directly. To migrate,
|
||||||
@@ -14,7 +14,7 @@ Several breaking changes were made between 0.9 and 0.10, but changes should be s
|
|||||||
|
|
||||||
#### Features
|
#### Features
|
||||||
|
|
||||||
* Add `tokio` 0.2 and 1.0 support
|
* Add `tokio` 1 support
|
||||||
* Add `rustls` support
|
* Add `rustls` support
|
||||||
* Add `async-std` support. NOTE: native-tls isn't supported when using async-std for the smtp transport.
|
* Add `async-std` support. NOTE: native-tls isn't supported when using async-std for the smtp transport.
|
||||||
* Allow enabling multiple SMTP authentication mechanisms
|
* Allow enabling multiple SMTP authentication mechanisms
|
||||||
|
|||||||
15
Cargo.toml
15
Cargo.toml
@@ -57,9 +57,6 @@ async-std = { version = "1.8", optional = true, features = ["unstable"] }
|
|||||||
async-rustls = { version = "0.2", optional = true }
|
async-rustls = { version = "0.2", optional = true }
|
||||||
|
|
||||||
## tokio
|
## tokio
|
||||||
tokio02_crate = { package = "tokio", version = "0.2.7", features = ["fs", "process", "tcp", "dns", "io-util"], optional = true }
|
|
||||||
tokio02_native_tls_crate = { package = "tokio-native-tls", version = "0.1", optional = true }
|
|
||||||
tokio02_rustls = { package = "tokio-rustls", version = "0.15", optional = true }
|
|
||||||
tokio1_crate = { package = "tokio", version = "1", features = ["fs", "process", "net", "io-util"], optional = true }
|
tokio1_crate = { package = "tokio", version = "1", features = ["fs", "process", "net", "io-util"], optional = true }
|
||||||
tokio1_native_tls_crate = { package = "tokio-native-tls", version = "0.3", optional = true }
|
tokio1_native_tls_crate = { package = "tokio-native-tls", version = "0.3", optional = true }
|
||||||
tokio1_rustls = { package = "tokio-rustls", version = "0.22", optional = true }
|
tokio1_rustls = { package = "tokio-rustls", version = "0.22", optional = true }
|
||||||
@@ -69,7 +66,6 @@ criterion = "0.3"
|
|||||||
tracing-subscriber = "0.2.10"
|
tracing-subscriber = "0.2.10"
|
||||||
glob = "0.3"
|
glob = "0.3"
|
||||||
walkdir = "2"
|
walkdir = "2"
|
||||||
tokio02_crate = { package = "tokio", version = "0.2.7", features = ["macros", "rt-threaded"] }
|
|
||||||
tokio1_crate = { package = "tokio", version = "1", features = ["macros", "rt-multi-thread"] }
|
tokio1_crate = { package = "tokio", version = "1", features = ["macros", "rt-multi-thread"] }
|
||||||
async-std = { version = "1.8", features = ["attributes"] }
|
async-std = { version = "1.8", features = ["attributes"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
@@ -95,9 +91,6 @@ rustls-tls = ["webpki", "webpki-roots", "rustls"]
|
|||||||
async-std1 = ["async-std", "async-trait", "futures-io", "futures-util"]
|
async-std1 = ["async-std", "async-trait", "futures-io", "futures-util"]
|
||||||
#async-std1-native-tls = ["async-std1", "native-tls", "async-native-tls"]
|
#async-std1-native-tls = ["async-std1", "native-tls", "async-native-tls"]
|
||||||
async-std1-rustls-tls = ["async-std1", "rustls-tls", "async-rustls"]
|
async-std1-rustls-tls = ["async-std1", "rustls-tls", "async-rustls"]
|
||||||
tokio02 = ["tokio02_crate", "async-trait", "futures-io", "futures-util"]
|
|
||||||
tokio02-native-tls = ["tokio02", "native-tls", "tokio02_native_tls_crate"]
|
|
||||||
tokio02-rustls-tls = ["tokio02", "rustls-tls", "tokio02_rustls"]
|
|
||||||
tokio1 = ["tokio1_crate", "async-trait", "futures-io", "futures-util"]
|
tokio1 = ["tokio1_crate", "async-trait", "futures-io", "futures-util"]
|
||||||
tokio1-native-tls = ["tokio1", "native-tls", "tokio1_native_tls_crate"]
|
tokio1-native-tls = ["tokio1", "native-tls", "tokio1_native_tls_crate"]
|
||||||
tokio1-rustls-tls = ["tokio1", "rustls-tls", "tokio1_rustls"]
|
tokio1-rustls-tls = ["tokio1", "rustls-tls", "tokio1_rustls"]
|
||||||
@@ -130,14 +123,6 @@ required-features = ["smtp-transport", "native-tls", "builder"]
|
|||||||
name = "smtp_selfsigned"
|
name = "smtp_selfsigned"
|
||||||
required-features = ["smtp-transport", "native-tls", "builder"]
|
required-features = ["smtp-transport", "native-tls", "builder"]
|
||||||
|
|
||||||
[[example]]
|
|
||||||
name = "tokio02_smtp_tls"
|
|
||||||
required-features = ["smtp-transport", "tokio02", "tokio02-native-tls", "builder"]
|
|
||||||
|
|
||||||
[[example]]
|
|
||||||
name = "tokio02_smtp_starttls"
|
|
||||||
required-features = ["smtp-transport", "tokio02", "tokio02-native-tls", "builder"]
|
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "tokio1_smtp_tls"
|
name = "tokio1_smtp_tls"
|
||||||
required-features = ["smtp-transport", "tokio1", "tokio1-native-tls", "builder"]
|
required-features = ["smtp-transport", "tokio1", "tokio1-native-tls", "builder"]
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ This folder contains examples showing how to use lettre in your own projects.
|
|||||||
- [smtp_starttls.rs] - Send an email over SMTP with STARTTLS and authenticating with username and password.
|
- [smtp_starttls.rs] - Send an email over SMTP with STARTTLS and authenticating with username and password.
|
||||||
- [smtp_selfsigned.rs] - Send an email over SMTP encrypted with TLS using a self-signed certificate and authenticating with username and password.
|
- [smtp_selfsigned.rs] - Send an email over SMTP encrypted with TLS using a self-signed certificate and authenticating with username and password.
|
||||||
- The [smtp_tls.rs] and [smtp_starttls.rs] examples also feature `async`hronous implementations powered by [Tokio](https://tokio.rs/).
|
- The [smtp_tls.rs] and [smtp_starttls.rs] examples also feature `async`hronous implementations powered by [Tokio](https://tokio.rs/).
|
||||||
These files are prefixed with `tokio02_`, `tokio1_` or `asyncstd1_`.
|
These files are prefixed with `tokio1_` or `asyncstd1_`.
|
||||||
|
|
||||||
[basic_html.rs]: ./basic_html.rs
|
[basic_html.rs]: ./basic_html.rs
|
||||||
[maud_html.rs]: ./maud_html.rs
|
[maud_html.rs]: ./maud_html.rs
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
// This line is only to make it compile from lettre's examples folder,
|
|
||||||
// since it uses Rust 2018 crate renaming to import tokio.
|
|
||||||
// Won't be needed in user's code.
|
|
||||||
use tokio02_crate as tokio;
|
|
||||||
|
|
||||||
use lettre::{
|
|
||||||
transport::smtp::authentication::Credentials, AsyncSmtpTransport, AsyncTransport, Message,
|
|
||||||
Tokio02Executor,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() {
|
|
||||||
tracing_subscriber::fmt::init();
|
|
||||||
|
|
||||||
let email = Message::builder()
|
|
||||||
.from("NoBody <nobody@domain.tld>".parse().unwrap())
|
|
||||||
.reply_to("Yuin <yuin@domain.tld>".parse().unwrap())
|
|
||||||
.to("Hei <hei@domain.tld>".parse().unwrap())
|
|
||||||
.subject("Happy new async year")
|
|
||||||
.body(String::from("Be happy with async!"))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let creds = Credentials::new("smtp_username".to_string(), "smtp_password".to_string());
|
|
||||||
|
|
||||||
// Open a remote connection to gmail using STARTTLS
|
|
||||||
let mailer: AsyncSmtpTransport<Tokio02Executor> =
|
|
||||||
AsyncSmtpTransport::<Tokio02Executor>::starttls_relay("smtp.gmail.com")
|
|
||||||
.unwrap()
|
|
||||||
.credentials(creds)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Send the email
|
|
||||||
match mailer.send(email).await {
|
|
||||||
Ok(_) => println!("Email sent successfully!"),
|
|
||||||
Err(e) => panic!("Could not send email: {:?}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
// This line is only to make it compile from lettre's examples folder,
|
|
||||||
// since it uses Rust 2018 crate renaming to import tokio.
|
|
||||||
// Won't be needed in user's code.
|
|
||||||
use tokio02_crate as tokio;
|
|
||||||
|
|
||||||
use lettre::{
|
|
||||||
transport::smtp::authentication::Credentials, AsyncSmtpTransport, AsyncTransport, Message,
|
|
||||||
Tokio02Executor,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() {
|
|
||||||
tracing_subscriber::fmt::init();
|
|
||||||
|
|
||||||
let email = Message::builder()
|
|
||||||
.from("NoBody <nobody@domain.tld>".parse().unwrap())
|
|
||||||
.reply_to("Yuin <yuin@domain.tld>".parse().unwrap())
|
|
||||||
.to("Hei <hei@domain.tld>".parse().unwrap())
|
|
||||||
.subject("Happy new async year")
|
|
||||||
.body(String::from("Be happy with async!"))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let creds = Credentials::new("smtp_username".to_string(), "smtp_password".to_string());
|
|
||||||
|
|
||||||
// Open a remote connection to gmail
|
|
||||||
let mailer: AsyncSmtpTransport<Tokio02Executor> =
|
|
||||||
AsyncSmtpTransport::<Tokio02Executor>::relay("smtp.gmail.com")
|
|
||||||
.unwrap()
|
|
||||||
.credentials(creds)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Send the email
|
|
||||||
match mailer.send(email).await {
|
|
||||||
Ok(_) => println!("Email sent successfully!"),
|
|
||||||
Err(e) => panic!("Could not send email: {:?}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,22 +8,22 @@ use std::path::Path;
|
|||||||
|
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
feature = "smtp-transport",
|
feature = "smtp-transport",
|
||||||
any(feature = "tokio02", feature = "tokio1", feature = "async-std1")
|
any(feature = "tokio1", feature = "async-std1")
|
||||||
))]
|
))]
|
||||||
use crate::transport::smtp::client::AsyncSmtpConnection;
|
use crate::transport::smtp::client::AsyncSmtpConnection;
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
feature = "smtp-transport",
|
feature = "smtp-transport",
|
||||||
any(feature = "tokio02", feature = "tokio1", feature = "async-std1")
|
any(feature = "tokio1", feature = "async-std1")
|
||||||
))]
|
))]
|
||||||
use crate::transport::smtp::client::Tls;
|
use crate::transport::smtp::client::Tls;
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
feature = "smtp-transport",
|
feature = "smtp-transport",
|
||||||
any(feature = "tokio02", feature = "tokio1", feature = "async-std1")
|
any(feature = "tokio1", feature = "async-std1")
|
||||||
))]
|
))]
|
||||||
use crate::transport::smtp::extension::ClientId;
|
use crate::transport::smtp::extension::ClientId;
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
feature = "smtp-transport",
|
feature = "smtp-transport",
|
||||||
any(feature = "tokio02", feature = "tokio1", feature = "async-std1")
|
any(feature = "tokio1", feature = "async-std1")
|
||||||
))]
|
))]
|
||||||
use crate::transport::smtp::Error;
|
use crate::transport::smtp::Error;
|
||||||
|
|
||||||
@@ -35,10 +35,7 @@ use crate::transport::smtp::Error;
|
|||||||
/// [`AsyncSmtpTransport`]: crate::AsyncSmtpTransport
|
/// [`AsyncSmtpTransport`]: crate::AsyncSmtpTransport
|
||||||
/// [`AsyncSendmailTransport`]: crate::AsyncSendmailTransport
|
/// [`AsyncSendmailTransport`]: crate::AsyncSendmailTransport
|
||||||
/// [`AsyncFileTransport`]: crate::AsyncFileTransport
|
/// [`AsyncFileTransport`]: crate::AsyncFileTransport
|
||||||
#[cfg_attr(
|
#[cfg_attr(docsrs, doc(cfg(any(feature = "tokio1", feature = "async-std1"))))]
|
||||||
docsrs,
|
|
||||||
doc(cfg(any(feature = "tokio02", feature = "tokio1", feature = "async-std1")))
|
|
||||||
)]
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait Executor: Debug + Send + Sync + private::Sealed {
|
pub trait Executor: Debug + Send + Sync + private::Sealed {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
@@ -59,72 +56,6 @@ pub trait Executor: Debug + Send + Sync + private::Sealed {
|
|||||||
async fn fs_write(path: &Path, contents: &[u8]) -> IoResult<()>;
|
async fn fs_write(path: &Path, contents: &[u8]) -> IoResult<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Async [`Executor`] using `tokio` `0.2.x`
|
|
||||||
///
|
|
||||||
/// Used by [`AsyncSmtpTransport`], [`AsyncSendmailTransport`] and [`AsyncFileTransport`]
|
|
||||||
/// in order to be able to work with different async runtimes.
|
|
||||||
///
|
|
||||||
/// [`AsyncSmtpTransport`]: crate::AsyncSmtpTransport
|
|
||||||
/// [`AsyncSendmailTransport`]: crate::AsyncSendmailTransport
|
|
||||||
/// [`AsyncFileTransport`]: crate::AsyncFileTransport
|
|
||||||
#[allow(missing_copy_implementations)]
|
|
||||||
#[non_exhaustive]
|
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio02")))]
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Tokio02Executor;
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
impl Executor for Tokio02Executor {
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[cfg(feature = "smtp-transport")]
|
|
||||||
async fn connect(
|
|
||||||
hostname: &str,
|
|
||||||
port: u16,
|
|
||||||
hello_name: &ClientId,
|
|
||||||
tls: &Tls,
|
|
||||||
) -> Result<AsyncSmtpConnection, Error> {
|
|
||||||
#[allow(clippy::match_single_binding)]
|
|
||||||
let tls_parameters = match tls {
|
|
||||||
#[cfg(any(feature = "tokio02-native-tls", feature = "tokio02-rustls-tls"))]
|
|
||||||
Tls::Wrapper(ref tls_parameters) => Some(tls_parameters.clone()),
|
|
||||||
_ => None,
|
|
||||||
};
|
|
||||||
#[allow(unused_mut)]
|
|
||||||
let mut conn =
|
|
||||||
AsyncSmtpConnection::connect_tokio02(hostname, port, hello_name, tls_parameters)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
#[cfg(any(feature = "tokio02-native-tls", feature = "tokio02-rustls-tls"))]
|
|
||||||
match tls {
|
|
||||||
Tls::Opportunistic(ref tls_parameters) => {
|
|
||||||
if conn.can_starttls() {
|
|
||||||
conn.starttls(tls_parameters.clone(), hello_name).await?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Tls::Required(ref tls_parameters) => {
|
|
||||||
conn.starttls(tls_parameters.clone(), hello_name).await?;
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(conn)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[cfg(feature = "file-transport-envelope")]
|
|
||||||
async fn fs_read(path: &Path) -> IoResult<Vec<u8>> {
|
|
||||||
tokio02_crate::fs::read(path).await
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[cfg(feature = "file-transport")]
|
|
||||||
async fn fs_write(path: &Path, contents: &[u8]) -> IoResult<()> {
|
|
||||||
tokio02_crate::fs::write(path, contents).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Async [`Executor`] using `tokio` `1.x`
|
/// Async [`Executor`] using `tokio` `1.x`
|
||||||
///
|
///
|
||||||
/// Used by [`AsyncSmtpTransport`], [`AsyncSendmailTransport`] and [`AsyncFileTransport`]
|
/// Used by [`AsyncSmtpTransport`], [`AsyncSendmailTransport`] and [`AsyncFileTransport`]
|
||||||
@@ -261,9 +192,6 @@ mod private {
|
|||||||
|
|
||||||
pub trait Sealed {}
|
pub trait Sealed {}
|
||||||
|
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
impl Sealed for Tokio02Executor {}
|
|
||||||
|
|
||||||
#[cfg(feature = "tokio1")]
|
#[cfg(feature = "tokio1")]
|
||||||
impl Sealed for Tokio1Executor {}
|
impl Sealed for Tokio1Executor {}
|
||||||
|
|
||||||
|
|||||||
20
src/lib.rs
20
src/lib.rs
@@ -37,7 +37,6 @@
|
|||||||
//! Uses schannel on Windows, Security-Framework on macOS, and OpenSSL on Linux.
|
//! Uses schannel on Windows, Security-Framework on macOS, and OpenSSL on Linux.
|
||||||
//!
|
//!
|
||||||
//! * **native-tls** 📫: TLS support for the synchronous version of the API
|
//! * **native-tls** 📫: TLS support for the synchronous version of the API
|
||||||
//! * **tokio02-native-tls**: TLS support for the `tokio02` async version of the API
|
|
||||||
//! * **tokio1-native-tls**: TLS support for the `tokio1` async version of the API
|
//! * **tokio1-native-tls**: TLS support for the `tokio1` async version of the API
|
||||||
//!
|
//!
|
||||||
//! NOTE: native-tls isn't supported with `async-std`
|
//! NOTE: native-tls isn't supported with `async-std`
|
||||||
@@ -49,7 +48,6 @@
|
|||||||
//! Rustls uses [ring] as the cryptography implementation. As a result, [not all Rust's targets are supported][ring-support].
|
//! Rustls uses [ring] as the cryptography implementation. As a result, [not all Rust's targets are supported][ring-support].
|
||||||
//!
|
//!
|
||||||
//! * **rustls-tls**: TLS support for the synchronous version of the API
|
//! * **rustls-tls**: TLS support for the synchronous version of the API
|
||||||
//! * **tokio02-rustls-tls**: TLS support for the `tokio02` async version of the API
|
|
||||||
//! * **tokio1-rustls-tls**: TLS support for the `tokio1` async version of the API
|
//! * **tokio1-rustls-tls**: TLS support for the `tokio1` async version of the API
|
||||||
//! * **async-std1-rustls-tls**: TLS support for the `async-std1` async version of the API
|
//! * **async-std1-rustls-tls**: TLS support for the `async-std1` async version of the API
|
||||||
//!
|
//!
|
||||||
@@ -71,11 +69,10 @@
|
|||||||
//! _Use [tokio] or [async-std] as an async execution runtime for sending emails_
|
//! _Use [tokio] or [async-std] as an async execution runtime for sending emails_
|
||||||
//!
|
//!
|
||||||
//! The correct runtime version must be chosen in order for lettre to work correctly.
|
//! The correct runtime version must be chosen in order for lettre to work correctly.
|
||||||
//! For example, when sending emails from a Tokio 1.3.0 context, the Tokio 1.x executor
|
//! For example, when sending emails from a Tokio 1.x context, the Tokio 1.x executor
|
||||||
//! ([`Tokio1Executor`]) must be used. Using a different version (for example Tokio 0.2.x),
|
//! ([`Tokio1Executor`]) must be used. Using a different version (for example Tokio 0.2.x),
|
||||||
//! or async-std, would result in a runtime panic.
|
//! or async-std, would result in a runtime panic.
|
||||||
//!
|
//!
|
||||||
//! * **tokio02**: Allow to asynchronously send emails using [Tokio 0.2.x]
|
|
||||||
//! * **tokio1**: Allow to asynchronously send emails using [Tokio 1.x]
|
//! * **tokio1**: Allow to asynchronously send emails using [Tokio 1.x]
|
||||||
//! * **async-std1**: Allow to asynchronously send emails using [async-std 1.x]
|
//! * **async-std1**: Allow to asynchronously send emails using [async-std 1.x]
|
||||||
//!
|
//!
|
||||||
@@ -95,7 +92,6 @@
|
|||||||
//! [async-std]: https://docs.rs/async-std/1
|
//! [async-std]: https://docs.rs/async-std/1
|
||||||
//! [ring]: https://github.com/briansmith/ring#ring
|
//! [ring]: https://github.com/briansmith/ring#ring
|
||||||
//! [ring-support]: https://github.com/briansmith/ring#online-automated-testing
|
//! [ring-support]: https://github.com/briansmith/ring#online-automated-testing
|
||||||
//! [Tokio 0.2.x]: https://docs.rs/tokio/0.2
|
|
||||||
//! [Tokio 1.x]: https://docs.rs/tokio/1
|
//! [Tokio 1.x]: https://docs.rs/tokio/1
|
||||||
//! [async-std 1.x]: https://docs.rs/async-std/1
|
//! [async-std 1.x]: https://docs.rs/async-std/1
|
||||||
|
|
||||||
@@ -115,7 +111,7 @@
|
|||||||
|
|
||||||
pub mod address;
|
pub mod address;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
#[cfg(any(feature = "tokio02", feature = "tokio1", feature = "async-std1"))]
|
#[cfg(any(feature = "tokio1", feature = "async-std1"))]
|
||||||
mod executor;
|
mod executor;
|
||||||
#[cfg(feature = "builder")]
|
#[cfg(feature = "builder")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "builder")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "builder")))]
|
||||||
@@ -124,13 +120,11 @@ pub mod transport;
|
|||||||
|
|
||||||
#[cfg(feature = "async-std1")]
|
#[cfg(feature = "async-std1")]
|
||||||
pub use self::executor::AsyncStd1Executor;
|
pub use self::executor::AsyncStd1Executor;
|
||||||
#[cfg(all(any(feature = "tokio02", feature = "tokio1", feature = "async-std1")))]
|
#[cfg(all(any(feature = "tokio1", feature = "async-std1")))]
|
||||||
pub use self::executor::Executor;
|
pub use self::executor::Executor;
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
pub use self::executor::Tokio02Executor;
|
|
||||||
#[cfg(feature = "tokio1")]
|
#[cfg(feature = "tokio1")]
|
||||||
pub use self::executor::Tokio1Executor;
|
pub use self::executor::Tokio1Executor;
|
||||||
#[cfg(all(any(feature = "tokio02", feature = "tokio1", feature = "async-std1")))]
|
#[cfg(all(any(feature = "tokio1", feature = "async-std1")))]
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use self::transport::AsyncTransport;
|
pub use self::transport::AsyncTransport;
|
||||||
pub use crate::address::Address;
|
pub use crate::address::Address;
|
||||||
@@ -139,7 +133,7 @@ pub use crate::address::Address;
|
|||||||
pub use crate::message::Message;
|
pub use crate::message::Message;
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
feature = "file-transport",
|
feature = "file-transport",
|
||||||
any(feature = "tokio02", feature = "tokio1", feature = "async-std1")
|
any(feature = "tokio1", feature = "async-std1")
|
||||||
))]
|
))]
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use crate::transport::file::AsyncFileTransport;
|
pub use crate::transport::file::AsyncFileTransport;
|
||||||
@@ -148,7 +142,7 @@ pub use crate::transport::file::AsyncFileTransport;
|
|||||||
pub use crate::transport::file::FileTransport;
|
pub use crate::transport::file::FileTransport;
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
feature = "sendmail-transport",
|
feature = "sendmail-transport",
|
||||||
any(feature = "tokio02", feature = "tokio1", feature = "async-std1")
|
any(feature = "tokio1", feature = "async-std1")
|
||||||
))]
|
))]
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use crate::transport::sendmail::AsyncSendmailTransport;
|
pub use crate::transport::sendmail::AsyncSendmailTransport;
|
||||||
@@ -157,7 +151,7 @@ pub use crate::transport::sendmail::AsyncSendmailTransport;
|
|||||||
pub use crate::transport::sendmail::SendmailTransport;
|
pub use crate::transport::sendmail::SendmailTransport;
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
feature = "smtp-transport",
|
feature = "smtp-transport",
|
||||||
any(feature = "tokio02", feature = "tokio1", feature = "async-std1")
|
any(feature = "tokio1", feature = "async-std1")
|
||||||
))]
|
))]
|
||||||
pub use crate::transport::smtp::AsyncSmtpTransport;
|
pub use crate::transport::smtp::AsyncSmtpTransport;
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
|
|||||||
@@ -134,11 +134,11 @@
|
|||||||
|
|
||||||
pub use self::error::Error;
|
pub use self::error::Error;
|
||||||
use crate::{address::Envelope, Transport};
|
use crate::{address::Envelope, Transport};
|
||||||
#[cfg(any(feature = "async-std1", feature = "tokio02", feature = "tokio1"))]
|
#[cfg(any(feature = "async-std1", feature = "tokio1"))]
|
||||||
use crate::{AsyncTransport, Executor};
|
use crate::{AsyncTransport, Executor};
|
||||||
#[cfg(any(feature = "async-std1", feature = "tokio02", feature = "tokio1"))]
|
#[cfg(any(feature = "async-std1", feature = "tokio1"))]
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
#[cfg(any(feature = "async-std1", feature = "tokio02", feature = "tokio1"))]
|
#[cfg(any(feature = "async-std1", feature = "tokio1"))]
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::{
|
use std::{
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
@@ -163,11 +163,8 @@ pub struct FileTransport {
|
|||||||
/// Asynchronously writes the content and the envelope information to a file
|
/// Asynchronously writes the content and the envelope information to a file
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(docsrs, doc(cfg(any(feature = "tokio1", feature = "async-std1"))))]
|
||||||
docsrs,
|
#[cfg(any(feature = "async-std1", feature = "tokio1"))]
|
||||||
doc(cfg(any(feature = "tokio02", feature = "tokio1", feature = "async-std1")))
|
|
||||||
)]
|
|
||||||
#[cfg(any(feature = "async-std1", feature = "tokio02", feature = "tokio1"))]
|
|
||||||
pub struct AsyncFileTransport<E: Executor> {
|
pub struct AsyncFileTransport<E: Executor> {
|
||||||
inner: FileTransport,
|
inner: FileTransport,
|
||||||
marker_: PhantomData<E>,
|
marker_: PhantomData<E>,
|
||||||
@@ -220,7 +217,7 @@ impl FileTransport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "async-std1", feature = "tokio02", feature = "tokio1"))]
|
#[cfg(any(feature = "async-std1", feature = "tokio1"))]
|
||||||
impl<E> AsyncFileTransport<E>
|
impl<E> AsyncFileTransport<E>
|
||||||
where
|
where
|
||||||
E: Executor,
|
E: Executor,
|
||||||
@@ -290,7 +287,7 @@ impl Transport for FileTransport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "async-std1", feature = "tokio02", feature = "tokio1"))]
|
#[cfg(any(feature = "async-std1", feature = "tokio1"))]
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<E> AsyncTransport for AsyncFileTransport<E>
|
impl<E> AsyncTransport for AsyncFileTransport<E>
|
||||||
where
|
where
|
||||||
|
|||||||
@@ -99,7 +99,7 @@
|
|||||||
//! [`AsyncFileTransport`]: crate::AsyncFileTransport
|
//! [`AsyncFileTransport`]: crate::AsyncFileTransport
|
||||||
//! [`StubTransport`]: crate::transport::stub::StubTransport
|
//! [`StubTransport`]: crate::transport::stub::StubTransport
|
||||||
|
|
||||||
#[cfg(any(feature = "async-std1", feature = "tokio02", feature = "tokio1"))]
|
#[cfg(any(feature = "async-std1", feature = "tokio1"))]
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
use crate::Envelope;
|
use crate::Envelope;
|
||||||
@@ -136,11 +136,8 @@ pub trait Transport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Async Transport method for emails
|
/// Async Transport method for emails
|
||||||
#[cfg(any(feature = "tokio02", feature = "tokio1", feature = "async-std1"))]
|
#[cfg(any(feature = "tokio1", feature = "async-std1"))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(docsrs, doc(cfg(any(feature = "tokio1", feature = "async-std1"))))]
|
||||||
docsrs,
|
|
||||||
doc(cfg(any(feature = "tokio02", feature = "tokio1", feature = "async-std1")))
|
|
||||||
)]
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait AsyncTransport {
|
pub trait AsyncTransport {
|
||||||
/// Response produced by the Transport
|
/// Response produced by the Transport
|
||||||
|
|||||||
@@ -26,29 +26,6 @@
|
|||||||
//! # fn main() {}
|
//! # fn main() {}
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! ## Async tokio 0.2 example
|
|
||||||
//!
|
|
||||||
//! ```rust,no_run
|
|
||||||
//! # use std::error::Error;
|
|
||||||
//! #
|
|
||||||
//! # #[cfg(all(feature = "tokio02", feature = "sendmail-transport", feature = "builder"))]
|
|
||||||
//! # async fn run() -> Result<(), Box<dyn Error>> {
|
|
||||||
//! use lettre::{Message, AsyncTransport, Tokio02Executor, AsyncSendmailTransport, SendmailTransport};
|
|
||||||
//!
|
|
||||||
//! let email = Message::builder()
|
|
||||||
//! .from("NoBody <nobody@domain.tld>".parse()?)
|
|
||||||
//! .reply_to("Yuin <yuin@domain.tld>".parse()?)
|
|
||||||
//! .to("Hei <hei@domain.tld>".parse()?)
|
|
||||||
//! .subject("Happy new year")
|
|
||||||
//! .body(String::from("Be happy!"))?;
|
|
||||||
//!
|
|
||||||
//! let sender = AsyncSendmailTransport::<Tokio02Executor>::new();
|
|
||||||
//! let result = sender.send(email).await;
|
|
||||||
//! assert!(result.is_ok());
|
|
||||||
//! # Ok(())
|
|
||||||
//! # }
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! ## Async tokio 1.x example
|
//! ## Async tokio 1.x example
|
||||||
//!
|
//!
|
||||||
//! ```rust,no_run
|
//! ```rust,no_run
|
||||||
@@ -98,16 +75,14 @@
|
|||||||
pub use self::error::Error;
|
pub use self::error::Error;
|
||||||
#[cfg(feature = "async-std1")]
|
#[cfg(feature = "async-std1")]
|
||||||
use crate::AsyncStd1Executor;
|
use crate::AsyncStd1Executor;
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
use crate::Tokio02Executor;
|
|
||||||
#[cfg(feature = "tokio1")]
|
#[cfg(feature = "tokio1")]
|
||||||
use crate::Tokio1Executor;
|
use crate::Tokio1Executor;
|
||||||
use crate::{address::Envelope, Transport};
|
use crate::{address::Envelope, Transport};
|
||||||
#[cfg(any(feature = "async-std1", feature = "tokio02", feature = "tokio1"))]
|
#[cfg(any(feature = "async-std1", feature = "tokio1"))]
|
||||||
use crate::{AsyncTransport, Executor};
|
use crate::{AsyncTransport, Executor};
|
||||||
#[cfg(any(feature = "async-std1", feature = "tokio02", feature = "tokio1"))]
|
#[cfg(any(feature = "async-std1", feature = "tokio1"))]
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
#[cfg(any(feature = "async-std1", feature = "tokio02", feature = "tokio1"))]
|
#[cfg(any(feature = "async-std1", feature = "tokio1"))]
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::{
|
use std::{
|
||||||
ffi::OsString,
|
ffi::OsString,
|
||||||
@@ -130,11 +105,8 @@ pub struct SendmailTransport {
|
|||||||
/// Asynchronously sends emails using the `sendmail` command
|
/// Asynchronously sends emails using the `sendmail` command
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||||
#[cfg(any(feature = "async-std1", feature = "tokio02", feature = "tokio1"))]
|
#[cfg(any(feature = "async-std1", feature = "tokio1"))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(docsrs, doc(cfg(any(feature = "tokio1", feature = "async-std1"))))]
|
||||||
docsrs,
|
|
||||||
doc(cfg(any(feature = "tokio02", feature = "tokio1", feature = "async-std1")))
|
|
||||||
)]
|
|
||||||
pub struct AsyncSendmailTransport<E: Executor> {
|
pub struct AsyncSendmailTransport<E: Executor> {
|
||||||
inner: SendmailTransport,
|
inner: SendmailTransport,
|
||||||
marker_: PhantomData<E>,
|
marker_: PhantomData<E>,
|
||||||
@@ -170,7 +142,7 @@ impl SendmailTransport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "async-std1", feature = "tokio02", feature = "tokio1"))]
|
#[cfg(any(feature = "async-std1", feature = "tokio1"))]
|
||||||
impl<E> AsyncSendmailTransport<E>
|
impl<E> AsyncSendmailTransport<E>
|
||||||
where
|
where
|
||||||
E: Executor,
|
E: Executor,
|
||||||
@@ -191,24 +163,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
fn tokio02_command(&self, envelope: &Envelope) -> tokio02_crate::process::Command {
|
|
||||||
use tokio02_crate::process::Command;
|
|
||||||
|
|
||||||
let mut c = Command::new(&self.inner.command);
|
|
||||||
c.kill_on_drop(true);
|
|
||||||
c.arg("-i");
|
|
||||||
if let Some(from) = envelope.from() {
|
|
||||||
c.arg("-f").arg(from);
|
|
||||||
}
|
|
||||||
c.arg("--")
|
|
||||||
.args(envelope.to())
|
|
||||||
.stdin(Stdio::piped())
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.stderr(Stdio::piped());
|
|
||||||
c
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "tokio1")]
|
#[cfg(feature = "tokio1")]
|
||||||
fn tokio1_command(&self, envelope: &Envelope) -> tokio1_crate::process::Command {
|
fn tokio1_command(&self, envelope: &Envelope) -> tokio1_crate::process::Command {
|
||||||
use tokio1_crate::process::Command;
|
use tokio1_crate::process::Command;
|
||||||
@@ -253,7 +207,7 @@ impl Default for SendmailTransport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "async-std1", feature = "tokio02", feature = "tokio1"))]
|
#[cfg(any(feature = "async-std1", feature = "tokio1"))]
|
||||||
impl<E> Default for AsyncSendmailTransport<E>
|
impl<E> Default for AsyncSendmailTransport<E>
|
||||||
where
|
where
|
||||||
E: Executor,
|
E: Executor,
|
||||||
@@ -320,38 +274,6 @@ impl AsyncTransport for AsyncSendmailTransport<AsyncStd1Executor> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
#[async_trait]
|
|
||||||
impl AsyncTransport for AsyncSendmailTransport<Tokio02Executor> {
|
|
||||||
type Ok = ();
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
async fn send_raw(&self, envelope: &Envelope, email: &[u8]) -> Result<Self::Ok, Self::Error> {
|
|
||||||
use tokio02_crate::io::AsyncWriteExt;
|
|
||||||
|
|
||||||
let mut command = self.tokio02_command(envelope);
|
|
||||||
|
|
||||||
// Spawn the sendmail command
|
|
||||||
let mut process = command.spawn().map_err(error::client)?;
|
|
||||||
|
|
||||||
process
|
|
||||||
.stdin
|
|
||||||
.as_mut()
|
|
||||||
.unwrap()
|
|
||||||
.write_all(&email)
|
|
||||||
.await
|
|
||||||
.map_err(error::client)?;
|
|
||||||
let output = process.wait_with_output().await.map_err(error::client)?;
|
|
||||||
|
|
||||||
if output.status.success() {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
let stderr = String::from_utf8(output.stderr).map_err(error::response)?;
|
|
||||||
Err(error::client(stderr))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "tokio1")]
|
#[cfg(feature = "tokio1")]
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl AsyncTransport for AsyncSendmailTransport<Tokio1Executor> {
|
impl AsyncTransport for AsyncSendmailTransport<Tokio1Executor> {
|
||||||
|
|||||||
@@ -10,42 +10,19 @@ use super::{
|
|||||||
};
|
};
|
||||||
#[cfg(feature = "async-std1")]
|
#[cfg(feature = "async-std1")]
|
||||||
use crate::AsyncStd1Executor;
|
use crate::AsyncStd1Executor;
|
||||||
#[cfg(any(feature = "tokio02", feature = "tokio1", feature = "async-std1"))]
|
#[cfg(any(feature = "tokio1", feature = "async-std1"))]
|
||||||
use crate::AsyncTransport;
|
use crate::AsyncTransport;
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
use crate::Tokio02Executor;
|
|
||||||
#[cfg(feature = "tokio1")]
|
#[cfg(feature = "tokio1")]
|
||||||
use crate::Tokio1Executor;
|
use crate::Tokio1Executor;
|
||||||
use crate::{Envelope, Executor};
|
use crate::{Envelope, Executor};
|
||||||
|
|
||||||
/// Asynchronously sends emails using the SMTP protocol
|
/// Asynchronously sends emails using the SMTP protocol
|
||||||
#[cfg_attr(
|
#[cfg_attr(docsrs, doc(cfg(any(feature = "tokio1", feature = "async-std1"))))]
|
||||||
docsrs,
|
|
||||||
doc(cfg(any(feature = "tokio02", feature = "tokio1", feature = "async-std1")))
|
|
||||||
)]
|
|
||||||
pub struct AsyncSmtpTransport<E> {
|
pub struct AsyncSmtpTransport<E> {
|
||||||
// TODO: pool
|
// TODO: pool
|
||||||
inner: AsyncSmtpClient<E>,
|
inner: AsyncSmtpClient<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
#[async_trait]
|
|
||||||
impl AsyncTransport for AsyncSmtpTransport<Tokio02Executor> {
|
|
||||||
type Ok = Response;
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
/// Sends an email
|
|
||||||
async fn send_raw(&self, envelope: &Envelope, email: &[u8]) -> Result<Self::Ok, Self::Error> {
|
|
||||||
let mut conn = self.inner.connection().await?;
|
|
||||||
|
|
||||||
let result = conn.send(envelope, email).await?;
|
|
||||||
|
|
||||||
conn.quit().await?;
|
|
||||||
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "tokio1")]
|
#[cfg(feature = "tokio1")]
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl AsyncTransport for AsyncSmtpTransport<Tokio1Executor> {
|
impl AsyncTransport for AsyncSmtpTransport<Tokio1Executor> {
|
||||||
@@ -93,8 +70,6 @@ where
|
|||||||
/// Creates an encrypted transport over submissions port, using the provided domain
|
/// Creates an encrypted transport over submissions port, using the provided domain
|
||||||
/// to validate TLS certificates.
|
/// to validate TLS certificates.
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "tokio02-native-tls",
|
|
||||||
feature = "tokio02-rustls-tls",
|
|
||||||
feature = "tokio1-native-tls",
|
feature = "tokio1-native-tls",
|
||||||
feature = "tokio1-rustls-tls",
|
feature = "tokio1-rustls-tls",
|
||||||
feature = "async-std1-native-tls",
|
feature = "async-std1-native-tls",
|
||||||
@@ -103,8 +78,6 @@ where
|
|||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
docsrs,
|
docsrs,
|
||||||
doc(cfg(any(
|
doc(cfg(any(
|
||||||
feature = "tokio02-native-tls",
|
|
||||||
feature = "tokio02-rustls-tls",
|
|
||||||
feature = "tokio1-native-tls",
|
feature = "tokio1-native-tls",
|
||||||
feature = "tokio1-rustls-tls",
|
feature = "tokio1-rustls-tls",
|
||||||
feature = "async-std1-rustls-tls"
|
feature = "async-std1-rustls-tls"
|
||||||
@@ -132,8 +105,6 @@ where
|
|||||||
/// An error is returned if the connection can't be upgraded. No credentials
|
/// An error is returned if the connection can't be upgraded. No credentials
|
||||||
/// or emails will be sent to the server, protecting from downgrade attacks.
|
/// or emails will be sent to the server, protecting from downgrade attacks.
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "tokio02-native-tls",
|
|
||||||
feature = "tokio02-rustls-tls",
|
|
||||||
feature = "tokio1-native-tls",
|
feature = "tokio1-native-tls",
|
||||||
feature = "tokio1-rustls-tls",
|
feature = "tokio1-rustls-tls",
|
||||||
feature = "async-std1-native-tls",
|
feature = "async-std1-native-tls",
|
||||||
@@ -142,8 +113,6 @@ where
|
|||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
docsrs,
|
docsrs,
|
||||||
doc(cfg(any(
|
doc(cfg(any(
|
||||||
feature = "tokio02-native-tls",
|
|
||||||
feature = "tokio02-rustls-tls",
|
|
||||||
feature = "tokio1-native-tls",
|
feature = "tokio1-native-tls",
|
||||||
feature = "tokio1-rustls-tls",
|
feature = "tokio1-rustls-tls",
|
||||||
feature = "async-std1-rustls-tls"
|
feature = "async-std1-rustls-tls"
|
||||||
@@ -208,10 +177,7 @@ where
|
|||||||
/// Contains client configuration.
|
/// Contains client configuration.
|
||||||
/// Instances of this struct can be created using functions of [`AsyncSmtpTransport`].
|
/// Instances of this struct can be created using functions of [`AsyncSmtpTransport`].
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[cfg_attr(
|
#[cfg_attr(docsrs, doc(cfg(any(feature = "tokio1", feature = "async-std1"))))]
|
||||||
docsrs,
|
|
||||||
doc(cfg(any(feature = "tokio02", feature = "tokio1", feature = "async-std1")))
|
|
||||||
)]
|
|
||||||
pub struct AsyncSmtpTransportBuilder {
|
pub struct AsyncSmtpTransportBuilder {
|
||||||
info: SmtpInfo,
|
info: SmtpInfo,
|
||||||
}
|
}
|
||||||
@@ -244,8 +210,6 @@ impl AsyncSmtpTransportBuilder {
|
|||||||
|
|
||||||
/// Set the TLS settings to use
|
/// Set the TLS settings to use
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "tokio02-native-tls",
|
|
||||||
feature = "tokio02-rustls-tls",
|
|
||||||
feature = "tokio1-native-tls",
|
feature = "tokio1-native-tls",
|
||||||
feature = "tokio1-rustls-tls",
|
feature = "tokio1-rustls-tls",
|
||||||
feature = "async-std1-native-tls",
|
feature = "async-std1-native-tls",
|
||||||
@@ -254,8 +218,6 @@ impl AsyncSmtpTransportBuilder {
|
|||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
docsrs,
|
docsrs,
|
||||||
doc(cfg(any(
|
doc(cfg(any(
|
||||||
feature = "tokio02-native-tls",
|
|
||||||
feature = "tokio02-rustls-tls",
|
|
||||||
feature = "tokio1-native-tls",
|
feature = "tokio1-native-tls",
|
||||||
feature = "tokio1-rustls-tls",
|
feature = "tokio1-rustls-tls",
|
||||||
feature = "async-std1-rustls-tls"
|
feature = "async-std1-rustls-tls"
|
||||||
|
|||||||
@@ -44,20 +44,6 @@ impl AsyncSmtpConnection {
|
|||||||
&self.server_info
|
&self.server_info
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Connects to the configured server
|
|
||||||
///
|
|
||||||
/// Sends EHLO and parses server information
|
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
pub async fn connect_tokio02(
|
|
||||||
hostname: &str,
|
|
||||||
port: u16,
|
|
||||||
hello_name: &ClientId,
|
|
||||||
tls_parameters: Option<TlsParameters>,
|
|
||||||
) -> Result<AsyncSmtpConnection, Error> {
|
|
||||||
let stream = AsyncNetworkStream::connect_tokio02(hostname, port, tls_parameters).await?;
|
|
||||||
Self::connect_impl(stream, hello_name).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Connects to the configured server
|
/// Connects to the configured server
|
||||||
///
|
///
|
||||||
/// Sends EHLO and parses server information
|
/// Sends EHLO and parses server information
|
||||||
|
|||||||
@@ -9,35 +9,25 @@ use futures_io::{
|
|||||||
AsyncRead as FuturesAsyncRead, AsyncWrite as FuturesAsyncWrite, Error as IoError, ErrorKind,
|
AsyncRead as FuturesAsyncRead, AsyncWrite as FuturesAsyncWrite, Error as IoError, ErrorKind,
|
||||||
Result as IoResult,
|
Result as IoResult,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
use tokio02_crate::io::{AsyncRead as _, AsyncWrite as _};
|
|
||||||
#[cfg(feature = "tokio1")]
|
#[cfg(feature = "tokio1")]
|
||||||
use tokio1_crate::io::{AsyncRead as _, AsyncWrite as _, ReadBuf as Tokio1ReadBuf};
|
use tokio1_crate::io::{AsyncRead as _, AsyncWrite as _, ReadBuf as Tokio1ReadBuf};
|
||||||
|
|
||||||
#[cfg(feature = "async-std1")]
|
#[cfg(feature = "async-std1")]
|
||||||
use async_std::net::TcpStream as AsyncStd1TcpStream;
|
use async_std::net::TcpStream as AsyncStd1TcpStream;
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
use tokio02_crate::net::TcpStream as Tokio02TcpStream;
|
|
||||||
#[cfg(feature = "tokio1")]
|
#[cfg(feature = "tokio1")]
|
||||||
use tokio1_crate::net::TcpStream as Tokio1TcpStream;
|
use tokio1_crate::net::TcpStream as Tokio1TcpStream;
|
||||||
|
|
||||||
#[cfg(feature = "async-std1-native-tls")]
|
#[cfg(feature = "async-std1-native-tls")]
|
||||||
use async_native_tls::TlsStream as AsyncStd1TlsStream;
|
use async_native_tls::TlsStream as AsyncStd1TlsStream;
|
||||||
#[cfg(feature = "tokio02-native-tls")]
|
|
||||||
use tokio02_native_tls_crate::TlsStream as Tokio02TlsStream;
|
|
||||||
#[cfg(feature = "tokio1-native-tls")]
|
#[cfg(feature = "tokio1-native-tls")]
|
||||||
use tokio1_native_tls_crate::TlsStream as Tokio1TlsStream;
|
use tokio1_native_tls_crate::TlsStream as Tokio1TlsStream;
|
||||||
|
|
||||||
#[cfg(feature = "async-std1-rustls-tls")]
|
#[cfg(feature = "async-std1-rustls-tls")]
|
||||||
use async_rustls::client::TlsStream as AsyncStd1RustlsTlsStream;
|
use async_rustls::client::TlsStream as AsyncStd1RustlsTlsStream;
|
||||||
#[cfg(feature = "tokio02-rustls-tls")]
|
|
||||||
use tokio02_rustls::client::TlsStream as Tokio02RustlsTlsStream;
|
|
||||||
#[cfg(feature = "tokio1-rustls-tls")]
|
#[cfg(feature = "tokio1-rustls-tls")]
|
||||||
use tokio1_rustls::client::TlsStream as Tokio1RustlsTlsStream;
|
use tokio1_rustls::client::TlsStream as Tokio1RustlsTlsStream;
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "tokio02-native-tls",
|
|
||||||
feature = "tokio02-rustls-tls",
|
|
||||||
feature = "tokio1-native-tls",
|
feature = "tokio1-native-tls",
|
||||||
feature = "tokio1-rustls-tls",
|
feature = "tokio1-rustls-tls",
|
||||||
feature = "async-std1-native-tls",
|
feature = "async-std1-native-tls",
|
||||||
@@ -58,15 +48,6 @@ pub struct AsyncNetworkStream {
|
|||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
enum InnerAsyncNetworkStream {
|
enum InnerAsyncNetworkStream {
|
||||||
/// Plain Tokio 0.2 TCP stream
|
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
Tokio02Tcp(Tokio02TcpStream),
|
|
||||||
/// Encrypted Tokio 0.2 TCP stream
|
|
||||||
#[cfg(feature = "tokio02-native-tls")]
|
|
||||||
Tokio02NativeTls(Tokio02TlsStream<Tokio02TcpStream>),
|
|
||||||
/// Encrypted Tokio 0.2 TCP stream
|
|
||||||
#[cfg(feature = "tokio02-rustls-tls")]
|
|
||||||
Tokio02RustlsTls(Tokio02RustlsTlsStream<Tokio02TcpStream>),
|
|
||||||
/// Plain Tokio 1.x TCP stream
|
/// Plain Tokio 1.x TCP stream
|
||||||
#[cfg(feature = "tokio1")]
|
#[cfg(feature = "tokio1")]
|
||||||
Tokio1Tcp(Tokio1TcpStream),
|
Tokio1Tcp(Tokio1TcpStream),
|
||||||
@@ -101,14 +82,6 @@ impl AsyncNetworkStream {
|
|||||||
/// Returns peer's address
|
/// Returns peer's address
|
||||||
pub fn peer_addr(&self) -> IoResult<SocketAddr> {
|
pub fn peer_addr(&self) -> IoResult<SocketAddr> {
|
||||||
match self.inner {
|
match self.inner {
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
InnerAsyncNetworkStream::Tokio02Tcp(ref s) => s.peer_addr(),
|
|
||||||
#[cfg(feature = "tokio02-native-tls")]
|
|
||||||
InnerAsyncNetworkStream::Tokio02NativeTls(ref s) => {
|
|
||||||
s.get_ref().get_ref().get_ref().peer_addr()
|
|
||||||
}
|
|
||||||
#[cfg(feature = "tokio02-rustls-tls")]
|
|
||||||
InnerAsyncNetworkStream::Tokio02RustlsTls(ref s) => s.get_ref().0.peer_addr(),
|
|
||||||
#[cfg(feature = "tokio1")]
|
#[cfg(feature = "tokio1")]
|
||||||
InnerAsyncNetworkStream::Tokio1Tcp(ref s) => s.peer_addr(),
|
InnerAsyncNetworkStream::Tokio1Tcp(ref s) => s.peer_addr(),
|
||||||
#[cfg(feature = "tokio1-native-tls")]
|
#[cfg(feature = "tokio1-native-tls")]
|
||||||
@@ -133,23 +106,6 @@ impl AsyncNetworkStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
pub async fn connect_tokio02(
|
|
||||||
hostname: &str,
|
|
||||||
port: u16,
|
|
||||||
tls_parameters: Option<TlsParameters>,
|
|
||||||
) -> Result<AsyncNetworkStream, Error> {
|
|
||||||
let tcp_stream = Tokio02TcpStream::connect((hostname, port))
|
|
||||||
.await
|
|
||||||
.map_err(error::connection)?;
|
|
||||||
|
|
||||||
let mut stream = AsyncNetworkStream::new(InnerAsyncNetworkStream::Tokio02Tcp(tcp_stream));
|
|
||||||
if let Some(tls_parameters) = tls_parameters {
|
|
||||||
stream.upgrade_tls(tls_parameters).await?;
|
|
||||||
}
|
|
||||||
Ok(stream)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "tokio1")]
|
#[cfg(feature = "tokio1")]
|
||||||
pub async fn connect_tokio1(
|
pub async fn connect_tokio1(
|
||||||
hostname: &str,
|
hostname: &str,
|
||||||
@@ -186,29 +142,6 @@ impl AsyncNetworkStream {
|
|||||||
|
|
||||||
pub async fn upgrade_tls(&mut self, tls_parameters: TlsParameters) -> Result<(), Error> {
|
pub async fn upgrade_tls(&mut self, tls_parameters: TlsParameters) -> Result<(), Error> {
|
||||||
match &self.inner {
|
match &self.inner {
|
||||||
#[cfg(all(
|
|
||||||
feature = "tokio02",
|
|
||||||
not(any(feature = "tokio02-native-tls", feature = "tokio02-rustls-tls"))
|
|
||||||
))]
|
|
||||||
InnerAsyncNetworkStream::Tokio02Tcp(_) => {
|
|
||||||
let _ = tls_parameters;
|
|
||||||
panic!("Trying to upgrade an AsyncNetworkStream without having enabled either the tokio02-native-tls or the tokio02-rustls-tls feature");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(feature = "tokio02-native-tls", feature = "tokio02-rustls-tls"))]
|
|
||||||
InnerAsyncNetworkStream::Tokio02Tcp(_) => {
|
|
||||||
// get owned TcpStream
|
|
||||||
let tcp_stream = mem::replace(&mut self.inner, InnerAsyncNetworkStream::None);
|
|
||||||
let tcp_stream = match tcp_stream {
|
|
||||||
InnerAsyncNetworkStream::Tokio02Tcp(tcp_stream) => tcp_stream,
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.inner = Self::upgrade_tokio02_tls(tcp_stream, tls_parameters)
|
|
||||||
.await
|
|
||||||
.map_err(error::connection)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
feature = "tokio1",
|
feature = "tokio1",
|
||||||
not(any(feature = "tokio1-native-tls", feature = "tokio1-rustls-tls"))
|
not(any(feature = "tokio1-native-tls", feature = "tokio1-rustls-tls"))
|
||||||
@@ -259,55 +192,6 @@ impl AsyncNetworkStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
|
||||||
#[cfg(any(feature = "tokio02-native-tls", feature = "tokio02-rustls-tls"))]
|
|
||||||
async fn upgrade_tokio02_tls(
|
|
||||||
tcp_stream: Tokio02TcpStream,
|
|
||||||
mut tls_parameters: TlsParameters,
|
|
||||||
) -> Result<InnerAsyncNetworkStream, Error> {
|
|
||||||
let domain = mem::take(&mut tls_parameters.domain);
|
|
||||||
|
|
||||||
match tls_parameters.connector {
|
|
||||||
#[cfg(feature = "native-tls")]
|
|
||||||
InnerTlsParameters::NativeTls(connector) => {
|
|
||||||
#[cfg(not(feature = "tokio02-native-tls"))]
|
|
||||||
panic!("built without the tokio02-native-tls feature");
|
|
||||||
|
|
||||||
#[cfg(feature = "tokio02-native-tls")]
|
|
||||||
return {
|
|
||||||
use tokio02_native_tls_crate::TlsConnector;
|
|
||||||
|
|
||||||
let connector = TlsConnector::from(connector);
|
|
||||||
let stream = connector
|
|
||||||
.connect(&domain, tcp_stream)
|
|
||||||
.await
|
|
||||||
.map_err(error::connection)?;
|
|
||||||
Ok(InnerAsyncNetworkStream::Tokio02NativeTls(stream))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#[cfg(feature = "rustls-tls")]
|
|
||||||
InnerTlsParameters::RustlsTls(config) => {
|
|
||||||
#[cfg(not(feature = "tokio02-rustls-tls"))]
|
|
||||||
panic!("built without the tokio02-rustls-tls feature");
|
|
||||||
|
|
||||||
#[cfg(feature = "tokio02-rustls-tls")]
|
|
||||||
return {
|
|
||||||
use tokio02_rustls::{webpki::DNSNameRef, TlsConnector};
|
|
||||||
|
|
||||||
let domain =
|
|
||||||
DNSNameRef::try_from_ascii_str(&domain).map_err(error::connection)?;
|
|
||||||
|
|
||||||
let connector = TlsConnector::from(config);
|
|
||||||
let stream = connector
|
|
||||||
.connect(domain, tcp_stream)
|
|
||||||
.await
|
|
||||||
.map_err(error::connection)?;
|
|
||||||
Ok(InnerAsyncNetworkStream::Tokio02RustlsTls(stream))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
#[cfg(any(feature = "tokio1-native-tls", feature = "tokio1-rustls-tls"))]
|
#[cfg(any(feature = "tokio1-native-tls", feature = "tokio1-rustls-tls"))]
|
||||||
async fn upgrade_tokio1_tls(
|
async fn upgrade_tokio1_tls(
|
||||||
@@ -411,12 +295,6 @@ impl AsyncNetworkStream {
|
|||||||
|
|
||||||
pub fn is_encrypted(&self) -> bool {
|
pub fn is_encrypted(&self) -> bool {
|
||||||
match self.inner {
|
match self.inner {
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
InnerAsyncNetworkStream::Tokio02Tcp(_) => false,
|
|
||||||
#[cfg(feature = "tokio02-native-tls")]
|
|
||||||
InnerAsyncNetworkStream::Tokio02NativeTls(_) => true,
|
|
||||||
#[cfg(feature = "tokio02-rustls-tls")]
|
|
||||||
InnerAsyncNetworkStream::Tokio02RustlsTls(_) => true,
|
|
||||||
#[cfg(feature = "tokio1")]
|
#[cfg(feature = "tokio1")]
|
||||||
InnerAsyncNetworkStream::Tokio1Tcp(_) => false,
|
InnerAsyncNetworkStream::Tokio1Tcp(_) => false,
|
||||||
#[cfg(feature = "tokio1-native-tls")]
|
#[cfg(feature = "tokio1-native-tls")]
|
||||||
@@ -441,12 +319,6 @@ impl FuturesAsyncRead for AsyncNetworkStream {
|
|||||||
buf: &mut [u8],
|
buf: &mut [u8],
|
||||||
) -> Poll<IoResult<usize>> {
|
) -> Poll<IoResult<usize>> {
|
||||||
match self.inner {
|
match self.inner {
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
InnerAsyncNetworkStream::Tokio02Tcp(ref mut s) => Pin::new(s).poll_read(cx, buf),
|
|
||||||
#[cfg(feature = "tokio02-native-tls")]
|
|
||||||
InnerAsyncNetworkStream::Tokio02NativeTls(ref mut s) => Pin::new(s).poll_read(cx, buf),
|
|
||||||
#[cfg(feature = "tokio02-rustls-tls")]
|
|
||||||
InnerAsyncNetworkStream::Tokio02RustlsTls(ref mut s) => Pin::new(s).poll_read(cx, buf),
|
|
||||||
#[cfg(feature = "tokio1")]
|
#[cfg(feature = "tokio1")]
|
||||||
InnerAsyncNetworkStream::Tokio1Tcp(ref mut s) => {
|
InnerAsyncNetworkStream::Tokio1Tcp(ref mut s) => {
|
||||||
let mut b = Tokio1ReadBuf::new(buf);
|
let mut b = Tokio1ReadBuf::new(buf);
|
||||||
@@ -499,12 +371,6 @@ impl FuturesAsyncWrite for AsyncNetworkStream {
|
|||||||
buf: &[u8],
|
buf: &[u8],
|
||||||
) -> Poll<IoResult<usize>> {
|
) -> Poll<IoResult<usize>> {
|
||||||
match self.inner {
|
match self.inner {
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
InnerAsyncNetworkStream::Tokio02Tcp(ref mut s) => Pin::new(s).poll_write(cx, buf),
|
|
||||||
#[cfg(feature = "tokio02-native-tls")]
|
|
||||||
InnerAsyncNetworkStream::Tokio02NativeTls(ref mut s) => Pin::new(s).poll_write(cx, buf),
|
|
||||||
#[cfg(feature = "tokio02-rustls-tls")]
|
|
||||||
InnerAsyncNetworkStream::Tokio02RustlsTls(ref mut s) => Pin::new(s).poll_write(cx, buf),
|
|
||||||
#[cfg(feature = "tokio1")]
|
#[cfg(feature = "tokio1")]
|
||||||
InnerAsyncNetworkStream::Tokio1Tcp(ref mut s) => Pin::new(s).poll_write(cx, buf),
|
InnerAsyncNetworkStream::Tokio1Tcp(ref mut s) => Pin::new(s).poll_write(cx, buf),
|
||||||
#[cfg(feature = "tokio1-native-tls")]
|
#[cfg(feature = "tokio1-native-tls")]
|
||||||
@@ -530,12 +396,6 @@ impl FuturesAsyncWrite for AsyncNetworkStream {
|
|||||||
|
|
||||||
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<IoResult<()>> {
|
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<IoResult<()>> {
|
||||||
match self.inner {
|
match self.inner {
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
InnerAsyncNetworkStream::Tokio02Tcp(ref mut s) => Pin::new(s).poll_flush(cx),
|
|
||||||
#[cfg(feature = "tokio02-native-tls")]
|
|
||||||
InnerAsyncNetworkStream::Tokio02NativeTls(ref mut s) => Pin::new(s).poll_flush(cx),
|
|
||||||
#[cfg(feature = "tokio02-rustls-tls")]
|
|
||||||
InnerAsyncNetworkStream::Tokio02RustlsTls(ref mut s) => Pin::new(s).poll_flush(cx),
|
|
||||||
#[cfg(feature = "tokio1")]
|
#[cfg(feature = "tokio1")]
|
||||||
InnerAsyncNetworkStream::Tokio1Tcp(ref mut s) => Pin::new(s).poll_flush(cx),
|
InnerAsyncNetworkStream::Tokio1Tcp(ref mut s) => Pin::new(s).poll_flush(cx),
|
||||||
#[cfg(feature = "tokio1-native-tls")]
|
#[cfg(feature = "tokio1-native-tls")]
|
||||||
@@ -557,12 +417,6 @@ impl FuturesAsyncWrite for AsyncNetworkStream {
|
|||||||
|
|
||||||
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<IoResult<()>> {
|
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<IoResult<()>> {
|
||||||
match self.inner {
|
match self.inner {
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
InnerAsyncNetworkStream::Tokio02Tcp(ref mut s) => Pin::new(s).poll_shutdown(cx),
|
|
||||||
#[cfg(feature = "tokio02-native-tls")]
|
|
||||||
InnerAsyncNetworkStream::Tokio02NativeTls(ref mut s) => Pin::new(s).poll_shutdown(cx),
|
|
||||||
#[cfg(feature = "tokio02-rustls-tls")]
|
|
||||||
InnerAsyncNetworkStream::Tokio02RustlsTls(ref mut s) => Pin::new(s).poll_shutdown(cx),
|
|
||||||
#[cfg(feature = "tokio1")]
|
#[cfg(feature = "tokio1")]
|
||||||
InnerAsyncNetworkStream::Tokio1Tcp(ref mut s) => Pin::new(s).poll_shutdown(cx),
|
InnerAsyncNetworkStream::Tokio1Tcp(ref mut s) => Pin::new(s).poll_shutdown(cx),
|
||||||
#[cfg(feature = "tokio1-native-tls")]
|
#[cfg(feature = "tokio1-native-tls")]
|
||||||
|
|||||||
@@ -27,9 +27,9 @@
|
|||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
#[cfg(any(feature = "tokio02", feature = "tokio1", feature = "async-std1"))]
|
#[cfg(any(feature = "tokio1", feature = "async-std1"))]
|
||||||
pub(crate) use self::async_connection::AsyncSmtpConnection;
|
pub(crate) use self::async_connection::AsyncSmtpConnection;
|
||||||
#[cfg(any(feature = "tokio02", feature = "tokio1", feature = "async-std1"))]
|
#[cfg(any(feature = "tokio1", feature = "async-std1"))]
|
||||||
pub(crate) use self::async_net::AsyncNetworkStream;
|
pub(crate) use self::async_net::AsyncNetworkStream;
|
||||||
use self::net::NetworkStream;
|
use self::net::NetworkStream;
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls-tls"))]
|
||||||
@@ -39,9 +39,9 @@ pub use self::{
|
|||||||
tls::{Certificate, Tls, TlsParameters, TlsParametersBuilder},
|
tls::{Certificate, Tls, TlsParameters, TlsParametersBuilder},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(any(feature = "tokio02", feature = "tokio1", feature = "async-std1"))]
|
#[cfg(any(feature = "tokio1", feature = "async-std1"))]
|
||||||
mod async_connection;
|
mod async_connection;
|
||||||
#[cfg(any(feature = "tokio02", feature = "tokio1", feature = "async-std1"))]
|
#[cfg(any(feature = "tokio1", feature = "async-std1"))]
|
||||||
mod async_net;
|
mod async_net;
|
||||||
mod connection;
|
mod connection;
|
||||||
mod net;
|
mod net;
|
||||||
|
|||||||
@@ -116,7 +116,7 @@
|
|||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
#[cfg(any(feature = "tokio02", feature = "tokio1", feature = "async-std1"))]
|
#[cfg(any(feature = "tokio1", feature = "async-std1"))]
|
||||||
pub use self::async_transport::{AsyncSmtpTransport, AsyncSmtpTransportBuilder};
|
pub use self::async_transport::{AsyncSmtpTransport, AsyncSmtpTransportBuilder};
|
||||||
#[cfg(feature = "r2d2")]
|
#[cfg(feature = "r2d2")]
|
||||||
pub use self::pool::PoolConfig;
|
pub use self::pool::PoolConfig;
|
||||||
@@ -137,7 +137,7 @@ use crate::transport::smtp::{
|
|||||||
use client::Tls;
|
use client::Tls;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
#[cfg(any(feature = "tokio02", feature = "tokio1", feature = "async-std1"))]
|
#[cfg(any(feature = "tokio1", feature = "async-std1"))]
|
||||||
mod async_transport;
|
mod async_transport;
|
||||||
pub mod authentication;
|
pub mod authentication;
|
||||||
pub mod client;
|
pub mod client;
|
||||||
|
|||||||
@@ -28,10 +28,10 @@
|
|||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
#[cfg(any(feature = "tokio02", feature = "tokio1", feature = "async-std1"))]
|
#[cfg(any(feature = "tokio1", feature = "async-std1"))]
|
||||||
use crate::AsyncTransport;
|
use crate::AsyncTransport;
|
||||||
use crate::{address::Envelope, Transport};
|
use crate::{address::Envelope, Transport};
|
||||||
#[cfg(any(feature = "tokio02", feature = "tokio1", feature = "async-std1"))]
|
#[cfg(any(feature = "tokio1", feature = "async-std1"))]
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use std::{error::Error as StdError, fmt};
|
use std::{error::Error as StdError, fmt};
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ impl Transport for StubTransport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "tokio02", feature = "tokio1", feature = "async-std1"))]
|
#[cfg(any(feature = "tokio1", feature = "async-std1"))]
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl AsyncTransport for StubTransport {
|
impl AsyncTransport for StubTransport {
|
||||||
type Ok = ();
|
type Ok = ();
|
||||||
|
|||||||
@@ -101,53 +101,6 @@ mod sync {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
#[cfg(all(feature = "file-transport", feature = "builder", feature = "tokio02"))]
|
|
||||||
mod tokio_02 {
|
|
||||||
use crate::default_date;
|
|
||||||
use lettre::{AsyncFileTransport, AsyncTransport, Message, Tokio02Executor};
|
|
||||||
use std::{
|
|
||||||
env::temp_dir,
|
|
||||||
fs::{read_to_string, remove_file},
|
|
||||||
};
|
|
||||||
|
|
||||||
use tokio02_crate as tokio;
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn file_transport_tokio02() {
|
|
||||||
let sender = AsyncFileTransport::<Tokio02Executor>::new(temp_dir());
|
|
||||||
let email = Message::builder()
|
|
||||||
.from("NoBody <nobody@domain.tld>".parse().unwrap())
|
|
||||||
.reply_to("Yuin <yuin@domain.tld>".parse().unwrap())
|
|
||||||
.to("Hei <hei@domain.tld>".parse().unwrap())
|
|
||||||
.subject("Happy new year")
|
|
||||||
.date(default_date())
|
|
||||||
.body(String::from("Be happy!"))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let result = sender.send(email).await;
|
|
||||||
let id = result.unwrap();
|
|
||||||
|
|
||||||
let eml_file = temp_dir().join(format!("{}.eml", id));
|
|
||||||
let eml = read_to_string(&eml_file).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
eml,
|
|
||||||
concat!(
|
|
||||||
"From: NoBody <nobody@domain.tld>\r\n",
|
|
||||||
"Reply-To: Yuin <yuin@domain.tld>\r\n",
|
|
||||||
"To: Hei <hei@domain.tld>\r\n",
|
|
||||||
"Subject: Happy new year\r\n",
|
|
||||||
"Date: Tue, 15 Nov 1994 08:12:31 -0000\r\n",
|
|
||||||
"Content-Transfer-Encoding: 7bit\r\n",
|
|
||||||
"\r\n",
|
|
||||||
"Be happy!"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
remove_file(eml_file).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(all(feature = "file-transport", feature = "builder", feature = "tokio1"))]
|
#[cfg(all(feature = "file-transport", feature = "builder", feature = "tokio1"))]
|
||||||
mod tokio_1 {
|
mod tokio_1 {
|
||||||
@@ -160,7 +113,6 @@ mod tokio_1 {
|
|||||||
|
|
||||||
use tokio1_crate as tokio;
|
use tokio1_crate as tokio;
|
||||||
|
|
||||||
#[cfg(feature = "tokio02")]
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn file_transport_tokio1() {
|
async fn file_transport_tokio1() {
|
||||||
let sender = AsyncFileTransport::<Tokio1Executor>::new(temp_dir());
|
let sender = AsyncFileTransport::<Tokio1Executor>::new(temp_dir());
|
||||||
|
|||||||
@@ -20,33 +20,6 @@ mod sync {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
#[cfg(all(
|
|
||||||
feature = "sendmail-transport",
|
|
||||||
feature = "builder",
|
|
||||||
feature = "tokio02"
|
|
||||||
))]
|
|
||||||
mod tokio_02 {
|
|
||||||
use lettre::{AsyncSendmailTransport, AsyncTransport, Message, Tokio02Executor};
|
|
||||||
use tokio02_crate as tokio;
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn sendmail_transport_tokio02() {
|
|
||||||
let sender = AsyncSendmailTransport::<Tokio02Executor>::new();
|
|
||||||
let email = Message::builder()
|
|
||||||
.from("NoBody <nobody@domain.tld>".parse().unwrap())
|
|
||||||
.reply_to("Yuin <yuin@domain.tld>".parse().unwrap())
|
|
||||||
.to("Hei <hei@domain.tld>".parse().unwrap())
|
|
||||||
.subject("Happy new year")
|
|
||||||
.body(String::from("Be happy!"))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let result = sender.send(email).await;
|
|
||||||
println!("{:?}", result);
|
|
||||||
assert!(result.is_ok());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
feature = "sendmail-transport",
|
feature = "sendmail-transport",
|
||||||
|
|||||||
@@ -20,31 +20,6 @@ mod sync {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
#[cfg(all(feature = "smtp-transport", feature = "builder", feature = "tokio02"))]
|
|
||||||
mod tokio_02 {
|
|
||||||
use lettre::{AsyncSmtpTransport, AsyncTransport, Message, Tokio02Executor};
|
|
||||||
|
|
||||||
use tokio02_crate as tokio;
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn smtp_transport_simple_tokio02() {
|
|
||||||
let email = Message::builder()
|
|
||||||
.from("NoBody <nobody@domain.tld>".parse().unwrap())
|
|
||||||
.reply_to("Yuin <yuin@domain.tld>".parse().unwrap())
|
|
||||||
.to("Hei <hei@domain.tld>".parse().unwrap())
|
|
||||||
.subject("Happy new year")
|
|
||||||
.body(String::from("Be happy!"))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let sender: AsyncSmtpTransport<Tokio02Executor> =
|
|
||||||
AsyncSmtpTransport::<Tokio02Executor>::builder_dangerous("127.0.0.1")
|
|
||||||
.port(2525)
|
|
||||||
.build();
|
|
||||||
sender.send(email).await.unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(all(feature = "smtp-transport", feature = "builder", feature = "tokio1"))]
|
#[cfg(all(feature = "smtp-transport", feature = "builder", feature = "tokio1"))]
|
||||||
mod tokio_1 {
|
mod tokio_1 {
|
||||||
|
|||||||
@@ -20,30 +20,6 @@ mod sync {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
#[cfg(all(feature = "builder", feature = "tokio02"))]
|
|
||||||
mod tokio_02 {
|
|
||||||
use lettre::{transport::stub::StubTransport, AsyncTransport, Message};
|
|
||||||
|
|
||||||
use tokio02_crate as tokio;
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn stub_transport_tokio02() {
|
|
||||||
let sender_ok = StubTransport::new_ok();
|
|
||||||
let sender_ko = StubTransport::new_error();
|
|
||||||
let email = Message::builder()
|
|
||||||
.from("NoBody <nobody@domain.tld>".parse().unwrap())
|
|
||||||
.reply_to("Yuin <yuin@domain.tld>".parse().unwrap())
|
|
||||||
.to("Hei <hei@domain.tld>".parse().unwrap())
|
|
||||||
.subject("Happy new year")
|
|
||||||
.body(String::from("Be happy!"))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
sender_ok.send(email.clone()).await.unwrap();
|
|
||||||
sender_ko.send(email).await.unwrap_err();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(all(feature = "builder", feature = "tokio1"))]
|
#[cfg(all(feature = "builder", feature = "tokio1"))]
|
||||||
mod tokio_1 {
|
mod tokio_1 {
|
||||||
|
|||||||
Reference in New Issue
Block a user