Skip to content

Commit

Permalink
Implement Read, Write directly on TTY
Browse files Browse the repository at this point in the history
  • Loading branch information
bash committed Jan 17, 2024
1 parent e8b10e7 commit 16817bd
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 17 deletions.
33 changes: 20 additions & 13 deletions src/os/unix/tty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use std::fs::{File, OpenOptions};
use std::io;
use std::io::{stderr, stdin, stdout, StderrLock, StdinLock, StdoutLock};
use std::mem::ManuallyDrop;
use std::ops::{Deref, DerefMut};
use std::os::fd::{AsRawFd, FromRawFd, RawFd};

macro_rules! try_tty {
Expand Down Expand Up @@ -49,28 +48,36 @@ pub(crate) enum TtyLock {
Stderr(StderrLock<'static>),
}

impl Deref for Tty {
type Target = File;
impl io::Write for Tty {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.as_file_mut().write(buf)
}

fn deref(&self) -> &Self::Target {
match self {
Tty::Owned(file) => file,
Tty::Borrowed(_, file) => file,
}
fn flush(&mut self) -> io::Result<()> {
self.as_file_mut().flush()
}
}

impl io::Read for Tty {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.as_file_mut().read(buf)
}
}

impl DerefMut for Tty {
fn deref_mut(&mut self) -> &mut Self::Target {
impl Tty {
fn as_file_mut(&mut self) -> &mut File {
match self {
Tty::Owned(file) => file,
Tty::Borrowed(_, file) => file,
Tty::Owned(f) => f,
Tty::Borrowed(_, f) => f,
}
}
}

impl AsRawFd for Tty {
fn as_raw_fd(&self) -> RawFd {
self.deref().as_raw_fd()
match self {
Tty::Owned(f) => f.as_raw_fd(),
Tty::Borrowed(_, f) => f.as_raw_fd(),
}
}
}
7 changes: 3 additions & 4 deletions src/xterm.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use crate::os::{poll_read, run_in_raw_mode, tty};
use crate::os::{poll_read, run_in_raw_mode, tty, Tty};
use crate::terminal::TerminalKind;
use crate::{Color, Error, Result};
use std::cmp::{max, min};
use std::fs::File;
use std::io::{Read, Write as _};
use std::os::fd::AsRawFd;
use std::str::from_utf8;
Expand Down Expand Up @@ -55,13 +54,13 @@ fn query_color_raw(q: &str, terminal: TerminalKind) -> Result<String> {
})
}

fn estimate_timeout(tty: &mut File) -> Result<Duration> {
fn estimate_timeout(tty: &mut Tty) -> Result<Duration> {
let (_, latency) = query(tty, "\x1b[c", MAX_TIMEOUT)?;
let timeout = latency * 2; // We want to be in the same ballpark as the latency of our test query. Factor 2 is mostly arbitrary.
Ok(min(max(timeout, MIN_TIMEOUT), MAX_TIMEOUT))
}

fn query(tty: &mut File, query: &str, timeout: Duration) -> Result<(String, Duration)> {
fn query(tty: &mut Tty, query: &str, timeout: Duration) -> Result<(String, Duration)> {
let mut buffer = vec![0; 100];

write!(tty, "{}", query)?;
Expand Down

0 comments on commit 16817bd

Please sign in to comment.