Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for tokio #52

Merged
merged 6 commits into from
Jun 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,23 @@ jobs:
command: check
args: --benches

- name: tests
- name: tests tokio
uses: actions-rs/cargo@v1
with:
command: test
args: --all --no-default-features --features file-transport smtp-transport
args: --all --no-default-features --features file-transport,smtp-transport,runtime-tokio

- name: tests tokio with socks5
uses: actions-rs/cargo@v1
with:
command: test
args: --all --no-default-features --features file-transport,smtp-transport,runtime-tokio,socks5

- name: tests async-std
uses: actions-rs/cargo@v1
with:
command: test
args: --all --no-default-features --features file-transport,smtp-transport,runtime-async-std

check_fmt_and_docs:
name: Checking fmt and docs
Expand Down Expand Up @@ -75,4 +87,3 @@ jobs:
- uses: actions-rs/clippy-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features
38 changes: 26 additions & 12 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,40 +19,54 @@ is-it-maintained-open-issues = { repository = "async-email/async-smtp" }

[dependencies]
log = "^0.4"
nom = { version = "^5.0", optional = true }
async-trait = "0.1.17"
pin-project = "1"
pin-utils = "0.1.0"
thiserror = "1.0.9"
futures = "0.3.21"

nom = { version = "^7.0", optional = true }
bufstream = { version = "^0.1", optional = true }
base64 = { version = "^0.13", optional = true }
hostname = { version = "0.3.1", optional = true }
serde = { version = "^1.0", optional = true }
serde_json = { version = "^1.0", optional = true }
serde_derive = { version = "^1.0", optional = true }
fast-socks5 = { version = "^0.4", optional = true }
async-native-tls = { version = "0.3.3" }
async-std = { version = "1.6.0", features = ["unstable"] }
async-trait = "0.1.17"
pin-project = "1"
pin-utils = "0.1.0"
thiserror = "1.0.9"
fast-socks5 = { version = "^0.8", optional = true }

async-std = { version = "1.11", features = ["unstable"], optional = true }
tokio = { version = "1", features = ["fs", "rt", "time", "net"], optional = true }
async-native-tls = { version = "0.4", default-features = false }


[dev-dependencies]
env_logger = "^0.8"
env_logger = "^0.9"
glob = "^0.3"
criterion = "^0.3"
async-attributes = "1.1.1"
async-std = { version = "1.11", features = ["unstable", "attributes"] }
tokio = { version = "1", features = ["fs", "rt", "time", "net", "macros"] }

[[bench]]
name = "transport_smtp"
harness = false

[features]
default = ["file-transport", "smtp-transport", "sendmail-transport"]
unstable = []
default = [
"file-transport",
"smtp-transport",
"sendmail-transport",
"runtime-tokio"
]

serde-impls = ["serde", "serde_derive"]
file-transport = ["serde-impls", "serde_json"]
smtp-transport = ["bufstream", "base64", "nom", "hostname"]
sendmail-transport = []
native-tls-vendored = ["async-native-tls/vendored"]
socks5 = ["fast-socks5"]
runtime-async-std = ["async-std", "async-native-tls/runtime-async-std"]
runtime-tokio = ["tokio", "async-native-tls/runtime-tokio"]


[[example]]
name = "smtp"
Expand Down
2 changes: 1 addition & 1 deletion src/file/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Error and result type for file transport

use async_std::io;
use futures::io;

/// An enum of all error kinds.
#[derive(thiserror::Error, Debug)]
Expand Down
14 changes: 7 additions & 7 deletions src/file/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
//! It can be useful for testing purposes, or if you want to keep track of sent messages.
//!

use std::path::Path;
use std::{path::PathBuf, time::Duration};

use async_std::fs::File;
use async_std::path::Path;
use async_std::prelude::*;
#[cfg(feature = "runtime-async-std")]
use async_std::fs::write;
use async_trait::async_trait;
#[cfg(feature = "runtime-tokio")]
use tokio::fs::write;

use crate::file::error::FileResult;
use crate::Envelope;
Expand Down Expand Up @@ -64,10 +66,8 @@ impl<'a> Transport<'a> for FileTransport {
message: email.message_to_string().await?.as_bytes().to_vec(),
})?;

