Skip to content

Commit c6aba19

Browse files
Merge pull request #52 from async-email/tokio
2 parents d6b947c + fd8e009 commit c6aba19

21 files changed

+567
-221
lines changed

Diff for: .github/workflows/ci.yml

+14-3
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,23 @@ jobs:
3838
command: check
3939
args: --benches
4040

41-
- name: tests
41+
- name: tests tokio
4242
uses: actions-rs/cargo@v1
4343
with:
4444
command: test
45-
args: --all --no-default-features --features file-transport smtp-transport
45+
args: --all --no-default-features --features file-transport,smtp-transport,runtime-tokio
46+
47+
- name: tests tokio with socks5
48+
uses: actions-rs/cargo@v1
49+
with:
50+
command: test
51+
args: --all --no-default-features --features file-transport,smtp-transport,runtime-tokio,socks5
52+
53+
- name: tests async-std
54+
uses: actions-rs/cargo@v1
55+
with:
56+
command: test
57+
args: --all --no-default-features --features file-transport,smtp-transport,runtime-async-std
4658

4759
check_fmt_and_docs:
4860
name: Checking fmt and docs
@@ -75,4 +87,3 @@ jobs:
7587
- uses: actions-rs/clippy-check@v1
7688
with:
7789
token: ${{ secrets.GITHUB_TOKEN }}
78-
args: --all-features

Diff for: Cargo.toml

+26-12
Original file line numberDiff line numberDiff line change
@@ -19,40 +19,54 @@ is-it-maintained-open-issues = { repository = "async-email/async-smtp" }
1919

2020
[dependencies]
2121
log = "^0.4"
22-
nom = { version = "^5.0", optional = true }
22+
async-trait = "0.1.17"
23+
pin-project = "1"
24+
pin-utils = "0.1.0"
25+
thiserror = "1.0.9"
26+
futures = "0.3.21"
27+
28+
nom = { version = "^7.0", optional = true }
2329
bufstream = { version = "^0.1", optional = true }
2430
base64 = { version = "^0.13", optional = true }
2531
hostname = { version = "0.3.1", optional = true }
2632
serde = { version = "^1.0", optional = true }
2733
serde_json = { version = "^1.0", optional = true }
2834
serde_derive = { version = "^1.0", optional = true }
29-
fast-socks5 = { version = "^0.4", optional = true }
30-
async-native-tls = { version = "0.3.3" }
31-
async-std = { version = "1.6.0", features = ["unstable"] }
32-
async-trait = "0.1.17"
33-
pin-project = "1"
34-
pin-utils = "0.1.0"
35-
thiserror = "1.0.9"
35+
fast-socks5 = { version = "^0.8", optional = true }
36+
37+
async-std = { version = "1.11", features = ["unstable"], optional = true }
38+
tokio = { version = "1", features = ["fs", "rt", "time", "net"], optional = true }
39+
async-native-tls = { version = "0.4", default-features = false }
40+
3641

3742
[dev-dependencies]
38-
env_logger = "^0.8"
43+
env_logger = "^0.9"
3944
glob = "^0.3"
4045
criterion = "^0.3"
41-
async-attributes = "1.1.1"
46+
async-std = { version = "1.11", features = ["unstable", "attributes"] }
47+
tokio = { version = "1", features = ["fs", "rt", "time", "net", "macros"] }
4248

4349
[[bench]]
4450
name = "transport_smtp"
4551
harness = false
4652

4753
[features]
48-
default = ["file-transport", "smtp-transport", "sendmail-transport"]
49-
unstable = []
54+
default = [
55+
"file-transport",
56+
"smtp-transport",
57+
"sendmail-transport",
58+
"runtime-tokio"
59+
]
60+
5061
serde-impls = ["serde", "serde_derive"]
5162
file-transport = ["serde-impls", "serde_json"]
5263
smtp-transport = ["bufstream", "base64", "nom", "hostname"]
5364
sendmail-transport = []
5465
native-tls-vendored = ["async-native-tls/vendored"]
5566
socks5 = ["fast-socks5"]
67+
runtime-async-std = ["async-std", "async-native-tls/runtime-async-std"]
68+
runtime-tokio = ["tokio", "async-native-tls/runtime-tokio"]
69+
5670

5771
[[example]]
5872
name = "smtp"

Diff for: src/file/error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Error and result type for file transport
22
3-
use async_std::io;
3+
use futures::io;
44

55
/// An enum of all error kinds.
66
#[derive(thiserror::Error, Debug)]

Diff for: src/file/mod.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
//! It can be useful for testing purposes, or if you want to keep track of sent messages.
44
//!
55
6+
use std::path::Path;
67
use std::{path::PathBuf, time::Duration};
78

