An open API service indexing awesome lists of open source software.

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

Awesome Lists containing this project

README

          

[![CI](https://github.com/lpenz/tokio-process-stream/actions/workflows/ci.yml/badge.svg)](https://github.com/lpenz/tokio-process-stream/actions/workflows/ci.yml)
[![coveralls](https://coveralls.io/repos/github/lpenz/tokio-process-stream/badge.svg?branch=main)](https://coveralls.io/github/lpenz/tokio-process-stream?branch=main)
[![crates.io](https://img.shields.io/crates/v/tokio-process-stream)](https://crates.io/crates/tokio-process-stream)
[![doc.rs](https://docs.rs/tokio-process-stream/badge.svg)](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