conpty 0.7.0

A library which provides an interface for ConPTY
Documentation
use std::{
    io::prelude::*,
    time::{Duration, Instant},
};

use conpty::io::PipeReader;

fn main() {
    let mut p = conpty::spawn(r#"cmd"#).unwrap();

    println!("Process PID={:?}", p.pid());

    let mut input = p.input().unwrap();
    let mut output = p.output().unwrap();
    output.blocking(false);

    println!("{:?}", wait_for(&mut output, "All rights reserved"));

    input
        .write_all("echo \"This is a test string 😁\"\r\n".as_bytes())
        .unwrap();

    println!("{:?}", wait_for(&mut output, "😁"));

    input.write_all(b"powershell\r\n").unwrap();

    println!("{:?}", wait_for(&mut output, "https://aka.ms/PSWindows"));

    input.write_all(b"cat examples/cat.rs\r\n").unwrap();

    println!("{:?}", wait_for(&mut output, "main"));
}

fn wait_for(output: &mut PipeReader, s: &str) -> String {
    let treashhold = Duration::from_secs(2);
    let now = Instant::now();

    let mut out = vec![0; 1000];
    let mut buf = String::new();
    loop {
        try_read(output, &mut out, &mut buf);
        if buf.contains(s) {
            return buf;
        }

        if now.elapsed() > treashhold {
            panic!("TIMEOUT REACHED")
        }
    }
}

fn try_read(o: &mut PipeReader, out: &mut Vec<u8>, buf: &mut String) {
    match o.read(out) {
        Ok(n) => {
            let s = String::from_utf8_lossy(&out[..n]);
            buf.push_str(&s);
        }
        Err(err) => {
            if err.kind() == std::io::ErrorKind::WouldBlock {
                return;
            }

            panic!("{:?}", err);
        }
    }
}