4848//! t.fg(term::color::RED).unwrap();
4949//! writeln!(t, "world!").unwrap();
5050//!
51- //! assert!( t.reset().unwrap() );
51+ //! t.reset().unwrap();
5252//! }
5353//! ```
5454//!
@@ -181,6 +181,153 @@ pub enum Attr {
181181 BackgroundColor ( color:: Color )
182182}
183183
184+ /// An error arising from interacting with the terminal.
185+ #[ derive( Debug ) ]
186+ pub enum Error {
187+ /// Indicates an error from any underlying IO
188+ Io ( io:: Error ) ,
189+ /// Indicates an error during terminfo parsing
190+ TerminfoParsing ( terminfo:: Error ) ,
191+ /// Indicates an error expanding a parameterized string from the terminfo database
192+ ParameterizedExpansion ( terminfo:: parm:: Error ) ,
193+ /// Indicates that the terminal does not support the requested operation.
194+ NotSupported ,
195+ /// Indicates that the `TERM` environment variable was unset, and thus we were unable to detect
196+ /// which terminal we should be using.
197+ TermUnset ,
198+ /// Indicates that we were unable to find a terminfo entry for the requested terminal.
199+ TerminfoEntryNotFound ,
200+ /// Indicates that the cursor could not be moved to the requested position.
201+ CursorDestinationInvalid ,
202+ /// Indicates that the terminal does not support displaying the requested color.
203+ ///
204+ /// This is like `NotSupported`, but more specific.
205+ ColorOutOfRange ,
206+ #[ doc( hidden) ]
207+ /// Please don't match against this - if you do, we can't promise we won't break your crate
208+ /// with a semver-compliant version bump.
209+ __Nonexhaustive,
210+ }
211+
212+ // manually implemented because std::io::Error does not implement Eq/PartialEq
213+ impl std:: cmp:: PartialEq for Error {
214+ fn eq ( & self , other : & Error ) -> bool {
215+ use Error :: * ;
216+ match self {
217+ & Io ( _) => {
218+ false
219+ }
220+ & TerminfoParsing ( ref inner1) => {
221+ match other {
222+ & TerminfoParsing ( ref inner2) => inner1 == inner2,
223+ _ => false
224+ }
225+ }
226+ & ParameterizedExpansion ( ref inner1) => {
227+ match other {
228+ & ParameterizedExpansion ( ref inner2) => inner1 == inner2,
229+ _ => false
230+ }
231+ }
232+ & NotSupported => {
233+ match other {
234+ & NotSupported => true ,
235+ _ => false
236+ }
237+ }
238+ & TermUnset => {
239+ match other {
240+ & TermUnset => true ,
241+ _ => false
242+ }
243+ }
244+ & TerminfoEntryNotFound => {
245+ match other {
246+ & TerminfoEntryNotFound => true ,
247+ _ => false
248+ }
249+ }
250+ & CursorDestinationInvalid => {
251+ match other {
252+ & CursorDestinationInvalid => true ,
253+ _ => false
254+ }
255+ }
256+ & ColorOutOfRange => {
257+ match other {
258+ & ColorOutOfRange => true ,
259+ _ => false
260+ }
261+ }
262+ & __Nonexhaustive => {
263+ match other {
264+ & __Nonexhaustive => true ,
265+ _ => false
266+ }
267+ }
268+ }
269+ }
270+ }
271+
272+ /// The canonical `Result` type using this crate's Error type.
273+ pub type Result < T > = std:: result:: Result < T , Error > ;
274+
275+ impl std:: fmt:: Display for Error {
276+ fn fmt ( & self , f : & mut std:: fmt:: Formatter ) -> std:: fmt:: Result {
277+ use std:: error:: Error ;
278+ if let & :: Error :: Io ( ref e) = self {
279+ write ! ( f, "{}" , e)
280+ } else {
281+ f. write_str ( self . description ( ) )
282+ }
283+ }
284+ }
285+
286+ impl std:: error:: Error for Error {
287+ fn description ( & self ) -> & str {
288+ use Error :: * ;
289+ use std:: error:: Error ;
290+ match self {
291+ & Io ( ref io) => io. description ( ) ,
292+ & TerminfoParsing ( ref e) => e. description ( ) ,
293+ & ParameterizedExpansion ( ref e) => e. description ( ) ,
294+ & NotSupported => "operation not supported by the terminal" ,
295+ & TermUnset => "TERM environment variable unset, unable to detect a terminal" ,
296+ & TerminfoEntryNotFound => "could not find a terminfo entry for this terminal" ,
297+ & CursorDestinationInvalid => "could not move cursor to requested position" ,
298+ & ColorOutOfRange => "color not supported by the terminal" ,
299+ & __Nonexhaustive => "placeholder variant that shouldn't be used" ,
300+ }
301+ }
302+
303+ fn cause ( & self ) -> Option < & std:: error:: Error > {
304+ match self {
305+ & Error :: Io ( ref io) => Some ( io) ,
306+ & Error :: TerminfoParsing ( ref e) => Some ( e) ,
307+ & Error :: ParameterizedExpansion ( ref e) => Some ( e) ,
308+ _ => None ,
309+ }
310+ }
311+ }
312+
313+ impl std:: convert:: From < io:: Error > for Error {
314+ fn from ( val : io:: Error ) -> Self {
315+ Error :: Io ( val)
316+ }
317+ }
318+
319+ impl std:: convert:: From < terminfo:: Error > for Error {
320+ fn from ( val : terminfo:: Error ) -> Self {
321+ Error :: TerminfoParsing ( val)
322+ }
323+ }
324+
325+ impl std:: convert:: From < terminfo:: parm:: Error > for Error {
326+ fn from ( val : terminfo:: parm:: Error ) -> Self {
327+ Error :: ParameterizedExpansion ( val)
328+ }
329+ }
330+
184331/// A terminal with similar capabilities to an ANSI Terminal
185332/// (foreground/background colors etc).
186333pub trait Terminal : Write {
@@ -192,56 +339,53 @@ pub trait Terminal: Write {
192339 /// If the color is a bright color, but the terminal only supports 8 colors,
193340 /// the corresponding normal color will be used instead.
194341 ///
195- /// Returns `Ok(true) ` if the color was set, `Ok(false)` otherwise, and `Err(e)`
196- /// if there was an I/O error.
197- fn fg ( & mut self , color : color:: Color ) -> io :: Result < bool > ;
342+ /// Returns `Ok(()) ` if the color change code was sent to the terminal, or `Err(e)` if there
343+ /// was an error.
344+ fn fg ( & mut self , color : color:: Color ) -> Result < ( ) > ;
198345
199346 /// Sets the background color to the given color.
200347 ///
201348 /// If the color is a bright color, but the terminal only supports 8 colors,
202349 /// the corresponding normal color will be used instead.
203350 ///
204- /// Returns `Ok(true) ` if the color was set, `Ok(false)` otherwise, and `Err(e)`
205- /// if there was an I/O error.
206- fn bg ( & mut self , color : color:: Color ) -> io :: Result < bool > ;
351+ /// Returns `Ok(()) ` if the color change code was sent to the terminal, or `Err(e)` if there
352+ /// was an error.
353+ fn bg ( & mut self , color : color:: Color ) -> Result < ( ) > ;
207354
208- /// Sets the given terminal attribute, if supported. Returns `Ok(true)`
209- /// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if
210- /// there was an I/O error .
211- fn attr ( & mut self , attr : Attr ) -> io :: Result < bool > ;
355+ /// Sets the given terminal attribute, if supported. Returns `Ok(())` if the attribute is
356+ /// supported and was sent to the terminal, or `Err(e)` if there was an error or the attribute
357+ /// wasn't supported .
358+ fn attr ( & mut self , attr : Attr ) -> Result < ( ) > ;
212359
213360 /// Returns whether the given terminal attribute is supported.
214361 fn supports_attr ( & self , attr : Attr ) -> bool ;
215362
216363 /// Resets all terminal attributes and colors to their defaults.
217364 ///
218- /// Returns `Ok(true)` if the terminal was reset, `Ok(false)` otherwise, and `Err(e)` if there
219- /// was an I/O error.
365+ /// Returns `Ok(())` if the reset code was printed, or `Err(e)` if there was an error.
220366 ///
221367 /// *Note: This does not flush.*
222368 ///
223369 /// That means the reset command may get buffered so, if you aren't planning on doing anything
224370 /// else that might flush stdout's buffer (e.g. writing a line of text), you should flush after
225371 /// calling reset.
226- fn reset ( & mut self ) -> io :: Result < bool > ;
372+ fn reset ( & mut self ) -> Result < ( ) > ;
227373
228374 /// Moves the cursor up one line.
229375 ///
230- /// Returns `Ok(true) ` if the cursor was moved, `Ok(false)` otherwise, and `Err(e)`
231- /// if there was an I/O error.
232- fn cursor_up ( & mut self ) -> io :: Result < bool > ;
376+ /// Returns `Ok(()) ` if the cursor movement code was printed, or `Err(e)` if there was an
377+ /// error.
378+ fn cursor_up ( & mut self ) -> Result < ( ) > ;
233379
234380 /// Deletes the text from the cursor location to the end of the line.
235381 ///
236- /// Returns `Ok(true)` if the text was deleted, `Ok(false)` otherwise, and `Err(e)`
237- /// if there was an I/O error.
238- fn delete_line ( & mut self ) -> io:: Result < bool > ;
382+ /// Returns `Ok(())` if the deletion code was printed, or `Err(e)` if there was an error.
383+ fn delete_line ( & mut self ) -> Result < ( ) > ;
239384
240385 /// Moves the cursor to the left edge of the current line.
241386 ///
242- /// Returns `Ok(true)` if the text was deleted, `Ok(false)` otherwise, and `Err(e)`
243- /// if there was an I/O error.
244- fn carriage_return ( & mut self ) -> io:: Result < bool > ;
387+ /// Returns `Ok(true)` if the deletion code was printed, or `Err(e)` if there was an error.
388+ fn carriage_return ( & mut self ) -> Result < ( ) > ;
245389
246390 /// Gets an immutable reference to the stream inside
247391 fn get_ref < ' a > ( & ' a self ) -> & ' a Self :: Output ;
0 commit comments