{"id":21034669,"url":"https://github.com/lpenz/tokio-process-stream","last_synced_at":"2025-05-15T13:33:00.019Z","repository":{"id":41507954,"uuid":"443764538","full_name":"lpenz/tokio-process-stream","owner":"lpenz","description":"Simple crate that wraps a tokio::process into a tokio::stream","archived":false,"fork":false,"pushed_at":"2024-02-18T21:39:12.000Z","size":20,"stargazers_count":11,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-01T00:39:53.673Z","etag":null,"topics":["async-stream","process","rust","stream","tokio"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lpenz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-01-02T12:49:40.000Z","updated_at":"2025-04-08T07:20:09.000Z","dependencies_parsed_at":"2024-02-18T12:21:39.478Z","dependency_job_id":"d3adedbb-ba56-4e63-badb-a46e10ab7860","html_url":"https://github.com/lpenz/tokio-process-stream","commit_stats":{"total_commits":17,"total_committers":3,"mean_commits":5.666666666666667,"dds":"0.11764705882352944","last_synced_commit":"1047b89945045662795635057c6fec0048df969f"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lpenz%2Ftokio-process-stream","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lpenz%2Ftokio-process-stream/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lpenz%2Ftokio-process-stream/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lpenz%2Ftokio-process-stream/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lpenz","download_url":"https://codeload.github.com/lpenz/tokio-process-stream/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254349640,"owners_count":22056388,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async-stream","process","rust","stream","tokio"],"created_at":"2024-11-19T13:07:56.794Z","updated_at":"2025-05-15T13:32:59.959Z","avatar_url":"https://github.com/lpenz.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"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)\n[![coveralls](https://coveralls.io/repos/github/lpenz/tokio-process-stream/badge.svg?branch=main)](https://coveralls.io/github/lpenz/tokio-process-stream?branch=main)\n[![crates.io](https://img.shields.io/crates/v/tokio-process-stream)](https://crates.io/crates/tokio-process-stream)\n[![doc.rs](https://docs.rs/tokio-process-stream/badge.svg)](https://docs.rs/tokio-process-stream)\n\n# tokio-process-stream\n\ntokio-process-stream is a simple crate that wraps a [`tokio::process`] into a\n[`tokio::stream`]\n\nHaving a stream interface to processes is useful when we have multiple sources of data that\nwe want to merge and start processing from a single entry point.\n\nThis crate provides a [`futures::stream::Stream`] wrapper for [`tokio::process::Child`]. The\nmain struct is [`ProcessLineStream`], which implements the trait, yielding one [`Item`] enum\nat a time, each containing one line from either stdout ([`Item::Stdout`]) or stderr\n([`Item::Stderr`]) of the underlying process until it exits. At this point, the stream\nyields a single [`Item::Done`] and finishes.\n\nExample usage:\n\n```rust\nuse tokio_process_stream::ProcessLineStream;\nuse tokio::process::Command;\nuse tokio_stream::StreamExt;\nuse std::error::Error;\n\n#[tokio::main]\nasync fn main() -\u003e Result\u003c(), Box\u003cdyn Error\u003e\u003e {\n    let mut sleep_cmd = Command::new(\"sleep\");\n    sleep_cmd.args(\u0026[\"1\"]);\n    let ls_cmd = Command::new(\"ls\");\n\n    let sleep_procstream = ProcessLineStream::try_from(sleep_cmd)?;\n    let ls_procstream = ProcessLineStream::try_from(ls_cmd)?;\n    let mut procstream = sleep_procstream.merge(ls_procstream);\n\n    while let Some(item) = procstream.next().await {\n        println!(\"{:?}\", item);\n    }\n\n    Ok(())\n}\n```\n\n## Streaming chunks\n\nIt is also possible to stream `Item\u003cBytes\u003e` chunks with [`ProcessChunkStream`].\n\n```rust\nuse tokio_process_stream::{Item, ProcessChunkStream};\nuse tokio::process::Command;\nuse tokio_stream::StreamExt;\nuse std::error::Error;\n\n#[tokio::main]\nasync fn main() -\u003e Result\u003c(), Box\u003cdyn Error\u003e\u003e {\n    let mut procstream: ProcessChunkStream = Command::new(\"/bin/sh\")\n        .arg(\"-c\")\n        .arg(r#\"printf \"1/2\"; sleep 0.1; printf \"\\r2/2 done\\n\"\"#)\n        .try_into()?;\n\n    while let Some(item) = procstream.next().await {\n        println!(\"{:?}\", item);\n    }\n    Ok(())\n}\n```\n\n[`tokio::process`]: https://docs.rs/tokio/latest/tokio/process\n[`tokio::stream`]: https://docs.rs/futures-core/latest/futures_core/stream\n[`futures::stream::Stream`]: https://docs.rs/futures-core/latest/futures_core/stream/trait.Stream.html\n[`tokio::process::Child`]: https://docs.rs/tokio/latest/tokio/process/struct.Child.html\n[`ProcessLineStream`]: https://docs.rs/tokio-process-stream/latest/tokio_process_stream/struct.ProcessLineStream.html\n[`ProcessChunkStream`]: https://docs.rs/tokio-process-stream/latest/tokio_process_stream/struct.ProcessChunkStream.html\n[`Item`]: https://docs.rs/tokio-process-stream/latest/tokio_process_stream/enum.Item.html\n[`Item::Stdout`]: https://docs.rs/tokio-process-stream/latest/tokio_process_stream/enum.Item.html#variant.Stdout\n[`Item::Stderr`]: https://docs.rs/tokio-process-stream/latest/tokio_process_stream/enum.Item.html#variant.Stderr\n[`Item::Done`]: https://docs.rs/tokio-process-stream/latest/tokio_process_stream/enum.Item.html#variant.Done\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flpenz%2Ftokio-process-stream","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flpenz%2Ftokio-process-stream","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flpenz%2Ftokio-process-stream/lists"}