File::create(file)
.await?
.write_all(serialized.as_bytes())
.await?;
write(file, serialized.as_bytes()).await?;

Ok(())
}

Expand Down
42 changes: 42 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
clippy::unwrap_used
)]

#[cfg(not(any(feature = "runtime-tokio", feature = "runtime-async-std")))]
compile_error!("one of 'runtime-async-std' or 'runtime-tokio' features must be enabled");

#[cfg(all(feature = "runtime-tokio", feature = "runtime-async-std"))]
compile_error!("only one of 'runtime-async-std' or 'runtime-tokio' features must be enabled");

pub mod error;
#[cfg(feature = "file-transport")]
pub mod file;
Expand Down Expand Up @@ -53,3 +59,39 @@ pub trait Transport<'a> {
timeout: Option<&Duration>,
) -> Self::Result;
}

#[macro_export]
macro_rules! async_test {
($name:ident, $block:block) => {
#[cfg(feature = "runtime-tokio")]
#[tokio::test]
async fn $name() {
$block
}

#[cfg(feature = "runtime-async-std")]
#[async_std::test]
async fn $name() {
$block
}
};
}

#[macro_export]
macro_rules! async_test_ignore {
($name:ident, $block:block) => {
#[cfg(feature = "runtime-tokio")]
#[tokio::test]
#[ignore]
async fn $name() {
$block
}

#[cfg(feature = "runtime-async-std")]
#[async_std::test]
#[ignore]
async fn $name() {
$block
}
};
}
5 changes: 4 additions & 1 deletion src/sendmail/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use std::string::FromUtf8Error;

use async_std::io;
use futures::io;

/// An enum of all error kinds.
#[derive(thiserror::Error, Debug)]
Expand All @@ -16,6 +16,9 @@ pub enum Error {
/// IO error
#[error("io error: {0}")]
Io(#[from] io::Error),
#[cfg(feature = "runtime-tokio")]
#[error("join: {0}")]
Join(#[from] tokio::task::JoinError),
}

/// sendmail result type
Expand Down
29 changes: 21 additions & 8 deletions src/sendmail/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use crate::sendmail::error::SendmailResult;
use crate::SendableEmail;
use crate::Transport;

use async_std::prelude::*;
use async_trait::async_trait;
use log::info;
use std::convert::AsRef;
Expand All @@ -15,6 +14,12 @@ use std::{
time::Duration,
};

#[cfg(feature = "runtime-tokio")]
use tokio::{io::AsyncReadExt, task::spawn_blocking};

#[cfg(feature = "runtime-async-std")]
use async_std::{io::ReadExt, task::spawn_blocking};

pub mod error;

/// Sends an email using the `sendmail` command
Expand Down Expand Up @@ -63,7 +68,7 @@ impl<'a> Transport<'a> for SendmailTransport {
let _ = email.message().read_to_string(&mut message_content).await;

// TODO: Convert to real async, once async-std has a process implementation.
let output = async_std::task::spawn_blocking(move || {
let res = spawn_blocking(move || {
// Spawn the sendmail command
let mut process = Command::new(command)
.arg("-i")
Expand All @@ -83,14 +88,22 @@ impl<'a> Transport<'a> for SendmailTransport {

info!("Wrote {} message to stdin", message_id);

process.wait_with_output()
let output = process.wait_with_output()?;
if output.status.success() {
Ok(())
} else {
Err(error::Error::Client(String::from_utf8(output.stderr)?))
}
})
.await?;
.await;

if output.status.success() {
Ok(())
} else {
Err(error::Error::Client(String::from_utf8(output.stderr)?))
#[cfg(feature = "runtime-tokio")]
{
res?
}
#[cfg(feature = "runtime-async-std")]
{
res
}
}

Expand Down
8 changes: 6 additions & 2 deletions src/smtp/client/codec.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use async_std::io::{self, Write};
use async_std::prelude::*;
#[cfg(feature = "runtime-async-std")]
use async_std::io::{Write, WriteExt};
#[cfg(feature = "runtime-tokio")]
use tokio::io::{AsyncWrite as Write, AsyncWriteExt};

use futures::io;

/// The codec used for transparency
#[derive(Default, Clone, Copy, Debug)]
Expand Down
Loading