32
32
//! t.fg(term::color::RED).unwrap();
33
33
//! writeln!(t, "world!").unwrap();
34
34
//!
35
- //! assert!( t.reset().unwrap() );
35
+ //! t.reset().unwrap();
36
36
//! }
37
37
//! ```
38
38
//!
@@ -166,6 +166,161 @@ pub enum Attr {
166
166
BackgroundColor ( color:: Color ) ,
167
167
}
168
168
169
+ /// An error arising from interacting with the terminal.
170
+ #[ derive( Debug ) ]
171
+ pub enum Error {
172
+ /// Indicates an error from any underlying IO
173
+ Io ( io:: Error ) ,
174
+ /// Indicates an error during terminfo parsing
175
+ TerminfoParsing ( terminfo:: Error ) ,
176
+ /// Indicates an error expanding a parameterized string from the terminfo database
177
+ ParameterizedExpansion ( terminfo:: parm:: Error ) ,
178
+ /// Indicates that the terminal does not support the requested operation.
179
+ NotSupported ,
180
+ /// Indicates that the `TERM` environment variable was unset, and thus we were unable to detect
181
+ /// which terminal we should be using.
182
+ TermUnset ,
183
+ /// Indicates that we were unable to find a terminfo entry for the requested terminal.
184
+ TerminfoEntryNotFound ,
185
+ /// Indicates that the cursor could not be moved to the requested position.
186
+ CursorDestinationInvalid ,
187
+ /// Indicates that the terminal does not support displaying the requested color.
188
+ ///
189
+ /// This is like `NotSupported`, but more specific.
190
+ ColorOutOfRange ,
191
+ #[ doc( hidden) ]
192
+ /// Please don't match against this - if you do, we can't promise we won't break your crate
193
+ /// with a semver-compliant version bump.
194
+ __Nonexhaustive,
195
+ }
196
+
197
+ // manually implemented because std::io::Error does not implement Eq/PartialEq
198
+ impl std:: cmp:: PartialEq for Error {
199
+ fn eq ( & self , other : & Error ) -> bool {
200
+ use Error :: * ;
201
+ match self {
202
+ & Io ( _) => false ,
203
+ & TerminfoParsing ( ref inner1) => {
204
+ match other {
205
+ & TerminfoParsing ( ref inner2) => inner1 == inner2,
206
+ _ => false ,
207
+ }
208
+ }
209
+ & ParameterizedExpansion ( ref inner1) => {
210
+ match other {
211
+ & ParameterizedExpansion ( ref inner2) => inner1 == inner2,
212
+ _ => false ,
213
+ }
214
+ }
215
+ & NotSupported => {
216
+ match other {
217
+ & NotSupported => true ,
218
+ _ => false ,
219
+ }
220
+ }
221
+ & TermUnset => {
222
+ match other {
223
+ & TermUnset => true ,
224
+ _ => false ,
225
+ }
226
+ }
227
+ & TerminfoEntryNotFound => {
228
+ match other {
229
+ & TerminfoEntryNotFound => true ,
230
+ _ => false ,
231
+ }
232
+ }
233
+ & CursorDestinationInvalid => {
234
+ match other {
235
+ & CursorDestinationInvalid => true ,
236
+ _ => false ,
237
+ }
238
+ }
239
+ & ColorOutOfRange => {
240
+ match other {
241
+ & ColorOutOfRange => true ,
242
+ _ => false ,
243
+ }
244
+ }
245
+ & __Nonexhaustive => {
246
+ match other {
247
+ & __Nonexhaustive => true ,
248
+ _ => false ,
249
+ }
250
+ }
251
+ }
252
+ }
253
+ }
254
+
255
+ /// The canonical `Result` type using this crate's Error type.
256
+ pub type Result < T > = std:: result:: Result < T , Error > ;
257
+
258
+ impl std:: fmt:: Display for Error {
259
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter ) -> std:: fmt:: Result {
260
+ use std:: error:: Error ;
261
+ if let & :: Error :: Io ( ref e) = self {
262
+ write ! ( f, "{}" , e)
263
+ } else {
264
+ f. write_str ( self . description ( ) )
265
+ }
266
+ }
267
+ }
268
+
269
+ impl std:: error:: Error for Error {
270
+ fn description ( & self ) -> & str {
271
+ use Error :: * ;
272
+ use std:: error:: Error ;
273
+ match self {
274
+ & Io ( ref io) => io. description ( ) ,
275
+ & TerminfoParsing ( ref e) => e. description ( ) ,
276
+ & ParameterizedExpansion ( ref e) => e. description ( ) ,
277
+ & NotSupported => "operation not supported by the terminal" ,
278
+ & TermUnset => "TERM environment variable unset, unable to detect a terminal" ,
279
+ & TerminfoEntryNotFound => "could not find a terminfo entry for this terminal" ,
280
+ & CursorDestinationInvalid => "could not move cursor to requested position" ,
281
+ & ColorOutOfRange => "color not supported by the terminal" ,
282
+ & __Nonexhaustive => "placeholder variant that shouldn't be used" ,
283
+ }
284
+ }
285
+
286
+ fn cause ( & self ) -> Option < & std:: error:: Error > {
287
+ match self {
288
+ & Error :: Io ( ref io) => Some ( io) ,
289
+ & Error :: TerminfoParsing ( ref e) => Some ( e) ,
290
+ & Error :: ParameterizedExpansion ( ref e) => Some ( e) ,
291
+ _ => None ,
292
+ }
293
+ }
294
+ }
295
+
296
+ impl From < Error > for io:: Error {
297
+ fn from ( err : Error ) -> io:: Error {
298
+ let kind = match & err {
299
+ & Error :: Io ( ref e) => e. kind ( ) ,
300
+ _ => io:: ErrorKind :: Other ,
301
+ } ;
302
+ io:: Error :: new ( kind, err)
303
+ }
304
+ }
305
+
306
+ impl std:: convert:: From < io:: Error > for Error {
307
+ fn from ( val : io:: Error ) -> Self {
308
+ Error :: Io ( val)
309
+ }
310
+ }
311
+
312
+ impl std:: convert:: From < terminfo:: Error > for Error {
313
+ fn from ( val : terminfo:: Error ) -> Self {
314
+ Error :: TerminfoParsing ( val)
315
+ }
316
+ }
317
+
318
+ impl std:: convert:: From < terminfo:: parm:: Error > for Error {
319
+ fn from ( val : terminfo:: parm:: Error ) -> Self {
320
+ Error :: ParameterizedExpansion ( val)
321
+ }
322
+ }
323
+
169
324
/// A terminal with similar capabilities to an ANSI Terminal
170
325
/// (foreground/background colors etc).
171
326
pub trait Terminal : Write {
@@ -177,38 +332,62 @@ pub trait Terminal: Write {
177
332
/// If the color is a bright color, but the terminal only supports 8 colors,
178
333
/// the corresponding normal color will be used instead.
179
334
///
180
- /// Returns `Ok(true) ` if the color was set, `Ok(false)` otherwise, and `Err(e)`
181
- /// if there was an I/O error.
182
- fn fg ( & mut self , color : color:: Color ) -> io :: Result < bool > ;
335
+ /// Returns `Ok(()) ` if the color change code was sent to the terminal, or `Err(e)` if there
336
+ /// was an error.
337
+ fn fg ( & mut self , color : color:: Color ) -> Result < ( ) > ;
183
338
184
339
/// Sets the background color to the given color.
185
340
///
186
341
/// If the color is a bright color, but the terminal only supports 8 colors,
187
342
/// the corresponding normal color will be used instead.
188
343
///
189
- /// Returns `Ok(true) ` if the color was set, `Ok(false)` otherwise, and `Err(e)`
190
- /// if there was an I/O error.
191
- fn bg ( & mut self , color : color:: Color ) -> io :: Result < bool > ;
344
+ /// Returns `Ok(()) ` if the color change code was sent to the terminal, or `Err(e)` if there
345
+ /// was an error.
346
+ fn bg ( & mut self , color : color:: Color ) -> Result < ( ) > ;
192
347
193
- /// Sets the given terminal attribute, if supported. Returns `Ok(true)`
194
- /// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if
195
- /// there was an I/O error .
196
- fn attr ( & mut self , attr : Attr ) -> io :: Result < bool > ;
348
+ /// Sets the given terminal attribute, if supported. Returns `Ok(())` if the attribute is
349
+ /// supported and was sent to the terminal, or `Err(e)` if there was an error or the attribute
350
+ /// wasn't supported .
351
+ fn attr ( & mut self , attr : Attr ) -> Result < ( ) > ;
197
352
198
353
/// Returns whether the given terminal attribute is supported.
199
354
fn supports_attr ( & self , attr : Attr ) -> bool ;
200
355
201
356
/// Resets all terminal attributes and colors to their defaults.
202
357
///
203
- /// Returns `Ok(true)` if the terminal was reset, `Ok(false)` otherwise, and `Err(e)` if there
204
- /// was an I/O error.
358
+ /// Returns `Ok(())` if the reset code was printed, or `Err(e)` if there was an error.
205
359
///
206
360
/// *Note: This does not flush.*
207
361
///
208
362
/// That means the reset command may get buffered so, if you aren't planning on doing anything
209
363
/// else that might flush stdout's buffer (e.g. writing a line of text), you should flush after
210
364
/// calling reset.
211
- fn reset ( & mut self ) -> io:: Result < bool > ;
365
+ fn reset ( & mut self ) -> Result < ( ) > ;
366
+
367
+ /// Returns true if reset is supported.
368
+ fn supports_reset ( & self ) -> bool ;
369
+
370
+ /// Returns true if color is fully supported.
371
+ ///
372
+ /// If this function returns `true`, `bg`, `fg`, and `reset` will never
373
+ /// return `Err(Error::NotSupported)`.
374
+ fn supports_color ( & self ) -> bool ;
375
+
376
+ /// Moves the cursor up one line.
377
+ ///
378
+ /// Returns `Ok(())` if the cursor movement code was printed, or `Err(e)` if there was an
379
+ /// error.
380
+ fn cursor_up ( & mut self ) -> Result < ( ) > ;
381
+
382
+ /// Deletes the text from the cursor location to the end of the line.
383
+ ///
384
+ /// Returns `Ok(())` if the deletion code was printed, or `Err(e)` if there was an error.
385
+ fn delete_line ( & mut self ) -> Result < ( ) > ;
386
+
387
+ /// Moves the cursor to the left edge of the current line.
388
+ ///
389
+ /// Returns `Ok(true)` if the deletion code was printed, or `Err(e)` if there was an error.
390
+ fn carriage_return ( & mut self ) -> Result < ( ) > ;
212
391
213
392
/// Gets an immutable reference to the stream inside
214
393
fn get_ref < ' a > ( & ' a self ) -> & ' a Self :: Output ;
0 commit comments