Skip to content
Open
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
6 changes: 5 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
rust: [1.70.0, stable]
rust: [1.81.0, stable]
os: [ubuntu-latest, macOS-latest, windows-latest]

steps:
Expand All @@ -50,3 +50,7 @@ jobs:
run: cargo check --no-default-features --features tokio-runtime,link_to
- name: Run unit tests (Tokio)
run: cargo test --verbose --no-default-features --features tokio-runtime,link_to --lib
- name: Check (Smol)
run: cargo check --no-default-features --features smol-runtime,link_to
- name: Run unit tests (Smol)
run: cargo test --verbose --no-default-features --features smol-runtime,link_to --lib
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ either = "1.6.1"
futures = { version = "0.3.17", optional = true }
hex = "0.4.3"
memmap2 = { version = "0.5.8", optional = true }
smol = { version = "2.0.0", optional = true }
miette = "5.7.0"
reflink-copy = "0.1.9"
serde = "1.0.130"
Expand All @@ -43,6 +44,8 @@ libc = { version = "0.2.144", optional = true }
async-attributes = { version = "1.1.2" }
criterion = "0.4.0"
lazy_static = "1.4.0"
smol-macros = "0.1.1"
macro_rules_attribute = "0.2.0"
tokio = { version = "1.12.0", features = [
"fs",
"io-util",
Expand All @@ -61,3 +64,4 @@ mmap = ["memmap2", "libc"]
async-std = ["dep:async-std", "futures"]
link_to = []
tokio-runtime = ["tokio", "tokio-stream", "futures"]
smol-runtime = ["smol", "futures"]
52 changes: 36 additions & 16 deletions benches/benchmarks.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#[cfg(feature = "async-std")]
use async_std::fs as afs;
#[cfg(feature = "smol")]
use smol::fs as afs;
#[cfg(feature = "link_to")]
use std::path::PathBuf;
#[cfg(all(test, feature = "tokio"))]
Expand All @@ -22,6 +24,15 @@ where
TOKIO_RUNTIME.block_on(future)
}

#[cfg(all(test, feature = "smol"))]
#[inline]
pub fn block_on<F, T>(future: F) -> T
where
F: std::future::Future<Output = T>,
{
smol::block_on(future)
}

use std::fs::{self, File};
use std::io::prelude::*;

Expand Down Expand Up @@ -62,7 +73,7 @@ fn baseline_read_many_sync(c: &mut Criterion) {
});
}

#[cfg(any(feature = "async-std", feature = "tokio"))]
#[cfg(any(feature = "async-std", feature = "tokio", feature = "smol"))]
fn baseline_read_async(c: &mut Criterion) {
let tmp = tempfile::tempdir().unwrap();
let path = tmp.path().join("test_file");
Expand All @@ -75,7 +86,7 @@ fn baseline_read_async(c: &mut Criterion) {
});
}

#[cfg(any(feature = "async-std", feature = "tokio"))]
#[cfg(any(feature = "async-std", feature = "tokio", feature = "smol"))]
fn baseline_read_many_async(c: &mut Criterion) {
let tmp = tempfile::tempdir().unwrap();
let paths: Vec<_> = (0..)
Expand Down Expand Up @@ -190,7 +201,7 @@ fn read_hash_sync_big_data_xxh3(c: &mut Criterion) {
});
}

#[cfg(any(feature = "async-std", feature = "tokio"))]
#[cfg(any(feature = "async-std", feature = "tokio", feature = "smol"))]
fn read_hash_many_async(c: &mut Criterion) {
let tmp = tempfile::tempdir().unwrap();
let cache = tmp.path().to_owned();
Expand All @@ -212,7 +223,7 @@ fn read_hash_many_async(c: &mut Criterion) {
});
}

#[cfg(any(feature = "async-std", feature = "tokio"))]
#[cfg(any(feature = "async-std", feature = "tokio", feature = "smol"))]
fn read_hash_async(c: &mut Criterion) {
let tmp = tempfile::tempdir().unwrap();
let cache = tmp.path().to_owned();
Expand All @@ -223,7 +234,7 @@ fn read_hash_async(c: &mut Criterion) {
});
}

#[cfg(any(feature = "async-std", feature = "tokio"))]
#[cfg(any(feature = "async-std", feature = "tokio", feature = "smol"))]
fn read_async(c: &mut Criterion) {
let tmp = tempfile::tempdir().unwrap();
let cache = tmp.path().to_owned();
Expand All @@ -234,7 +245,7 @@ fn read_async(c: &mut Criterion) {
});
}

#[cfg(any(feature = "async-std", feature = "tokio"))]
#[cfg(any(feature = "async-std", feature = "tokio", feature = "smol"))]
fn read_hash_async_big_data(c: &mut Criterion) {
let tmp = tempfile::tempdir().unwrap();
let cache = tmp.path().to_owned();
Expand Down Expand Up @@ -278,7 +289,7 @@ fn write_hash_xxh3(c: &mut Criterion) {
});
}

