From 39287b07f87aba15c4cb0f64d7008ba67289151d Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Tue, 22 Feb 2022 17:02:12 -0500 Subject: another rewrite --- examples/interhack.rs | 87 +++++++++++++++++++++------------------------------ 1 file changed, 35 insertions(+), 52 deletions(-) (limited to 'examples/interhack.rs') diff --git a/examples/interhack.rs b/examples/interhack.rs index 212c12e..5fe1474 100644 --- a/examples/interhack.rs +++ b/examples/interhack.rs @@ -2,68 +2,63 @@ mod raw_guard; #[cfg(feature = "async")] mod main { - use smol::io::{AsyncReadExt as _, AsyncWriteExt as _}; + use tokio::io::{AsyncReadExt as _, AsyncWriteExt as _}; pub async fn run( - child: &async_process::Child, - pty: &pty_process::Pty, + child: &mut tokio::process::Child, + pty: &mut pty_process::Pty, ) -> std::result::Result<(), Box> { let _raw = super::raw_guard::RawGuard::new(); - let mut input_pty = pty; - let mut output_pty = pty; - let ex = smol::Executor::new(); + let mut in_buf = [0_u8; 4096]; + let mut out_buf = [0_u8; 4096]; - let input = ex.spawn(async { - let mut buf = [0_u8; 4096]; - let mut stdin = smol::Unblock::new(std::io::stdin()); - loop { - match stdin.read(&mut buf).await { + let mut stdin = tokio::io::stdin(); + let mut stdout = tokio::io::stdout(); + + #[allow(clippy::trivial_regex)] + let re = regex::bytes::Regex::new("Elbereth").unwrap(); + + loop { + tokio::select! { + bytes = stdin.read(&mut in_buf) => match bytes { Ok(bytes) => { // engrave Elbereth with ^E - if buf[..bytes].contains(&5u8) { - for byte in buf[..bytes].iter() { + if in_buf[..bytes].contains(&5u8) { + for byte in in_buf[..bytes].iter() { match byte { - 5u8 => input_pty + 5u8 => pty .write_all(b"E- Elbereth\n") .await .unwrap(), - _ => input_pty + _ => pty .write_all(&[*byte]) .await .unwrap(), } } } else { - input_pty.write_all(&buf[..bytes]).await.unwrap(); + pty.write_all(&in_buf[..bytes]).await.unwrap(); } } Err(e) => { eprintln!("stdin read failed: {:?}", e); break; } - } - } - }); - let output = ex.spawn(async { - let mut buf = [0_u8; 4096]; - let mut stdout = smol::Unblock::new(std::io::stdout()); - #[allow(clippy::trivial_regex)] - let re = regex::bytes::Regex::new("Elbereth").unwrap(); - loop { - match output_pty.read(&mut buf).await { + }, + bytes = pty.read(&mut out_buf) => match bytes { Ok(bytes) => { // highlight successful Elbereths - if re.is_match(&buf[..bytes]) { + if re.is_match(&out_buf[..bytes]) { stdout .write_all(&re.replace_all( - &buf[..bytes], + &out_buf[..bytes], &b"\x1b[35m$0\x1b[m"[..], )) .await .unwrap(); } else { - stdout.write_all(&buf[..bytes]).await.unwrap(); + stdout.write_all(&out_buf[..bytes]).await.unwrap(); } stdout.flush().await.unwrap(); } @@ -71,38 +66,26 @@ mod main { eprintln!("pty read failed: {:?}", e); break; } - } + }, + _ = child.wait() => break, } - }); - - let wait = async { - child.status_no_drop().await.unwrap(); - }; - - ex.run(smol::future::or(smol::future::or(input, output), wait)) - .await; + } Ok(()) } } #[cfg(feature = "async")] -fn main() { +#[tokio::main] +async fn main() { use std::os::unix::process::ExitStatusExt as _; - let (w, h) = if let Some((w, h)) = term_size::dimensions() { - (w as u16, h as u16) - } else { - (80, 24) - }; - let status = smol::block_on(async { - let pty = pty_process::Pty::new().unwrap(); - pty.resize(pty_process::Size::new(h, w)).unwrap(); - let mut child = - pty_process::Command::new("nethack").spawn(&pty).unwrap(); - main::run(&child, &pty).await.unwrap(); - child.status().await.unwrap() - }); + let mut pty = pty_process::Pty::new().unwrap(); + let pts = pty.pts().unwrap(); + pty.resize(pty_process::Size::new(24, 80)).unwrap(); + let mut child = pty_process::Command::new("nethack").spawn(&pts).unwrap(); + main::run(&mut child, &mut pty).await.unwrap(); + let status = child.wait().await.unwrap(); std::process::exit( status .code() -- cgit v1.2.3-54-g00ecf