serialport-stream 0.3.2

Async runtime-agnostic Stream and AsyncRead/AsyncWrite for serial ports using platform-specific I/O
Documentation
# serialport-stream-rs

Async serial port I/O as [`futures::Stream`](https://docs.rs/futures/latest/futures/stream/trait.Stream.html), [`AsyncRead`](https://docs.rs/futures/latest/futures/io/trait.AsyncRead.html), and [`AsyncWrite`](https://docs.rs/futures/latest/futures/io/trait.AsyncWrite.html). Uses POSIX termios on Unix and Win32 COMM APIs on Windows.

**Async runtime agnostic** — implements [`futures`](https://docs.rs/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

```toml
[dependencies]
serialport-stream = "0.3"
```

Optional diagnostic logs via the [`tracing`](https://docs.rs/tracing) crate:

```toml
serialport-stream = { version = "0.3", features = ["tracing"] }
```

Examples below also use `futures-lite` (blocking) or `tokio`.

## Usage

### Stream (blocking)

```rust
use serialport_stream::new;
use futures_lite::stream;

fn main() -> std::io::Result<()> {
    let stream = new("COM3", 115200).dtr_on_open(true).open()?;

    for chunk in stream::block_on(stream) {
        println!("{:?}", chunk?);
    }

    Ok(())
}
```

### Stream (Tokio)

```rust
use serialport_stream::{new, TryStreamExt};

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let mut stream = new("/dev/ttyUSB0", 9600).open()?;

    while let Some(bytes) = stream.try_next().await? {
        println!("Received: {bytes:?}");
    }

    Ok(())
}
```

### Reading

A background thread fills one in-memory FIFO. There is no backpressure; the buffer can grow without bound.

| 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 |

Use one read style per port. Mixing `Stream` and `AsyncRead` can split messages across calls.

[`AsyncReadExt`](https://docs.rs/futures/latest/futures/io/trait.AsyncReadExt.html) is re-exported (`read`, `read_to_end`, etc.). Example: `cargo run --example tokio_async_read -- /dev/ttyUSB0 115200`. Add `--features tracing` with `--trace` for diagnostic logs.

For `tokio::io::AsyncRead`, bridge with [`tokio_util::compat`](https://docs.rs/tokio-util/latest/tokio_util/compat/index.html) (`tokio-util` feature `compat`).

### Writing

[`AsyncWrite`](https://docs.rs/futures/latest/futures/io/trait.AsyncWrite.html) / [`AsyncWriteExt`](https://docs.rs/futures/latest/futures/io/trait.AsyncWriteExt.html) are re-exported.

```rust
use serialport_stream::{new, AsyncWriteExt, TryStreamExt};

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let mut stream = new("/dev/ttyUSB0", 115200).open()?;

    stream.write_all(b"PING\r\n").await?;
    stream.flush().await?;

    if let Some(reply) = stream.try_next().await? {
        println!("Received: {reply:?}");
    }

    Ok(())
}
```

Example: `cargo run --example tokio_async_rw -- /dev/ttyUSB0 115200`. Add `--features tracing` with `--trace` for diagnostic logs.

For `tokio::io::AsyncWrite`, use [`tokio_util::compat`](https://docs.rs/tokio-util/latest/tokio_util/compat/index.html) as above.

## Builder

Open with [`new(path, baud_rate)`](https://docs.rs/serialport-stream/latest/serialport_stream/fn.new.html), 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](https://github.com/serialport/serialport-rs).

## License

This project is licensed under either of:

- Apache License, Version 2.0 ([LICENSE-APACHE]LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT]LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.