crossterm::ErrorKind to io::Error (#553)

This commit is contained in:
Plecra 2021-04-13 07:46:51 +01:00 committed by GitHub
parent 174de58b69
commit 58f580eaad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 58 additions and 131 deletions

View File

@ -46,8 +46,7 @@ fn read_position_raw() -> Result<(u16, u16)> {
return Err(Error::new(
ErrorKind::Other,
"The cursor position could not be read within a normal duration",
)
.into());
));
}
Err(_) => {}
}

View File

@ -138,8 +138,7 @@ impl ScreenBufferCursor {
"Argument Out of Range Exception when setting cursor position to X: {}",
x
),
)
.into());
));
}
if y < 0 {
@ -149,8 +148,7 @@ impl ScreenBufferCursor {
"Argument Out of Range Exception when setting cursor position to Y: {}",
y
),
)
.into());
));
}
let position = COORD { X: x, Y: y };
@ -160,7 +158,7 @@ impl ScreenBufferCursor {
**self.screen_buffer.handle(),
position,
)) {
return Err(io::Error::last_os_error().into());
return Err(io::Error::last_os_error());
}
}
Ok(())
@ -177,7 +175,7 @@ impl ScreenBufferCursor {
**self.screen_buffer.handle(),
&cursor_info,
)) {
return Err(io::Error::last_os_error().into());
return Err(io::Error::last_os_error());
}
}
Ok(())

View File

@ -1,50 +1,8 @@
//! Module containing error handling logic.
use std::{
fmt::{self, Display, Formatter},
io,
};
use crate::impl_from;
use std::io;
/// The `crossterm` result type.
pub type Result<T> = std::result::Result<T, ErrorKind>;
/// Wrapper for all errors that can occur in `crossterm`.
#[derive(Debug)]
#[non_exhaustive]
pub enum ErrorKind {
IoError(io::Error),
FmtError(fmt::Error),
Utf8Error(std::string::FromUtf8Error),
ParseIntError(std::num::ParseIntError),
ResizingTerminalFailure(String),
SettingTerminalTitleFailure,
}
impl std::error::Error for ErrorKind {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
ErrorKind::IoError(e) => Some(e),
ErrorKind::FmtError(e) => Some(e),
ErrorKind::Utf8Error(e) => Some(e),
ErrorKind::ParseIntError(e) => Some(e),
_ => None,
}
}
}
impl Display for ErrorKind {
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
match *self {
ErrorKind::IoError(_) => write!(fmt, "IO-error occurred"),
ErrorKind::ResizingTerminalFailure(_) => write!(fmt, "Cannot resize the terminal"),
_ => write!(fmt, "Some error has occurred"),
}
}
}
impl_from!(io::Error, ErrorKind::IoError);
impl_from!(fmt::Error, ErrorKind::FmtError);
impl_from!(std::string::FromUtf8Error, ErrorKind::Utf8Error);
impl_from!(std::num::ParseIntError, ErrorKind::ParseIntError);
pub type ErrorKind = io::Error;

View File

