diff options
| author | Rose Hogenson <rosehogenson@posteo.net> | 2024-01-06 11:14:24 -0800 |
|---|---|---|
| committer | Rose Hogenson <rosehogenson@posteo.net> | 2024-01-06 11:14:24 -0800 |
| commit | b5f471c6a5c517605aa0c53738d4e916579ede78 (patch) | |
| tree | e227878c26fb2423aebe89ee7653e7aa859e9f93 /src/term.rs | |
| parent | dbb1ba202bb5803af1b580b588e7aeef0c6f7e31 (diff) | |
| download | editor-b5f471c6a5c517605aa0c53738d4e916579ede78.tar.zst | |
Use more idiomatic error handling.
Diffstat (limited to 'src/term.rs')
| -rw-r--r-- | src/term.rs | 55 |
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; |