8-
use async_std::fs::File;
9-
use async_std::path::Path;
10-
use async_std::prelude::*;
9+
#[cfg(feature = "runtime-async-std")]
10+
use async_std::fs::write;
1111
use async_trait::async_trait;
12+
#[cfg(feature = "runtime-tokio")]
13+
use tokio::fs::write;
1214

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

67-
File::create(file)
68-
.await?
69-
.write_all(serialized.as_bytes())
70-
.await?;
69+
write(file, serialized.as_bytes()).await?;
70+
7171
Ok(())
7272
}
7373

Diff for: src/lib.rs

+42
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
clippy::unwrap_used
1212
)]
1313

14+
#[cfg(not(any(feature = "runtime-tokio", feature = "runtime-async-std")))]
15+
compile_error!("one of 'runtime-async-std' or 'runtime-tokio' features must be enabled");
16+
17+
#[cfg(all(feature = "runtime-tokio", feature = "runtime-async-std"))]
18+
compile_error!("only one of 'runtime-async-std' or 'runtime-tokio' features must be enabled");
19+
1420
pub mod error;
1521
#[cfg(feature = "file-transport")]
1622
pub mod file;
@@ -53,3 +59,39 @@ pub trait Transport<'a> {
5359
timeout: Option<&Duration>,
5460
) -> Self::Result;
5561
}
62+
63+
#[macro_export]
64+
macro_rules! async_test {
65+
($name:ident, $block:block) => {
66+
#[cfg(feature = "runtime-tokio")]
67+
#[tokio::test]
68+
async fn $name() {
69+
$block
70+
}
71+
72+
#[cfg(feature = "runtime-async-std")]
73+
#[async_std::test]
74+
async fn $name() {
75+
$block
76+
}
77+
};
78+
}
79+
80+
#[macro_export]
81+
macro_rules! async_test_ignore {
82+
($name:ident, $block:block) => {
83+
#[cfg(feature = "runtime-tokio")]
84+
#[tokio::test]
85+
#[ignore]
86+
async fn $name() {
87+
$block
88+
}
89+
90+
#[cfg(feature = "runtime-async-std")]
91+
#[async_std::test]
92+
#[ignore]
93+
async fn $name() {
94+
$block
95+
}
96+
};
97+
}

Diff for: src/sendmail/error.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use std::string::FromUtf8Error;
44

5-
use async_std::io;
5+
use futures::io;
66

77
/// An enum of all error kinds.
88
#[derive(thiserror::Error, Debug)]
@@ -16,6 +16,9 @@ pub enum Error {
1616
/// IO error
1717
#[error("io error: {0}")]
1818
Io(#[from] io::Error),
19+
#[cfg(feature = "runtime-tokio")]
20+
#[error("join: {0}")]
21+
Join(#[from] tokio::task::JoinError),
1922
}
2023

2124
/// sendmail result type

Diff for: src/sendmail/mod.rs

+21-8
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use crate::sendmail::error::SendmailResult;
55
use crate::SendableEmail;
66
use crate::Transport;
77

8-
use async_std::prelude::*;
98
use async_trait::async_trait;
109
use log::info;
1110
use std::convert::AsRef;
@@ -15,6 +14,12 @@ use std::{
1514
time::Duration,
1615
};
1716

17+
#[cfg(feature = "runtime-tokio")]
18+
use tokio::{io::AsyncReadExt, task::spawn_blocking};
19+
20+
#[cfg(feature = "runtime-async-std")]
21+
use async_std::{io::ReadExt, task::spawn_blocking};
22+
1823
pub mod error;
1924

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

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

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

86-
process.wait_with_output()
91+
let output = process.wait_with_output()?;
92+
if output.status.success() {
93+
Ok(())
94+
} else {
95+
Err(error::Error::Client(String::from_utf8(output.stderr)?))
96+
}
8797
})
88-
.await?;
98+
.await;
8999

90-
if output.status.success() {
91-
Ok(())
92-
} else {
93-
Err(error::Error::Client(String::from_utf8(output.stderr)?))
100+
#[cfg(feature = "runtime-tokio")]
101+
{
102+
res?
103+
}
104+
#[cfg(feature = "runtime-async-std")]
105+
{
106+
res
94107
}
95108
}
96109

Diff for: src/smtp/client/codec.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
use async_std::io::{self, Write};
2-
use async_std::prelude::*;
1+
#[cfg(feature = "runtime-async-std")]
2+
use async_std::io::{Write, WriteExt};
3+
#[cfg(feature = "runtime-tokio")]
4+
use tokio::io::{AsyncWrite as Write, AsyncWriteExt};
5+
6+
use futures::io;
37

48
/// The codec used for transparency
59
#[derive(Default, Clone, Copy, Debug)]

0 commit comments

Comments
 (0)