echoes 0.10.2

Find duplicated Rust doctests, functions and contexts
Documentation
use std::path::Path;
use std::process::{Child, Command, Output, Stdio};
use std::sync::atomic::{AtomicU64, Ordering};
use std::thread;
use std::time::{Duration, Instant};

static REQUEST: AtomicU64 = AtomicU64::new(0);

struct Process(Child);

impl Drop for Process {
    fn drop(&mut self) {
        let _ = self.0.kill();
        let started = Instant::now();
        while started.elapsed() < Duration::from_secs(5) {
            if !matches!(self.0.try_wait(), Ok(None)) {
                return;
            }
            thread::sleep(Duration::from_millis(10));
        }
    }
}

pub(super) fn run_cli(root: &Path, args: &[&str]) -> Output {
    let id = format!(
        "echoes.test.{}-{}",
        std::process::id(),
        REQUEST.fetch_add(1, Ordering::Relaxed)
    );
    let deadline = Instant::now() + Duration::from_secs(120);
    let capture = tempfile::tempdir().unwrap();
    let stdout = capture.path().join(format!("{id}.stdout"));
    let stderr = capture.path().join(format!("{id}.stderr"));
    let mut process = Process(
        Command::new(env!("CARGO_BIN_EXE_cargo-echoes"))
            .current_dir(root)
            .args(args)
            .env("ECHOES_TEST_REQUEST", &id)
            .stdin(Stdio::null())
            .stdout(std::fs::File::create(&stdout).unwrap())
            .stderr(std::fs::File::create(&stderr).unwrap())
            .spawn()
            .unwrap_or_else(|error| panic!("{id} spawn failed {error}")),
    );
    loop {
        match process.0.try_wait() {
            Ok(Some(status)) => {
                return Output {
                    status,
                    stdout: std::fs::read(stdout).unwrap(),
                    stderr: std::fs::read(stderr).unwrap(),
                };
            }
            Ok(None) if Instant::now() < deadline => thread::sleep(Duration::from_millis(10)),
            Ok(None) => panic!("{id} CLI deadline expired"),
            Err(error) => panic!("{id} wait failed {error}"),
        }
    }
}