refactor: impl AsyncTTY

move methods inside of AsyncTTY
This commit is contained in:
Jack Wills
2024-04-17 21:14:28 +00:00
parent aa09474053
commit bf33776e9a
+19 -18
View File
@@ -84,7 +84,14 @@ pub fn tty_readable() -> bool {
.is_ok() .is_ok()
} }
async fn tty_read_loop(mut f: File, tx: Sender<u8>, cancel_token: CancellationToken) {
struct AsyncTTY {
rx: std::sync::mpsc::Receiver<u8>,
}
impl AsyncTTY {
/// Use an async timeout to read data from the file, and send to the "main" thread
async fn read_loop(mut f: File, tx: Sender<u8>) {
loop { loop {
let mut buf = [0]; let mut buf = [0];
if tokio::time::timeout(std::time::Duration::from_millis(10), f.read_exact(&mut buf)) if tokio::time::timeout(std::time::Duration::from_millis(10), f.read_exact(&mut buf))
@@ -92,35 +99,29 @@ async fn tty_read_loop(mut f: File, tx: Sender<u8>, cancel_token: CancellationTo
.is_ok() .is_ok()
&& tx.send(buf[0]).is_err() && tx.send(buf[0]).is_err()
{ {
cancel_token.cancel(); break;
} }
} }
} }
/// Async tty reading, spawned into its own tokio thread
/// This should be a cancel token /// Async tty reading, spawned into its own tokio thread
fn tty(cancel_token: &CancellationToken) -> Option<AsyncTTY> { fn get(cancel_token: &CancellationToken) -> Option<Self> {
if tty_readable() { if tty_readable() {
let (tx, rx) = std::sync::mpsc::channel(); let (tx, rx) = std::sync::mpsc::channel();
let cancel_token = cancel_token.to_owned(); let cancel_token = cancel_token.to_owned();
tokio::spawn(async move { tokio::spawn(async move {
if let Ok(f) = tokio::fs::File::open(TTY).await { if let Ok(f) = tokio::fs::File::open(TTY).await {
let c_1 = cancel_token.clone();
let c_2 = cancel_token.clone();
tokio::select! { tokio::select! {
() = c_1.cancelled() => (), () = cancel_token.cancelled() => (),
() = tty_read_loop(f, tx, c_2) => (), () = Self::read_loop(f, tx) => cancel_token.cancel(),
} }
} }
}); });
Some(AsyncTTY { rx }) Some(Self { rx })
} else { } else {
None None
} }
} }
struct AsyncTTY {
rx: std::sync::mpsc::Receiver<u8>,
} }
/// This is used to set the terminal size when exec via the Internal method /// This is used to set the terminal size when exec via the Internal method
@@ -258,7 +259,7 @@ impl ExecMode {
) )
.await .await
{ {
if let Some(async_tty) = tty(&cancel_token) { if let Some(tty) = AsyncTTY::get(&cancel_token) {
tokio::spawn(async move { tokio::spawn(async move {
enable_raw_mode().ok(); enable_raw_mode().ok();
let mut stdout = std::io::stdout(); let mut stdout = std::io::stdout();
@@ -284,7 +285,7 @@ impl ExecMode {
.ok(); .ok();
} }
while let Ok(x) = async_tty.rx.recv() { while let Ok(x) = tty.rx.recv() {
input.write_all(&[x]).await.ok(); input.write_all(&[x]).await.ok();
} }