@ -7,9 +7,6 @@ use super::source::windows::WindowsEventSource;
#[cfg(feature = "event-stream")]
use super::sys::Waker;
use super::{filter::Filter, source::EventSource, timeout::PollTimeout, InternalEvent, Result};
use crate::ErrorKind;
/// Can be used to read `InternalEvent`s.
pub(crate) struct InternalEventReader {
events: VecDeque<InternalEvent>,
@ -57,8 +54,7 @@ impl InternalEventReader {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"Failed to initialize input reader",
)
.into())
))
}
};
@ -75,14 +71,13 @@ impl InternalEventReader {
None
}
}
Err(ErrorKind::IoError(e)) => {
Err(e) => {
if e.kind() == io::ErrorKind::Interrupted {
return Ok(false);
}
return Err(ErrorKind::IoError(e));
return Err(e);
}
Err(e) => return Err(e),
};
if poll_timeout.elapsed() || maybe_event.is_some() {
@ -131,6 +126,7 @@ impl InternalEventReader {
#[cfg(test)]
mod tests {
use std::io;
use std::{collections::VecDeque, time::Duration};
use crate::ErrorKind;
@ -314,7 +310,7 @@ mod tests {
#[test]
fn test_poll_propagates_error() {
let source = FakeSource::with_error(ErrorKind::ResizingTerminalFailure("Foo".to_string()));
let source = FakeSource::with_error(ErrorKind::from(io::ErrorKind::Other));
let mut reader = InternalEventReader {
events: VecDeque::new(),
@ -327,16 +323,13 @@ mod tests {
.poll(Some(Duration::from_secs(0)), &InternalEventFilter)
.err()
.map(|e| format!("{:?}", &e)),
Some(format!(
"{:?}",
ErrorKind::ResizingTerminalFailure("Foo".to_string())
))
Some(format!("{:?}", ErrorKind::from(io::ErrorKind::Other)))
);
}
#[test]
fn test_read_propagates_error() {
let source = FakeSource::with_error(ErrorKind::ResizingTerminalFailure("Foo".to_string()));
let source = FakeSource::with_error(ErrorKind::from(io::ErrorKind::Other));
let mut reader = InternalEventReader {
events: VecDeque::new(),
@ -349,10 +342,7 @@ mod tests {
.read(&InternalEventFilter)
.err()
.map(|e| format!("{:?}", &e)),
Some(format!(
"{:?}",
ErrorKind::ResizingTerminalFailure("Foo".to_string())
))
Some(format!("{:?}", ErrorKind::from(io::ErrorKind::Other)))
);
}
@ -360,10 +350,7 @@ mod tests {
fn test_poll_continues_after_error() {
const EVENT: InternalEvent = InternalEvent::Event(Event::Resize(10, 10));
let source = FakeSource::new(
&[EVENT, EVENT],
ErrorKind::ResizingTerminalFailure("Foo".to_string()),
);
let source = FakeSource::new(&[EVENT, EVENT], ErrorKind::from(io::ErrorKind::Other));
let mut reader = InternalEventReader {
events: VecDeque::new(),
@ -382,10 +369,7 @@ mod tests {
fn test_read_continues_after_error() {
const EVENT: InternalEvent = InternalEvent::Event(Event::Resize(10, 10));
let source = FakeSource::new(
&[EVENT, EVENT],
ErrorKind::ResizingTerminalFailure("Foo".to_string()),
);
let source = FakeSource::new(&[EVENT, EVENT], ErrorKind::from(io::ErrorKind::Other));
let mut reader = InternalEventReader {
events: VecDeque::new(),

View File

@ -3,7 +3,7 @@ use std::{collections::VecDeque, io, time::Duration};
use mio::{unix::SourceFd, Events, Interest, Poll, Token};
use signal_hook::iterator::Signals;
use crate::{ErrorKind, Result};
use crate::Result;
#[cfg(feature = "event-stream")]
use super::super::sys::Waker;
@ -87,7 +87,7 @@ impl EventSource for UnixInternalEventSource {
if e.kind() == io::ErrorKind::Interrupted {
continue;
} else {
return Err(ErrorKind::IoError(e));
return Err(e);
}
};
@ -109,7 +109,7 @@ impl EventSource for UnixInternalEventSource {
);
}
}
Err(ErrorKind::IoError(e)) => {
Err(e) => {
// No more data to read at the moment. We will receive another event
if e.kind() == io::ErrorKind::WouldBlock {
break;
@ -119,7 +119,6 @@ impl EventSource for UnixInternalEventSource {
continue;
}
}
Err(e) => return Err(e),
};
if let Some(event) = self.parser.next() {

View File

@ -5,7 +5,7 @@ use std::{
use libc::size_t;
use crate::{ErrorKind, Result};
use crate::Result;
/// A file descriptor wrapper.
///
@ -38,7 +38,7 @@ impl FileDesc {
};
if result < 0 {
Err(ErrorKind::IoError(io::Error::last_os_error()))
Err(io::Error::last_os_error())
} else {
Ok(result as usize)
}

View File

@ -20,10 +20,7 @@ use super::super::super::InternalEvent;
//
fn could_not_parse_event_error() -> ErrorKind {
ErrorKind::IoError(io::Error::new(
io::ErrorKind::Other,
"Could not parse an event.",
))
io::Error::new(io::ErrorKind::Other, "Could not parse an event.")
}
pub(crate) fn parse_event(buffer: &[u8], input_available: bool) -> Result<Option<InternalEvent>> {

View File

@ -74,12 +74,11 @@ impl WinApiPoll {
// timeout elapsed
Ok(None)
}
WAIT_FAILED => Err(io::Error::last_os_error().into()),
WAIT_FAILED => Err(io::Error::last_os_error()),
_ => Err(io::Error::new(
io::ErrorKind::Other,
"WaitForMultipleObjects returned unexpected result.",
)
.into()),
)),
}
}

View File

@ -117,7 +117,7 @@ macro_rules! execute {
// Queue each command, then flush
$crate::queue!($writer $(, $command)*)
.and_then(|()| {
::std::io::Write::flush($writer.by_ref()).map_err($crate::ErrorKind::IoError)
::std::io::Write::flush($writer.by_ref())
})
}}
}

View File

@ -10,7 +10,7 @@ use libc::{
};
use parking_lot::Mutex;
use crate::error::{ErrorKind, Result};
use crate::error::Result;
use crate::event::sys::unix::file_descriptor::{tty_fd, FileDesc};
// Some(Termios) -> we're in the raw mode and this is the previous mode
@ -129,7 +129,7 @@ fn set_terminal_attr(fd: RawFd, termios: &Termios) -> Result<()> {
fn wrap_with_result(result: i32) -> Result<()> {
if result == -1 {
Err(ErrorKind::IoError(io::Error::last_os_error()))
Err(io::Error::last_os_error())
} else {
Ok(())
}

View File

@ -1,6 +1,7 @@
//! WinAPI related logic for terminal manipulation.
use std::fmt::{self, Write};
use std::io;
use crossterm_winapi::{Console, ConsoleMode, Coord, Handle, ScreenBuffer, Size};
use winapi::{
@ -99,15 +100,17 @@ pub(crate) fn scroll_down(row_count: u16) -> Result<()> {
pub(crate) fn set_size(width: u16, height: u16) -> Result<()> {
if width <= 1 {
return Err(ErrorKind::ResizingTerminalFailure(String::from(
"Cannot set the terminal width lower than 1.",
)));
return Err(ErrorKind::new(
io::ErrorKind::InvalidInput,
"terminal width must be at least 1",
));
}
if height <= 1 {
return Err(ErrorKind::ResizingTerminalFailure(String::from(
"Cannot set the terminal height lower then 1.",
)));
return Err(ErrorKind::new(
io::ErrorKind::InvalidInput,
"terminal height must be at least 1",
));
}
// get the position of the current console window
@ -127,9 +130,10 @@ pub(crate) fn set_size(width: u16, height: u16) -> Result<()> {
let width = width as i16;
if current_size.width < window.left + width {
if window.left >= i16::max_value() - width {
return Err(ErrorKind::ResizingTerminalFailure(String::from(
"Argument out of range when setting terminal width.",
)));
return Err(ErrorKind::new(
io::ErrorKind::InvalidInput,
"terminal width too large",
));
}
new_size.width = window.left + width;
@ -138,23 +142,18 @@ pub(crate) fn set_size(width: u16, height: u16) -> Result<()> {
let height = height as i16;
if current_size.height < window.top + height {
if window.top >= i16::max_value() - height {
return Err(ErrorKind::ResizingTerminalFailure(String::from(
"Argument out of range when setting terminal height.",
)));
return Err(ErrorKind::new(
io::ErrorKind::InvalidInput,
"terminal height too large",
));
}
new_size.height = window.top + height;
resize_buffer = true;
}
if resize_buffer
&& screen_buffer
.set_size(new_size.width - 1, new_size.height - 1)
.is_err()
{
return Err(ErrorKind::ResizingTerminalFailure(String::from(
"Something went wrong when setting screen buffer size.",
)));
if resize_buffer {
screen_buffer.set_size(new_size.width - 1, new_size.height - 1)?;
}
let mut window = window;
@ -165,29 +164,23 @@ pub(crate) fn set_size(width: u16, height: u16) -> Result<()> {
console.set_console_info(true, window)?;
// if we resized the buffer, un-resize it.
if resize_buffer
&& screen_buffer
.set_size(current_size.width - 1, current_size.height - 1)
.is_err()
{
return Err(ErrorKind::ResizingTerminalFailure(String::from(
"Something went wrong when setting screen buffer size.",
)));
if resize_buffer {
screen_buffer.set_size(current_size.width - 1, current_size.height - 1)?;
}
let bounds = console.largest_window_size();
if width > bounds.x {
return Err(ErrorKind::ResizingTerminalFailure(format!(
"Argument width: {} out of range when setting terminal width.",
width
)));
return Err(ErrorKind::new(
io::ErrorKind::InvalidInput,
format!("terminal width {} too large", width),
));
}
if height > bounds.y {
return Err(ErrorKind::ResizingTerminalFailure(format!(
"Argument height: {} out of range when setting terminal height.",
width
)));
return Err(ErrorKind::new(
io::ErrorKind::InvalidInput,
format!("terminal height {} too large", height),
));
}
Ok(())
@ -211,7 +204,7 @@ pub(crate) fn set_window_title(title: impl fmt::Display) -> Result<()> {
if result != 0 {
Ok(())
} else {
Err(ErrorKind::SettingTerminalTitleFailure)
Err(ErrorKind::last_os_error())
}
}