4 releases (breaking)
| 0.4.0 | Feb 13, 2026 |
|---|---|
| 0.3.0 | Feb 13, 2026 |
| 0.2.0 | Feb 13, 2026 |
| 0.1.0 | Feb 13, 2026 |
#864 in Asynchronous
37KB
655 lines
randomio
Async random-access I/O traits for Rust The
AsyncWrite/AsyncReadequivalent forwrite_at/read_at.
randomio provides minimal, zero-cost capability traits for writing and reading bytes at arbitrary offsets.
If you have ever needed:
- async
pwrite/pread - write chunks out-of-order
- download pieces into a sparse file
- persist blocks to disk/object storage
- build a WAL or chunk assembler
this crate provides the missing primitive.
Why randomio?
Rust has:
- sequential →
AsyncWrite - sequential →
AsyncRead
But there is no standard trait for random-access async I/O.
randomio fills that gap:
AsyncWrite → sequential only
AsyncRandomWrite → offset-based writes (this crate)
Quick Example
use randomio::AsyncRandomWrite;
use std::pin::Pin;
use std::task::{Context, Poll};
fn write_block<W: AsyncRandomWrite>(
writer: Pin<&mut W>,
cx: &mut Context<'_>,
) -> Poll<std::io::Result<()>> {
// write "hello" at byte offset 4096
writer.poll_write_at(cx, 4096, b"hello")
}
Works for:
- files
- block devices
- object storage
- memory backends
- io_uring
- network storage
- WASM
What this crate provides
Core types
| Type | Description |
|---|---|
Range |
Half-open byte interval [start, end) |
Block<B> |
Data block at an offset with generic buffer |
Core traits
AsyncRandomWrite
pub trait AsyncRandomWrite: Send {
fn poll_write_at(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
offset: u64,
buf: &[u8],
) -> Poll<std::io::Result<()>>;
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>>;
fn poll_sync(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>>;
}
AsyncRandomRead
pub trait AsyncRandomRead: Send {
fn poll_read_at(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
offset: u64,
buf: &mut [u8],
) -> Poll<std::io::Result<()>>;
}
Design principles
- Zero policy – no buffering, batching, or scheduling
- Zero-cost abstraction – no allocation, no
async_trait, no dynamic dispatch - Device agnostic – files, block devices, object stores, io_uring, WASM
- Capability, not runtime – describes what a backend can do, not how to use it
This crate is intentionally tiny and stable.
What this crate does NOT provide
These belong in higher-level runtimes:
- ❌ buffering / batching
- ❌ scheduling
- ❌ ordering guarantees
- ❌ durability tracking
- ❌ Sink/Stream adapters
- ❌ ingestion pipelines
Stability
When randomio reaches 1.0, the following are permanently frozen:
RangeBlockAsyncRandomWriteAsyncRandomRead- all method signatures
Only additive changes are allowed in 1.x.
Testing
randomio includes comprehensive test coverage:
- Unit tests for all core types and traits
- Property-based tests for edge cases
- Fuzz testing with production-grade targets
- write_model: Verifies correct offset writes
- read_write_consistency: Tests write_at → read_at consistency
- cancellation: Async cancellation safety
- overlap: Deterministic overlapping writes
Run tests:
cargo test
# Run with sanitizers
RUSTFLAGS="-Zsanitizer=address" cargo test
# Run fuzz tests (requires cargo-fuzz)
cargo install cargo-fuzz
for target in write_model read_write_consistency cancellation overlap; do
cargo fuzz run $target -- -max_total_time=10
done
License
This project is licensed under either of:
at your option.
Dependencies
~195KB