aboutsummaryrefslogtreecommitdiffstats
path: root/src/term.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/term.rs')
-rw-r--r--src/term.rs55
1 files changed, 24 insertions, 31 deletions
diff --git a/src/term.rs b/src/term.rs
index c4319b4..c23dc4e 100644
--- a/src/term.rs
+++ b/src/term.rs
@@ -1,32 +1,36 @@
use libc::{termios, winsize};
+use std::error::Error;
use std::io::{Read, Stdin};
-pub fn size() -> Option<winsize> {
+pub fn size() -> Result<winsize, Box<dyn Error>> {
unsafe {
let mut window: winsize = std::mem::zeroed();
- if libc::ioctl(1, libc::TIOCGWINSZ, &mut window) < 0 {
- return None;
+ let status = libc::ioctl(1, libc::TIOCGWINSZ, &mut window);
+ if status < 0 {
+ return Err(Box::from(format!("terminal size: ioctl failed with code {}", status)));
}
- return Some(window);
+ return Ok(window);
}
}
-fn get_attr() -> Option<termios> {
+fn get_attr() -> Result<termios, Box<dyn Error>> {
unsafe {
let mut attr: termios = std::mem::zeroed();
- if libc::tcgetattr(1, &mut attr) < 0 {
- return None;
+ let status = libc::tcgetattr(1, &mut attr);
+ if status < 0 {
+ return Err(Box::from(format!("tcgetattr failed with code {}", status)));
}
- return Some(attr);
+ return Ok(attr);
}
}
-fn set_attr(attrs: &termios) -> Option<()> {
+fn set_attr(attrs: &termios) -> Result<(), Box<dyn Error>> {
unsafe {
- if libc::tcsetattr(1, libc::TCSANOW, attrs) < 0 {
- return None;
+ let status = libc::tcsetattr(1, libc::TCSANOW, attrs);
+ if status < 0 {
+ return Err(Box::from(format!("set attributes: code {}", status)));
}
- return Some(());
+ return Ok(());
}
}
@@ -44,21 +48,14 @@ pub struct RawHandle {
impl Drop for RawHandle {
fn drop(&mut self) {
- set_attr(&self.old);
+ let _ = set_attr(&self.old);
}
}
-pub fn raw() -> Option<RawHandle> {
- let old = match get_attr() {
- Some(old) => old,
- None => {
- return None;
- }
- };
- if let None = set_attr(&make_raw()) {
- return None;
- }
- return Some(RawHandle { old: old });
+pub fn raw() -> Result<RawHandle, Box<dyn Error>> {
+ let old = get_attr()?;
+ set_attr(&make_raw())?;
+ return Ok(RawHandle { old: old });
}
pub enum Key {
@@ -71,16 +68,14 @@ pub enum Key {
Char(u8),
}
-pub fn read_key(stdin: &mut Stdin) -> Result<Key, String> {
+pub fn read_key(stdin: &mut Stdin) -> Result<Key, Box<dyn Error>> {
const CTRL_Q: u8 = 17;
const CTRL_S: u8 = 19;
const ESC: u8 = 27;
loop {
let mut buf = vec![0; 1];
- if let Err(err) = stdin.read_exact(&mut buf) {
- return Err(format!("read input: {}", err));
- }
+ stdin.read_exact(&mut buf)?;
if buf[0] == CTRL_Q {
return Ok(Key::CtrlQ);
}
@@ -92,9 +87,7 @@ pub fn read_key(stdin: &mut Stdin) -> Result<Key, String> {
}
// Try to handle an escape sequence.
let mut buf = vec![0; 2];
- if let Err(err) = stdin.read_exact(&mut buf) {
- return Err(format!("read input: {}", err));
- }
+ stdin.read_exact(&mut buf)?;
if buf[0] != b'[' {
// Unknown escape sequence, just read another key.
continue;