#[cfg(any(feature = "async-std", feature = "tokio"))]
#[cfg(any(feature = "async-std", feature = "tokio", feature = "smol"))]
fn write_hash_async(c: &mut Criterion) {
let tmp = tempfile::tempdir().unwrap();
let cache = tmp.path().to_owned();
Expand All @@ -293,7 +304,7 @@ fn write_hash_async(c: &mut Criterion) {
});
}

#[cfg(any(feature = "async-std", feature = "tokio"))]
#[cfg(any(feature = "async-std", feature = "tokio", feature = "smol"))]
fn write_hash_async_xxh3(c: &mut Criterion) {
let tmp = tempfile::tempdir().unwrap();
let cache = tmp.path().to_owned();
Expand Down Expand Up @@ -325,7 +336,7 @@ fn create_tmpfile(tmp: &tempfile::TempDir, buf: &[u8]) -> PathBuf {
}

#[cfg(feature = "link_to")]
#[cfg(any(feature = "async-std", feature = "tokio"))]
#[cfg(any(feature = "async-std", feature = "tokio", feature = "smol"))]
fn link_to_async(c: &mut Criterion) {
let tmp = tempfile::tempdir().unwrap();
let target = create_tmpfile(&tmp, b"hello world");
Expand All @@ -348,7 +359,10 @@ fn link_to_async(c: &mut Criterion) {
});
}

#[cfg(all(feature = "link_to", any(feature = "async-std", feature = "tokio")))]
#[cfg(all(
feature = "link_to",
any(feature = "async-std", feature = "tokio", feature = "smol")
))]
fn link_to_hash_async(c: &mut Criterion) {
let tmp = tempfile::tempdir().unwrap();
let target = create_tmpfile(&tmp, b"hello world");
Expand Down Expand Up @@ -405,7 +419,7 @@ criterion_group!(
read_hash_sync_big_data_xxh3,
);

#[cfg(any(feature = "async-std", feature = "tokio"))]
#[cfg(any(feature = "async-std", feature = "tokio", feature = "smol"))]
criterion_group!(
benches_async,
baseline_read_async,
Expand All @@ -418,23 +432,29 @@ criterion_group!(
read_hash_async_big_data,
);

#[cfg(all(feature = "link_to", any(feature = "async-std", feature = "tokio")))]
#[cfg(all(
feature = "link_to",
any(feature = "async-std", feature = "tokio", feature = "smol")
))]
criterion_group!(link_to_benches_async, link_to_async, link_to_hash_async,);

#[cfg(feature = "link_to")]
criterion_group!(link_to_benches, link_to_sync, link_to_hash_sync);

#[cfg(all(
feature = "link_to",
not(any(feature = "async-std", feature = "tokio"))
not(any(feature = "async-std", feature = "tokio", feature = "smol"))
))]
criterion_main!(benches, link_to_benches);
#[cfg(all(
not(feature = "link_to"),
any(feature = "async-std", feature = "tokio")
any(feature = "async-std", feature = "tokio", feature = "smol")
))]
criterion_main!(benches, benches_async);
#[cfg(all(feature = "link_to", any(feature = "async-std", feature = "tokio")))]
#[cfg(all(
feature = "link_to",
any(feature = "async-std", feature = "tokio", feature = "smol")
))]
criterion_main!(
benches,
benches_async,
Expand All @@ -443,6 +463,6 @@ criterion_main!(
);
#[cfg(all(
not(feature = "link_to"),
not(any(feature = "async-std", feature = "tokio"))
not(any(feature = "async-std", feature = "tokio", feature = "smol"))
))]
criterion_main!(benches);
8 changes: 7 additions & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,32 @@
@help:
just -l

# Run tests on both runtimes with cargo nextest
# Run tests on all runtimes with cargo nextest
@test:
echo "----------\nasync-std:\n"
cargo nextest run
echo "\n----------\ntokio:\n"
cargo nextest run --no-default-features --features tokio-runtime
echo "\n----------\nsmol:\n"
cargo nextest run --no-default-features --features smol-runtime

# Run benchmarks with `cargo bench`
@bench:
echo "----------\nasync-std:\n"
cargo bench
echo "\n----------\ntokio:\n"
cargo bench --no-default-features --features tokio-runtime
echo "\n----------\nsmol:\n"
cargo bench --no-default-features --features smol-runtime

# Run benchmarks with `cargo criterion`
@criterion:
echo "----------\nasync-std:\n"
cargo criterion
echo "\n----------\ntokio:\n"
cargo criterion --no-default-features --features tokio-runtime
echo "\n----------\nsmol:\n"
cargo criterion --no-default-features --features smol-runtime

# Generate a changelog with git-cliff
changelog TAG:
Expand Down
58 changes: 58 additions & 0 deletions src/async_lib.rs
Original file line number Diff line number Diff line change
@@ -1,75 +1,105 @@
#[cfg(feature = "async-std")]
pub use async_std::fs::File;
#[cfg(feature = "smol")]
pub use smol::fs::File;
#[cfg(feature = "tokio")]
pub use tokio::fs::File;

