-
Notifications
You must be signed in to change notification settings - Fork 54
Error handling overhaul #49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -181,6 +181,88 @@ pub enum Attr { | |
| BackgroundColor(color::Color) | ||
| } | ||
|
|
||
| /// An error arising from interacting with the terminal. | ||
| #[derive(Debug)] | ||
| pub enum Error { | ||
| /// Indicates an error from any underlying IO | ||
| Io(io::Error), | ||
| /// Indicates an error during terminfo parsing | ||
| TerminfoParsing(terminfo::Error), | ||
| /// Indicates an error expanding a parameterized string from the terminfo database | ||
| ParameterizedExpansion(terminfo::parm::Error), | ||
| /// Indicates that the terminal does not support the requested attribute | ||
| AttributeNotSupported, | ||
| /// Indicates that the `TERM` environment variable was unset, and thus we were unable to detect | ||
| /// which terminal we should be using. | ||
| TermUnset, | ||
| /// Indicates that we were unable to find a terminfo entry for the requested terminal. | ||
| TerminfoEntryNotFound, | ||
| /// Indicates that the cursor could not be moved to the requested position. | ||
| CursorDestinationInvalid, | ||
| /// Indicates that the terminal does not support the requested color. | ||
| /// | ||
| /// This is like `AttributeNotSupported`, but more specific. | ||
| ColorNotSupported, | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we add a non-exhaustive variant? #[doc(hidden)]
__Nonexhaustive,
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good call.
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree. How about On 12-13-15, cmr wrote:
|
||
| } | ||
|
|
||
| /// The canonical `Result` type using this crate's Error type. | ||
| pub type Result<T> = std::result::Result<T, Error>; | ||
|
|
||
| impl std::fmt::Display for Error { | ||
| fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
| use std::error::Error; | ||
| if let &::Error::Io(ref e) = self { | ||
| write!(f, "{}", e) | ||
| } else { | ||
| f.write_str(self.description()) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl std::error::Error for Error { | ||
| fn description(&self) -> &str { | ||
| use Error::*; | ||
| use std::error::Error; | ||
| match self { | ||
| &Io(ref io) => io.description(), | ||
| &TerminfoParsing(ref e) => e.description(), | ||
| &ParameterizedExpansion(ref e) => e.description(), | ||
| &AttributeNotSupported => "attribute not supported by the terminal", | ||
| &TermUnset => "TERM environment variable unset, unable to detect a terminal", | ||
| &TerminfoEntryNotFound => "could not find a terminfo entry for this terminal", | ||
| &CursorDestinationInvalid => "could not move cursor to requested position", | ||
| &ColorNotSupported => "color not supported by the terminal", | ||
| } | ||
| } | ||
|
|
||
| fn cause(&self) -> Option<&std::error::Error> { | ||
| match self { | ||
| &Error::Io(ref io) => Some(io), | ||
| &Error::TerminfoParsing(ref e) => Some(e), | ||
| &Error::ParameterizedExpansion(ref e) => Some(e), | ||
| _ => None, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl std::convert::From<io::Error> for Error { | ||
| fn from(val: io::Error) -> Self { | ||
| Error::Io(val) | ||
| } | ||
| } | ||
|
|
||
| impl std::convert::From<terminfo::Error> for Error { | ||
| fn from(val: terminfo::Error) -> Self { | ||
| Error::TerminfoParsing(val) | ||
| } | ||
| } | ||
|
|
||
| impl std::convert::From<terminfo::parm::Error> for Error { | ||
| fn from(val: terminfo::parm::Error) -> Self { | ||
| Error::ParameterizedExpansion(val) | ||
| } | ||
| } | ||
|
|
||
| /// A terminal with similar capabilities to an ANSI Terminal | ||
| /// (foreground/background colors etc). | ||
| pub trait Terminal: Write { | ||
|
|
@@ -192,56 +274,53 @@ pub trait Terminal: Write { | |
| /// If the color is a bright color, but the terminal only supports 8 colors, | ||
| /// the corresponding normal color will be used instead. | ||
| /// | ||
| /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)` | ||
| /// if there was an I/O error. | ||
| fn fg(&mut self, color: color::Color) -> io::Result<bool>; | ||
| /// Returns `Ok(())` if the color change code was sent to the terminal, or `Err(e)` if there | ||
| /// was an error. | ||
| fn fg(&mut self, color: color::Color) -> Result<()>; | ||
|
|
||
| /// Sets the background color to the given color. | ||
| /// | ||
| /// If the color is a bright color, but the terminal only supports 8 colors, | ||
| /// the corresponding normal color will be used instead. | ||
| /// | ||
| /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)` | ||
| /// if there was an I/O error. | ||
| fn bg(&mut self, color: color::Color) -> io::Result<bool>; | ||
| /// Returns `Ok(())` if the color change code was sent to the terminal, or `Err(e)` if there | ||
| /// was an error. | ||
| fn bg(&mut self, color: color::Color) -> Result<()>; | ||
|
|
||
| /// Sets the given terminal attribute, if supported. Returns `Ok(true)` | ||
| /// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if | ||
| /// there was an I/O error. | ||
| fn attr(&mut self, attr: Attr) -> io::Result<bool>; | ||
| /// Sets the given terminal attribute, if supported. Returns `Ok(())` if the attribute is | ||
| /// supported and was sent to the terminal, or `Err(e)` if there was an error or the attribute | ||
| /// wasn't supported. | ||
| fn attr(&mut self, attr: Attr) -> Result<()>; | ||
|
|
||
| /// Returns whether the given terminal attribute is supported. | ||
| fn supports_attr(&self, attr: Attr) -> bool; | ||
|
|
||
| /// Resets all terminal attributes and colors to their defaults. | ||
| /// | ||
| /// Returns `Ok(true)` if the terminal was reset, `Ok(false)` otherwise, and `Err(e)` if there | ||
| /// was an I/O error. | ||
| /// Returns `Ok(())` if the reset code was printed, or `Err(e)` if there was an error. | ||
| /// | ||
| /// *Note: This does not flush.* | ||
| /// | ||
| /// That means the reset command may get buffered so, if you aren't planning on doing anything | ||
| /// else that might flush stdout's buffer (e.g. writing a line of text), you should flush after | ||
| /// calling reset. | ||
| fn reset(&mut self) -> io::Result<bool>; | ||
| fn reset(&mut self) -> Result<()>; | ||
|
|
||
| /// Moves the cursor up one line. | ||
| /// | ||
| /// Returns `Ok(true)` if the cursor was moved, `Ok(false)` otherwise, and `Err(e)` | ||
| /// if there was an I/O error. | ||
| fn cursor_up(&mut self) -> io::Result<bool>; | ||
| /// Returns `Ok(())` if the cursor movement code was printed, or `Err(e)` if there was an | ||
| /// error. | ||
| fn cursor_up(&mut self) -> Result<()>; | ||
|
|
||
| /// Deletes the text from the cursor location to the end of the line. | ||
| /// | ||
| /// Returns `Ok(true)` if the text was deleted, `Ok(false)` otherwise, and `Err(e)` | ||
| /// if there was an I/O error. | ||
| fn delete_line(&mut self) -> io::Result<bool>; | ||
| /// Returns `Ok(())` if the deletion code was printed, or `Err(e)` if there was an error. | ||
| fn delete_line(&mut self) -> Result<()>; | ||
|
|
||
| /// Moves the cursor to the left edge of the current line. | ||
| /// | ||
| /// Returns `Ok(true)` if the text was deleted, `Ok(false)` otherwise, and `Err(e)` | ||
| /// if there was an I/O error. | ||
| fn carriage_return(&mut self) -> io::Result<bool>; | ||
| /// Returns `Ok(true)` if the deletion code was printed, or `Err(e)` if there was an error. | ||
| fn carriage_return(&mut self) -> Result<()>; | ||
|
|
||
| /// Gets an immutable reference to the stream inside | ||
| fn get_ref<'a>(&'a self) -> &'a Self::Output; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we change this to a more generic
NotSupported(orOperationNotSupported)? #50 needs a way to say that querying the terminal size isn't supported.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy with
NotSupported.