From 58f580eaad4e80ccb8a09541b760a329971bb4bc Mon Sep 17 00:00:00 2001 From: Plecra Date: Tue, 13 Apr 2021 07:46:51 +0100 Subject: [PATCH] crossterm::ErrorKind to io::Error (#553) --- src/cursor/sys/unix.rs | 3 +- src/cursor/sys/windows.rs | 10 ++-- src/error.rs | 46 +----------------- src/event/read.rs | 36 ++++---------- src/event/source/unix.rs | 7 ++- src/event/sys/unix/file_descriptor.rs | 4 +- src/event/sys/unix/parse.rs | 5 +- src/event/sys/windows/poll.rs | 5 +- src/macros.rs | 2 +- src/terminal/sys/unix.rs | 4 +- src/terminal/sys/windows.rs | 67 ++++++++++++--------------- 11 files changed, 58 insertions(+), 131 deletions(-) diff --git a/src/cursor/sys/unix.rs b/src/cursor/sys/unix.rs index 5468f3065..bf893099b 100644 --- a/src/cursor/sys/unix.rs +++ b/src/cursor/sys/unix.rs @@ -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(_) => {} } diff --git a/src/cursor/sys/windows.rs b/src/cursor/sys/windows.rs index 0e20e84ba..1151e2224 100644 --- a/src/cursor/sys/windows.rs +++ b/src/cursor/sys/windows.rs @@ -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(()) diff --git a/src/error.rs b/src/error.rs index 1761996b9..500c9fa1c 100644 --- a/src/error.rs +++ b/src/error.rs @@ -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 = std::result::Result; -/// 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; diff --git a/src/event/read.rs b/src/event/read.rs index a24170a3a..34e8892a1 100644 --- a/src/event/read.rs +++ b/src/event/read.rs @@ -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, @@ -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(), diff --git a/src/event/source/unix.rs b/src/event/source/unix.rs index 23e598b27..b73dcba07 100644 --- a/src/event/source/unix.rs +++ b/src/event/source/unix.rs @@ -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() { diff --git a/src/event/sys/unix/file_descriptor.rs b/src/event/sys/unix/file_descriptor.rs index c80557123..8b481766b 100644 --- a/src/event/sys/unix/file_descriptor.rs +++ b/src/event/sys/unix/file_descriptor.rs @@ -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) } diff --git a/src/event/sys/unix/parse.rs b/src/event/sys/unix/parse.rs index dc2d26eae..401836f5c 100644 --- a/src/event/sys/unix/parse.rs +++ b/src/event/sys/unix/parse.rs @@ -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> { diff --git a/src/event/sys/windows/poll.rs b/src/event/sys/windows/poll.rs index 429b45f65..32511fb0a 100644 --- a/src/event/sys/windows/poll.rs +++ b/src/event/sys/windows/poll.rs @@ -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()), + )), } } diff --git a/src/macros.rs b/src/macros.rs index 893e90667..f0bd6417b 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -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()) }) }} } diff --git a/src/terminal/sys/unix.rs b/src/terminal/sys/unix.rs index d5e582703..ecf4bff8d 100644 --- a/src/terminal/sys/unix.rs +++ b/src/terminal/sys/unix.rs @@ -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(()) } diff --git a/src/terminal/sys/windows.rs b/src/terminal/sys/windows.rs index 483ea3fb0..b76d64aa8 100644 --- a/src/terminal/sys/windows.rs +++ b/src/terminal/sys/windows.rs @@ -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()) } }