#[cfg(feature = "async-std")]
pub use futures::io::AsyncRead;
#[cfg(feature = "smol")]
pub use futures::io::AsyncRead;
#[cfg(feature = "tokio")]
pub use tokio::io::AsyncRead;

#[cfg(feature = "async-std")]
pub use futures::io::AsyncReadExt;
#[cfg(feature = "smol")]
pub use futures::io::AsyncReadExt;
#[cfg(feature = "tokio")]
pub use tokio::io::AsyncReadExt;

#[cfg(feature = "async-std")]
pub use futures::io::AsyncBufReadExt;
#[cfg(feature = "smol")]
pub use futures::io::AsyncBufReadExt;
#[cfg(feature = "tokio")]
pub use tokio::io::AsyncBufReadExt;

#[cfg(feature = "async-std")]
pub use futures::io::AsyncWrite;
#[cfg(feature = "smol")]
pub use futures::io::AsyncWrite;
#[cfg(feature = "tokio")]
pub use tokio::io::AsyncWrite;

#[cfg(feature = "async-std")]
pub use futures::io::AsyncWriteExt;
#[cfg(feature = "smol")]
pub use futures::io::AsyncWriteExt;
#[cfg(feature = "tokio")]
pub use tokio::io::AsyncWriteExt;

#[cfg(feature = "async-std")]
pub use async_std::fs::read;
#[cfg(feature = "smol")]
pub use smol::fs::read;
#[cfg(feature = "tokio")]
pub use tokio::fs::read;

#[cfg(feature = "async-std")]
pub use async_std::fs::copy;
#[cfg(feature = "smol")]
pub use smol::fs::copy;
#[cfg(feature = "tokio")]
pub use tokio::fs::copy;

#[cfg(feature = "async-std")]
pub use async_std::fs::metadata;
#[cfg(feature = "smol")]
pub use smol::fs::metadata;
#[cfg(feature = "tokio")]
pub use tokio::fs::metadata;

#[cfg(feature = "async-std")]
pub use async_std::fs::remove_file;
#[cfg(feature = "smol")]
pub use smol::fs::remove_file;
#[cfg(feature = "tokio")]
pub use tokio::fs::remove_file;

#[cfg(feature = "async-std")]
pub use async_std::fs::create_dir_all;
#[cfg(feature = "smol")]
pub use smol::fs::create_dir_all;
#[cfg(feature = "tokio")]
pub use tokio::fs::create_dir_all;

#[cfg(feature = "async-std")]
pub use async_std::fs::remove_dir_all;
#[cfg(feature = "smol")]
pub use smol::fs::remove_dir_all;
#[cfg(feature = "tokio")]
pub use tokio::fs::remove_dir_all;

#[cfg(feature = "async-std")]
pub use async_std::fs::DirBuilder;
#[cfg(feature = "smol")]
pub use smol::fs::DirBuilder;
#[cfg(feature = "tokio")]
pub use tokio::fs::DirBuilder;

#[cfg(feature = "async-std")]
pub use async_std::fs::OpenOptions;
#[cfg(feature = "smol")]
pub use smol::fs::OpenOptions;
#[cfg(feature = "tokio")]
pub use tokio::fs::OpenOptions;

#[cfg(feature = "async-std")]
pub use async_std::io::BufReader;
#[cfg(feature = "smol")]
pub use futures::io::BufReader;
#[cfg(feature = "tokio")]
pub use tokio::io::BufReader;

Expand All @@ -83,9 +113,16 @@ pub fn lines_to_stream<R>(lines: futures::io::Lines<R>) -> futures::io::Lines<R>
pub fn lines_to_stream<R>(lines: tokio::io::Lines<R>) -> tokio_stream::wrappers::LinesStream<R> {
tokio_stream::wrappers::LinesStream::new(lines)
}
#[cfg(feature = "smol")]
#[inline]
pub fn lines_to_stream<R>(lines: futures::io::Lines<R>) -> futures::io::Lines<R> {
lines
}

#[cfg(feature = "async-std")]
pub use async_std::task::spawn_blocking;
#[cfg(feature = "smol")]
pub use smol::unblock as spawn_blocking;
#[cfg(feature = "tokio")]
pub use tokio::task::spawn_blocking;

Expand All @@ -103,6 +140,13 @@ pub use tokio::task::JoinHandle;
pub fn unwrap_joinhandle_value<T>(value: T) -> T {
value
}
#[cfg(feature = "smol")]
pub use smol::Task as JoinHandle;
#[cfg(feature = "smol")]
#[inline]
pub fn unwrap_joinhandle_value<T>(value: T) -> T {
value
}

use tempfile::NamedTempFile;

Expand Down Expand Up @@ -135,3 +179,17 @@ pub async fn create_named_tempfile(
_ => None,
}
}

#[cfg(feature = "smol")]
#[inline]
pub async fn create_named_tempfile(
tmp_path: std::path::PathBuf,
) -> Option<crate::Result<NamedTempFile>> {
let cloned = tmp_path.clone();

Some(
spawn_blocking(|| NamedTempFile::new_in(tmp_path))
.await
.with_context(|| format!("Failed to create a temp file at {}", cloned.display())),
)
}
Loading
Loading