https://github.com/lpenz/tokio-process-stream
Simple crate that wraps a tokio::process into a tokio::stream
https://github.com/lpenz/tokio-process-stream
async-stream process rust stream tokio
Last synced: about 1 year ago
JSON representation
Simple crate that wraps a tokio::process into a tokio::stream
- Host: GitHub
- URL: https://github.com/lpenz/tokio-process-stream
- Owner: lpenz
- License: mit
- Created: 2022-01-02T12:49:40.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2024-02-18T21:39:12.000Z (over 2 years ago)
- Last Synced: 2025-05-01T00:39:53.673Z (about 1 year ago)
- Topics: async-stream, process, rust, stream, tokio
- Language: Rust
- Homepage:
- Size: 19.5 KB
- Stars: 11
- Watchers: 2
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://github.com/lpenz/tokio-process-stream/actions/workflows/ci.yml)
[](https://coveralls.io/github/lpenz/tokio-process-stream?branch=main)
[](https://crates.io/crates/tokio-process-stream)
[](https://docs.rs/tokio-process-stream)
# tokio-process-stream
tokio-process-stream is a simple crate that wraps a [`tokio::process`] into a
[`tokio::stream`]
Having a stream interface to processes is useful when we have multiple sources of data that
we want to merge and start processing from a single entry point.
This crate provides a [`futures::stream::Stream`] wrapper for [`tokio::process::Child`]. The
main struct is [`ProcessLineStream`], which implements the trait, yielding one [`Item`] enum
at a time, each containing one line from either stdout ([`Item::Stdout`]) or stderr
([`Item::Stderr`]) of the underlying process until it exits. At this point, the stream
yields a single [`Item::Done`] and finishes.
Example usage:
```rust
use tokio_process_stream::ProcessLineStream;
use tokio::process::Command;
use tokio_stream::StreamExt;
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box> {
let mut sleep_cmd = Command::new("sleep");
sleep_cmd.args(&["1"]);
let ls_cmd = Command::new("ls");
let sleep_procstream = ProcessLineStream::try_from(sleep_cmd)?;
let ls_procstream = ProcessLineStream::try_from(ls_cmd)?;
let mut procstream = sleep_procstream.merge(ls_procstream);
while let Some(item) = procstream.next().await {
println!("{:?}", item);
}
Ok(())
}
```
## Streaming chunks
It is also possible to stream `Item` chunks with [`ProcessChunkStream`].
```rust
use tokio_process_stream::{Item, ProcessChunkStream};
use tokio::process::Command;
use tokio_stream::StreamExt;
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box> {
let mut procstream: ProcessChunkStream = Command::new("/bin/sh")
.arg("-c")
.arg(r#"printf "1/2"; sleep 0.1; printf "\r2/2 done\n""#)
.try_into()?;
while let Some(item) = procstream.next().await {
println!("{:?}", item);
}
Ok(())
}
```
[`tokio::process`]: https://docs.rs/tokio/latest/tokio/process
[`tokio::stream`]: https://docs.rs/futures-core/latest/futures_core/stream
[`futures::stream::Stream`]: https://docs.rs/futures-core/latest/futures_core/stream/trait.Stream.html
[`tokio::process::Child`]: https://docs.rs/tokio/latest/tokio/process/struct.Child.html
[`ProcessLineStream`]: https://docs.rs/tokio-process-stream/latest/tokio_process_stream/struct.ProcessLineStream.html
[`ProcessChunkStream`]: https://docs.rs/tokio-process-stream/latest/tokio_process_stream/struct.ProcessChunkStream.html
[`Item`]: https://docs.rs/tokio-process-stream/latest/tokio_process_stream/enum.Item.html
[`Item::Stdout`]: https://docs.rs/tokio-process-stream/latest/tokio_process_stream/enum.Item.html#variant.Stdout
[`Item::Stderr`]: https://docs.rs/tokio-process-stream/latest/tokio_process_stream/enum.Item.html#variant.Stderr
[`Item::Done`]: https://docs.rs/tokio-process-stream/latest/tokio_process_stream/enum.Item.html#variant.Done