serialport-stream-rs
Async serial port I/O as futures::AsyncRead and AsyncWrite, with optional Stream support. Uses POSIX termios on Unix and Win32 COMM APIs on Windows.
Async runtime agnostic — implements futures traits only; no Tokio/async-std dependency. Works with any executor that polls those futures (Tokio, async-std, futures_lite::future::block_on, etc.).
Installation
[]
= "0.4"
Optional features:
# Stream / try_next — background receive FIFO pump (Unix and Windows)
= { = "0.4", = ["stream"] }
# Diagnostic logs (EAGAIN retries, receive-buffer diagnostics)
= { = "0.4", = ["tracing"] }
Examples below also use futures-lite (blocking) or tokio.
Read behavior
| Platform | AsyncRead |
Stream / try_next (stream feature) |
|---|---|---|
| Unix | Direct async-io poll on the port |
Poll-based background read thread → FIFO |
| Windows | Overlapped ReadFile + windows thread-pool |
WaitCommEvent background read thread → FIFO |
With the stream feature, AsyncRead also reads from the FIFO. Do not mix Stream / try_next and AsyncRead on the same port — that can split messages across calls.
| API | Each call returns |
|---|---|
Stream / try_next |
All bytes in the FIFO (buffer drained) |
AsyncRead |
Up to your buffer length; remainder stays in the FIFO |
There is no backpressure on FIFO paths; the buffer can grow without bound.
Write behavior
| Platform | AsyncWrite |
|---|---|
| Unix | Direct async-io poll on the port |
| Windows | Overlapped WriteFile + windows thread-pool |
Usage
AsyncRead (default)
Works without extra features. Preferred path on both platforms.
use ;
async
Example: cargo run --example tokio_async_read -- /dev/ttyUSB0 115200
Add --features tracing and pass --trace in examples that support it for diagnostic logs.
For tokio::io::AsyncRead, bridge with tokio_util::compat (tokio-util feature compat).
Stream (stream feature)
Requires features = ["stream"].
Blocking (futures_lite::stream::block_on):
use new;
use stream;
Example: cargo run --example read_stream --features stream -- COM3 115200
Tokio:
use ;
async
Example: cargo run --example tokio_read_stream --features stream -- /dev/ttyUSB0 115200
Writing
AsyncWriteExt is re-exported. On Unix, writes use async-io; on Windows, overlapped WriteFile with a windows thread-pool completion.
use ;
async
Read + write example (AsyncRead + AsyncWrite, no extra features): cargo run --example tokio_async_rw -- /dev/ttyUSB0 115200
For tokio::io::AsyncWrite, use tokio_util::compat as above.
Builder
Open with new(path, baud_rate), then chain options and call .open():
.data_bits,.parity,.stop_bits,.flow_control— default is 8N1, no flow control.dtr_on_open(bool)— drive DTR on open.clear(ClearBuffer::Input | Output | All)— purge driver buffers at open
Types DataBits, Parity, StopBits, FlowControl, and ClearBuffer are exported from serialport_stream.
Acknowledgements
Some of the platform I/O code is inspired by serialport-rs.
License
This project is licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.