Skip to content

Commit cc238a3

Browse files
committed
term: synchronize with public "term" crate v0.4.4
The only point of divergence from the public crate is that this patch uses `std::sys::windows` instead of the `winapi` and `kernel32` crate to access the Windows Console APIs.
1 parent 7f1b282 commit cc238a3

File tree

6 files changed

+791
-398
lines changed

6 files changed

+791
-398
lines changed

src/libterm/lib.rs

+193-14
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
//! t.fg(term::color::RED).unwrap();
3333
//! writeln!(t, "world!").unwrap();
3434
//!
35-
//! assert!(t.reset().unwrap());
35+
//! t.reset().unwrap();
3636
//! }
3737
//! ```
3838
//!
@@ -166,6 +166,161 @@ pub enum Attr {
166166
BackgroundColor(color::Color),
167167
}
168168

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+
169324
/// A terminal with similar capabilities to an ANSI Terminal
170325
/// (foreground/background colors etc).
171326
pub trait Terminal: Write {
@@ -177,38 +332,62 @@ pub trait Terminal: Write {
177332
/// If the color is a bright color, but the terminal only supports 8 colors,
178333
/// the corresponding normal color will be used instead.
179334
///
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<()>;
183338

184339
/// Sets the background color to the given color.
185340
///
186341
/// If the color is a bright color, but the terminal only supports 8 colors,
187342
/// the corresponding normal color will be used instead.
188343
///
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<()>;
192347

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<()>;
197352

198353
/// Returns whether the given terminal attribute is supported.
199354
fn supports_attr(&self, attr: Attr) -> bool;
200355

201356
/// Resets all terminal attributes and colors to their defaults.
202357
///
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.
205359
///
206360
/// *Note: This does not flush.*
207361
///
208362
/// That means the reset command may get buffered so, if you aren't planning on doing anything
209363
/// else that might flush stdout's buffer (e.g. writing a line of text), you should flush after
210364
/// 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<()>;
212391

213392
/// Gets an immutable reference to the stream inside
214393
fn get_ref<'a>(&'a self) -> &'a Self::Output;

0 commit comments

Comments
 (0)