rustyline/
error.rs

1//! Contains error type for handling I/O and Errno errors
2#[cfg(windows)]
3use std::char;
4use std::error::Error;
5use std::fmt;
6use std::io;
7
8/// The error type for Rustyline errors that can arise from
9/// I/O related errors or Errno when using the nix-rust library
10// #[non_exhaustive]
11#[allow(clippy::module_name_repetitions)]
12#[derive(Debug)]
13#[non_exhaustive]
14pub enum ReadlineError {
15    /// I/O Error
16    Io(io::Error),
17    /// EOF (VEOF / Ctrl-D)
18    Eof,
19    /// Interrupt signal (VINTR / VQUIT / Ctrl-C)
20    Interrupted,
21    /// Unix Error from syscall
22    #[cfg(unix)]
23    Errno(nix::Error),
24    /// Error generated on WINDOW_BUFFER_SIZE_EVENT / SIGWINCH signal
25    WindowResized,
26    /// Like Utf8Error on unix
27    #[cfg(windows)]
28    Decode(char::DecodeUtf16Error),
29    /// Something went wrong calling a Windows API
30    #[cfg(windows)]
31    SystemError(clipboard_win::SystemError),
32}
33
34impl fmt::Display for ReadlineError {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        match *self {
37            ReadlineError::Io(ref err) => err.fmt(f),
38            ReadlineError::Eof => write!(f, "EOF"),
39            ReadlineError::Interrupted => write!(f, "Interrupted"),
40            #[cfg(unix)]
41            ReadlineError::Errno(ref err) => err.fmt(f),
42            ReadlineError::WindowResized => write!(f, "WindowResized"),
43            #[cfg(windows)]
44            ReadlineError::Decode(ref err) => err.fmt(f),
45            #[cfg(windows)]
46            ReadlineError::SystemError(ref err) => err.fmt(f),
47        }
48    }
49}
50
51impl Error for ReadlineError {
52    fn source(&self) -> Option<&(dyn Error + 'static)> {
53        match *self {
54            ReadlineError::Io(ref err) => Some(err),
55            ReadlineError::Eof => None,
56            ReadlineError::Interrupted => None,
57            #[cfg(unix)]
58            ReadlineError::Errno(ref err) => Some(err),
59            ReadlineError::WindowResized => None,
60            #[cfg(windows)]
61            ReadlineError::Decode(ref err) => Some(err),
62            #[cfg(windows)]
63            ReadlineError::SystemError(_) => None,
64        }
65    }
66}
67
68#[cfg(unix)]
69#[derive(Debug)]
70pub(crate) struct WindowResizedError;
71#[cfg(unix)]
72impl fmt::Display for WindowResizedError {
73    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74        write!(f, "WindowResized")
75    }
76}
77#[cfg(unix)]
78impl Error for WindowResizedError {}
79
80impl From<io::Error> for ReadlineError {
81    fn from(err: io::Error) -> Self {
82        #[cfg(unix)]
83        if err.kind() == io::ErrorKind::Interrupted {
84            if let Some(e) = err.get_ref() {
85                if e.downcast_ref::<WindowResizedError>().is_some() {
86                    return ReadlineError::WindowResized;
87                }
88            }
89        }
90        ReadlineError::Io(err)
91    }
92}
93
94impl From<io::ErrorKind> for ReadlineError {
95    fn from(kind: io::ErrorKind) -> Self {
96        ReadlineError::Io(io::Error::from(kind))
97    }
98}
99
100#[cfg(unix)]
101impl From<nix::Error> for ReadlineError {
102    fn from(err: nix::Error) -> Self {
103        ReadlineError::Errno(err)
104    }
105}
106
107#[cfg(windows)]
108impl From<char::DecodeUtf16Error> for ReadlineError {
109    fn from(err: char::DecodeUtf16Error) -> Self {
110        ReadlineError::Io(io::Error::new(io::ErrorKind::InvalidData, err))
111    }
112}
113
114#[cfg(windows)]
115impl From<std::string::FromUtf8Error> for ReadlineError {
116    fn from(err: std::string::FromUtf8Error) -> Self {
117        ReadlineError::Io(io::Error::new(io::ErrorKind::InvalidData, err))
118    }
119}
120
121#[cfg(unix)]
122impl From<fmt::Error> for ReadlineError {
123    fn from(err: fmt::Error) -> Self {
124        ReadlineError::Io(io::Error::new(io::ErrorKind::Other, err))
125    }
126}
127
128#[cfg(windows)]
129impl From<clipboard_win::SystemError> for ReadlineError {
130    fn from(err: clipboard_win::SystemError) -> Self {
131        ReadlineError::SystemError(err)
132    }
133}