#![allow(clippy::wildcard_imports)]
use std::time::Duration;
use tokio::process::Command;
use tokio_process_tools::*;
#[derive(Debug, Default)]
struct ChunkStats {
bytes: usize,
chunks: usize,
gaps: usize,
}
impl StreamVisitor for ChunkStats {
type Output = Self;
fn on_chunk(&mut self, chunk: Chunk) -> Next {
self.bytes += chunk.as_ref().len();
self.chunks += 1;
Next::Continue
}
fn on_gap(&mut self) {
self.gaps += 1;
}
fn into_output(self) -> Self::Output {
self
}
}
#[tokio::main]
async fn main() {
let mut process = Process::new(Command::new("ls"))
.name(AutoName::program_only())
.stdout_and_stderr(|stream| {
stream
.single_subscriber()
.lossy_without_backpressure()
.replay_last_bytes(1.megabytes())
.read_chunk_size(DEFAULT_READ_CHUNK_SIZE)
.max_buffered_chunks(DEFAULT_MAX_BUFFERED_CHUNKS)
})
.spawn()
.expect("failed to spawn command");
let counter = process
.stdout()
.consume(ChunkStats::default())
.expect("no other consumer is attached yet");
let _status = process
.wait_for_completion(Duration::from_secs(30))
.await
.unwrap()
.expect_completed("process should complete");
let stats = counter.wait().await.unwrap();
println!(
"stdout: {} bytes across {} chunks ({} gaps)",
stats.bytes, stats.chunks, stats.gaps,
);
}