aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml1
-rw-r--r--examples/async.rs2
-rw-r--r--src/blocking/input.rs25
-rw-r--r--src/blocking/output.rs14
-rw-r--r--src/error.rs10
-rw-r--r--src/input.rs27
-rw-r--r--src/lib.rs2
-rw-r--r--src/output.rs14
8 files changed, 55 insertions, 40 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 0ce270f..6fced2f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,6 +8,7 @@ edition = "2018"
itoa = "0.4"
nix = "0.20"
terminal_size = "0.1"
+thiserror = "1.0"
vt100 = "0.12"
blocking = { version = "1.0", optional = true }
diff --git a/examples/async.rs b/examples/async.rs
index af5ccb5..3ff4c92 100644
--- a/examples/async.rs
+++ b/examples/async.rs
@@ -1,6 +1,6 @@
use textmode::Textmode as _;
-async fn run(tm: &mut textmode::Output) -> std::io::Result<()> {
+async fn run(tm: &mut textmode::Output) -> textmode::Result<()> {
tm.move_to(5, 5);
tm.write_str("foo");
smol::Timer::after(std::time::Duration::from_secs(2)).await;
diff --git a/src/blocking/input.rs b/src/blocking/input.rs
index 716cfca..ff69eda 100644
--- a/src/blocking/input.rs
+++ b/src/blocking/input.rs
@@ -1,3 +1,5 @@
+use crate::error::*;
+
use std::io::Read as _;
pub struct Input {
@@ -49,7 +51,7 @@ impl Input {
self.parse_single = parse;
}
- pub fn read_key(&mut self) -> std::io::Result<Option<crate::Key>> {
+ pub fn read_key(&mut self) -> Result<Option<crate::Key>> {
if self.parse_single {
self.read_single_key()
} else {
@@ -105,7 +107,7 @@ impl Input {
}
}
- fn read_single_key(&mut self) -> std::io::Result<Option<crate::Key>> {
+ fn read_single_key(&mut self) -> Result<Option<crate::Key>> {
match self.getc(true)? {
Some(0) => Ok(Some(crate::Key::Byte(0))),
Some(c @ 1..=26) => {
@@ -148,9 +150,7 @@ impl Input {
}
}
- fn read_escape_sequence(
- &mut self,
- ) -> std::io::Result<Option<crate::Key>> {
+ fn read_escape_sequence(&mut self) -> Result<Option<crate::Key>> {
let mut seen = vec![b'\x1b'];
macro_rules! fail {
@@ -259,10 +259,7 @@ impl Input {
}
}
- fn read_utf8_char(
- &mut self,
- initial: u8,
- ) -> std::io::Result<Option<crate::Key>> {
+ fn read_utf8_char(&mut self, initial: u8) -> Result<Option<crate::Key>> {
let mut buf = vec![initial];
macro_rules! fail {
@@ -314,7 +311,7 @@ impl Input {
}
}
- fn getc(&mut self, fill: bool) -> std::io::Result<Option<u8>> {
+ fn getc(&mut self, fill: bool) -> Result<Option<u8>> {
if fill {
if !self.maybe_fill_buf()? {
return Ok(None);
@@ -338,7 +335,7 @@ impl Input {
}
}
- fn maybe_fill_buf(&mut self) -> std::io::Result<bool> {
+ fn maybe_fill_buf(&mut self) -> Result<bool> {
if self.buf_is_empty() {
self.fill_buf()
} else {
@@ -350,7 +347,7 @@ impl Input {
self.pos >= self.buf.len()
}
- fn fill_buf(&mut self) -> std::io::Result<bool> {
+ fn fill_buf(&mut self) -> Result<bool> {
self.buf.resize(4096, 0);
self.pos = 0;
let bytes = read_stdin(&mut self.buf)?;
@@ -362,6 +359,6 @@ impl Input {
}
}
-fn read_stdin(buf: &mut [u8]) -> std::io::Result<usize> {
- std::io::stdin().read(buf)
+fn read_stdin(buf: &mut [u8]) -> Result<usize> {
+ std::io::stdin().read(buf).map_err(Error::ReadStdin)
}
diff --git a/src/blocking/output.rs b/src/blocking/output.rs
index 3049cac..fa21617 100644
--- a/src/blocking/output.rs
+++ b/src/blocking/output.rs
@@ -1,3 +1,5 @@
+use crate::error::*;
+
use std::io::Write as _;
use crate::private::TextmodeImpl as _;
@@ -7,7 +9,7 @@ pub struct ScreenGuard {
}
impl ScreenGuard {
- pub fn cleanup(&mut self) -> std::io::Result<()> {
+ pub fn cleanup(&mut self) -> Result<()> {
if self.cleaned_up {
return Ok(());
}
@@ -48,7 +50,7 @@ impl crate::private::TextmodeImpl for Output {
impl crate::Textmode for Output {}
impl Output {
- pub fn new() -> std::io::Result<(Self, ScreenGuard)> {
+ pub fn new() -> Result<(Self, ScreenGuard)> {
write_stdout(crate::INIT)?;
Ok((
Self::new_without_screen(),
@@ -69,7 +71,7 @@ impl Output {
Self { cur, next }
}
- pub fn refresh(&mut self) -> std::io::Result<()> {
+ pub fn refresh(&mut self) -> Result<()> {
let diffs = &[
self.next().screen().contents_diff(self.cur().screen()),
self.next().screen().input_mode_diff(self.cur().screen()),
@@ -84,9 +86,9 @@ impl Output {
}
}
-fn write_stdout(buf: &[u8]) -> std::io::Result<()> {
+fn write_stdout(buf: &[u8]) -> Result<()> {
let mut stdout = std::io::stdout();
- stdout.write_all(buf)?;
- stdout.flush()?;
+ stdout.write_all(buf).map_err(Error::WriteStdout)?;
+ stdout.flush().map_err(Error::WriteStdout)?;
Ok(())
}
diff --git a/src/error.rs b/src/error.rs
new file mode 100644
index 0000000..560f5cb
--- /dev/null
+++ b/src/error.rs
@@ -0,0 +1,10 @@
+#[derive(thiserror::Error, Debug)]
+pub enum Error {
+ #[error("error reading from stdin")]
+ ReadStdin(#[source] std::io::Error),
+
+ #[error("error writing to stdout")]
+ WriteStdout(#[source] std::io::Error),
+}
+
+pub type Result<T> = std::result::Result<T, Error>;
diff --git a/src/input.rs b/src/input.rs
index cb4d0a0..8bd3b60 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -1,3 +1,5 @@
+use crate::error::*;
+
use futures_lite::io::AsyncReadExt as _;
pub struct Input {
@@ -49,7 +51,7 @@ impl Input {
self.parse_single = parse;
}
- pub async fn read_key(&mut self) -> std::io::Result<Option<crate::Key>> {
+ pub async fn read_key(&mut self) -> Result<Option<crate::Key>> {
if self.parse_single {
self.read_single_key().await
} else {
@@ -105,9 +107,7 @@ impl Input {
}
}
- async fn read_single_key(
- &mut self,
- ) -> std::io::Result<Option<crate::Key>> {
+ async fn read_single_key(&mut self) -> Result<Option<crate::Key>> {
match self.getc(true).await? {
Some(0) => Ok(Some(crate::Key::Byte(0))),
Some(c @ 1..=26) => {
@@ -150,9 +150,7 @@ impl Input {
}
}
- async fn read_escape_sequence(
- &mut self,
- ) -> std::io::Result<Option<crate::Key>> {
+ async fn read_escape_sequence(&mut self) -> Result<Option<crate::Key>> {
let mut seen = vec![b'\x1b'];
macro_rules! fail {
@@ -264,7 +262,7 @@ impl Input {
async fn read_utf8_char(
&mut self,
initial: u8,
- ) -> std::io::Result<Option<crate::Key>> {
+ ) -> Result<Option<crate::Key>> {
let mut buf = vec![initial];
macro_rules! fail {
@@ -316,7 +314,7 @@ impl Input {
}
}
- async fn getc(&mut self, fill: bool) -> std::io::Result<Option<u8>> {
+ async fn getc(&mut self, fill: bool) -> Result<Option<u8>> {
if fill {
if !self.maybe_fill_buf().await? {
return Ok(None);
@@ -340,7 +338,7 @@ impl Input {
}
}
- async fn maybe_fill_buf(&mut self) -> std::io::Result<bool> {
+ async fn maybe_fill_buf(&mut self) -> Result<bool> {
if self.buf_is_empty() {
self.fill_buf().await
} else {
@@ -352,7 +350,7 @@ impl Input {
self.pos >= self.buf.len()
}
- async fn fill_buf(&mut self) -> std::io::Result<bool> {
+ async fn fill_buf(&mut self) -> Result<bool> {
self.buf.resize(4096, 0);
self.pos = 0;
let bytes = read_stdin(&mut self.buf).await?;
@@ -364,6 +362,9 @@ impl Input {
}
}
-async fn read_stdin(buf: &mut [u8]) -> std::io::Result<usize> {
- blocking::Unblock::new(std::io::stdin()).read(buf).await
+async fn read_stdin(buf: &mut [u8]) -> Result<usize> {
+ blocking::Unblock::new(std::io::stdin())
+ .read(buf)
+ .await
+ .map_err(Error::ReadStdin)
}
diff --git a/src/lib.rs b/src/lib.rs
index 5fc2429..41561b8 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -3,6 +3,8 @@
pub mod blocking;
pub mod color;
+pub mod error;
+pub use error::{Error, Result};
mod key;
pub use key::Key;
mod raw_guard;
diff --git a/src/output.rs b/src/output.rs
index 9e8c220..52495d0 100644
--- a/src/output.rs
+++ b/src/output.rs
@@ -1,3 +1,5 @@
+use crate::error::*;
+
use futures_lite::io::AsyncWriteExt as _;
use super::private::TextmodeImpl as _;
@@ -7,7 +9,7 @@ pub struct ScreenGuard {
}
impl ScreenGuard {
- pub async fn cleanup(&mut self) -> std::io::Result<()> {
+ pub async fn cleanup(&mut self) -> Result<()> {
if self.cleaned_up {
return Ok(());
}
@@ -50,7 +52,7 @@ impl super::private::TextmodeImpl for Output {
impl super::Textmode for Output {}
impl Output {
- pub async fn new() -> std::io::Result<(Self, ScreenGuard)> {
+ pub async fn new() -> Result<(Self, ScreenGuard)> {
write_stdout(super::INIT).await?;
Ok((
@@ -71,7 +73,7 @@ impl Output {
Self { cur, next }
}
- pub async fn refresh(&mut self) -> std::io::Result<()> {
+ pub async fn refresh(&mut self) -> Result<()> {
let diffs = &[
self.next().screen().contents_diff(self.cur().screen()),
self.next().screen().input_mode_diff(self.cur().screen()),
@@ -86,9 +88,9 @@ impl Output {
}
}
-async fn write_stdout(buf: &[u8]) -> std::io::Result<()> {
+async fn write_stdout(buf: &[u8]) -> Result<()> {
let mut stdout = blocking::Unblock::new(std::io::stdout());
- stdout.write_all(buf).await?;
- stdout.flush().await?;
+ stdout.write_all(buf).await.map_err(Error::WriteStdout)?;
+ stdout.flush().await.map_err(Error::WriteStdout)?;
Ok(())
}