Skip to content

Commit

Permalink
refactor: impl AsyncTTY
Browse files Browse the repository at this point in the history
move methods inside of AsyncTTY
  • Loading branch information
mrjackwills committed Apr 17, 2024
1 parent aa09474 commit bf33776
Showing 1 changed file with 36 additions and 35 deletions.
71 changes: 36 additions & 35 deletions src/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,43 +84,44 @@ pub fn tty_readable() -> bool {
.is_ok()
}

async fn tty_read_loop(mut f: File, tx: Sender<u8>, cancel_token: CancellationToken) {
loop {
let mut buf = [0];
if tokio::time::timeout(std::time::Duration::from_millis(10), f.read_exact(&mut buf))
.await
.is_ok()
&& tx.send(buf[0]).is_err()
{
cancel_token.cancel();
}
}

struct AsyncTTY {
rx: std::sync::mpsc::Receiver<u8>,
}
/// Async tty reading, spawned into its own tokio thread
/// This should be a cancel token
fn tty(cancel_token: &CancellationToken) -> Option<AsyncTTY> {
if tty_readable() {
let (tx, rx) = std::sync::mpsc::channel();
let cancel_token = cancel_token.to_owned();
tokio::spawn(async move {
if let Ok(f) = tokio::fs::File::open(TTY).await {
let c_1 = cancel_token.clone();
let c_2 = cancel_token.clone();

tokio::select! {
() = c_1.cancelled() => (),
() = tty_read_loop(f, tx, c_2) => (),
}

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 {
let mut buf = [0];
if tokio::time::timeout(std::time::Duration::from_millis(10), f.read_exact(&mut buf))
.await
.is_ok()
&& tx.send(buf[0]).is_err()
{
break;
}
});
Some(AsyncTTY { rx })
} else {
None
}
}
}

struct AsyncTTY {
rx: std::sync::mpsc::Receiver<u8>,
/// Async tty reading, spawned into its own tokio thread
fn get(cancel_token: &CancellationToken) -> Option<Self> {
if tty_readable() {
let (tx, rx) = std::sync::mpsc::channel();
let cancel_token = cancel_token.to_owned();
tokio::spawn(async move {
if let Ok(f) = tokio::fs::File::open(TTY).await {
tokio::select! {
() = cancel_token.cancelled() => (),
() = Self::read_loop(f, tx) => cancel_token.cancel(),
}
}
});
Some(Self { rx })
} else {
None
}
}
}

/// This is used to set the terminal size when exec via the Internal method
Expand Down Expand Up @@ -258,7 +259,7 @@ impl ExecMode {
)
.await
{
if let Some(async_tty) = tty(&cancel_token) {
if let Some(tty) = AsyncTTY::get(&cancel_token) {
tokio::spawn(async move {
enable_raw_mode().ok();
let mut stdout = std::io::stdout();
Expand All @@ -284,7 +285,7 @@ impl ExecMode {
.ok();
}

while let Ok(x) = async_tty.rx.recv() {
while let Ok(x) = tty.rx.recv() {
input.write_all(&[x]).await.ok();
}

Expand Down

0 comments on commit bf33776

Please sign in to comment.