crossterm::ErrorKind to io::Error (#553)
This commit is contained in:
parent
174de58b69
commit
58f580eaad
@ -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(_) => {}
|
||||
}
|
||||
|
@ -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(())
|
||||
|
46
src/error.rs
46
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<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;
|
||||
|
@ -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(),
|
||||
|
@ -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() {
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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>> {
|
||||
|
@ -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()),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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())
|
||||
})
|
||||
}}
|
||||
}
|
||||
|
@ -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(())
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user