summaryrefslogtreecommitdiffstats
path: root/vendor/yansi-term/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /vendor/yansi-term/src
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/yansi-term/src')
-rw-r--r--vendor/yansi-term/src/ansi.rs290
-rw-r--r--vendor/yansi-term/src/display.rs80
-rw-r--r--vendor/yansi-term/src/lib.rs168
-rw-r--r--vendor/yansi-term/src/style.rs541
-rw-r--r--vendor/yansi-term/src/windows.rs61
5 files changed, 1140 insertions, 0 deletions
diff --git a/vendor/yansi-term/src/ansi.rs b/vendor/yansi-term/src/ansi.rs
new file mode 100644
index 000000000..159038d38
--- /dev/null
+++ b/vendor/yansi-term/src/ansi.rs
@@ -0,0 +1,290 @@
+use std::fmt::{self, Display, Write};
+
+use crate::{Colour, Style};
+
+impl Style {
+ /// Write any bytes that go *before* a piece of text to the given writer.
+ pub fn write_prefix(&self, f: &mut fmt::Formatter) -> Result<bool, fmt::Error> {
+ let mut written_anything = false;
+ macro_rules! write_anything {
+ () => {
+ if written_anything {
+ f.write_char(';')?;
+ } else {
+ // Write the codes’ prefix, then write numbers, separated by
+ // semicolons, for each text style we want to apply.
+ f.write_str("\x1B[")?;
+ written_anything = true;
+ }
+ };
+ }
+ macro_rules! write_char {
+ ($cond:ident, $c:expr) => {
+ if self.$cond {
+ write_anything!();
+ f.write_char($c)?;
+ }
+ };
+ }
+ macro_rules! write_chars {
+ ($cond:ident => $c:expr) => { write_char!($cond, $c); };
+ ($cond:ident => $c:expr, $($t:tt)+) => {
+ write_char!($cond, $c);
+ write_chars!($($t)+);
+ };
+ }
+
+ write_chars!(
+ is_bold => '1',
+ is_dimmed => '2',
+ is_italic => '3',
+ is_underline => '4',
+ is_blink => '5',
+ is_reverse => '7',
+ is_hidden => '8',
+ is_strikethrough => '9'
+ );
+
+ // The foreground and background colours, if specified, need to be
+ // handled specially because the number codes are more complicated.
+ // (see `write_background_code` and `write_foreground_code`)
+ if let Some(bg) = self.background {
+ write_anything!();
+ bg.write_background_code(f)?;
+ }
+
+ if let Some(fg) = self.foreground {
+ write_anything!();
+ fg.write_foreground_code(f)?;
+ }
+
+ if written_anything {
+ // All the codes end with an `m`, because reasons.
+ f.write_char('m')?;
+ }
+
+ Ok(written_anything)
+ }
+
+ /// Write any bytes that go *after* a piece of text to the given writer.
+ #[inline]
+ pub fn write_reset(f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str(RESET)
+ }
+}
+
+impl Colour {
+ /// Write any bytes that go *before* a piece of text to the given writer.
+ #[inline]
+ pub fn write_prefix(self, f: &mut fmt::Formatter) -> Result<bool, fmt::Error> {
+ self.normal().write_prefix(f)
+ }
+}
+
+/// The code to send to reset all styles and return to `Style::default()`.
+pub static RESET: &str = "\x1B[0m";
+
+macro_rules! write_color {
+ ($_self:ident, $f:ident =>
+ $black:expr, $red:expr, $green:expr, $yellow:expr, $blue:expr,
+ $purple:expr, $cyan:expr, $white:expr, $fixed:expr, $rgb:expr) => {{
+ use Colour::*;
+ match $_self {
+ Black => $f.write_str($black),
+ Red => $f.write_str($red),
+ Green => $f.write_str($green),
+ Yellow => $f.write_str($yellow),
+ Blue => $f.write_str($blue),
+ Purple => $f.write_str($purple),
+ Cyan => $f.write_str($cyan),
+ White => $f.write_str($white),
+ Fixed(num) => {
+ $f.write_str($fixed)?;
+ num.fmt($f)
+ }
+ RGB(r, g, b) => {
+ $f.write_str($rgb)?;
+ r.fmt($f)?;
+ $f.write_char(';')?;
+ g.fmt($f)?;
+ $f.write_char(';')?;
+ b.fmt($f)
+ }
+ }
+ }};
+}
+
+impl Colour {
+ #[inline]
+ fn write_foreground_code(self, f: &mut fmt::Formatter) -> fmt::Result {
+ write_color!(self, f => "30", "31", "32", "33", "34", "35", "36", "37", "38;5;", "38;2;")
+ }
+
+ #[inline]
+ fn write_background_code(self, f: &mut fmt::Formatter) -> fmt::Result {
+ write_color!(self, f => "40", "41", "42", "43", "44", "45", "46", "47", "48;5;", "48;2;")
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use crate::{Colour::*, Style};
+
+ macro_rules! test {
+ ($name: ident: $style: expr; $input: expr => $result: expr) => {
+ #[test]
+ fn $name() {
+ assert_eq!($style.paint($input).to_string(), $result.to_string());
+ }
+ };
+ }
+
+ test!(plain: Style::default(); "text/plain" => "text/plain");
+ test!(red: Red; "hi" => "\x1B[31mhi\x1B[0m");
+ test!(black: Black.normal(); "hi" => "\x1B[30mhi\x1B[0m");
+ test!(yellow_bold: Yellow.bold(); "hi" => "\x1B[1;33mhi\x1B[0m");
+ test!(yellow_bold_2: Yellow.normal().bold(); "hi" => "\x1B[1;33mhi\x1B[0m");
+ test!(blue_underline: Blue.underline(); "hi" => "\x1B[4;34mhi\x1B[0m");
+ test!(green_bold_ul: Green.bold().underline(); "hi" => "\x1B[1;4;32mhi\x1B[0m");
+ test!(green_bold_ul_2: Green.underline().bold(); "hi" => "\x1B[1;4;32mhi\x1B[0m");
+ test!(purple_on_white: Purple.on(White); "hi" => "\x1B[47;35mhi\x1B[0m");
+ test!(purple_on_white_2: Purple.normal().on(White); "hi" => "\x1B[47;35mhi\x1B[0m");
+ test!(yellow_on_blue: Style::new().on(Blue).fg(Yellow); "hi" => "\x1B[44;33mhi\x1B[0m");
+ test!(yellow_on_blue_2: Cyan.on(Blue).fg(Yellow); "hi" => "\x1B[44;33mhi\x1B[0m");
+ test!(cyan_bold_on_white: Cyan.bold().on(White); "hi" => "\x1B[1;47;36mhi\x1B[0m");
+ test!(cyan_ul_on_white: Cyan.underline().on(White); "hi" => "\x1B[4;47;36mhi\x1B[0m");
+ test!(cyan_bold_ul_on_white: Cyan.bold().underline().on(White); "hi" => "\x1B[1;4;47;36mhi\x1B[0m");
+ test!(cyan_ul_bold_on_white: Cyan.underline().bold().on(White); "hi" => "\x1B[1;4;47;36mhi\x1B[0m");
+ test!(fixed: Fixed(100); "hi" => "\x1B[38;5;100mhi\x1B[0m");
+ test!(fixed_on_purple: Fixed(100).on(Purple); "hi" => "\x1B[45;38;5;100mhi\x1B[0m");
+ test!(fixed_on_fixed: Fixed(100).on(Fixed(200)); "hi" => "\x1B[48;5;200;38;5;100mhi\x1B[0m");
+ test!(rgb: RGB(70,130,180); "hi" => "\x1B[38;2;70;130;180mhi\x1B[0m");
+ test!(rgb_on_blue: RGB(70,130,180).on(Blue); "hi" => "\x1B[44;38;2;70;130;180mhi\x1B[0m");
+ test!(blue_on_rgb: Blue.on(RGB(70,130,180)); "hi" => "\x1B[48;2;70;130;180;34mhi\x1B[0m");
+ test!(rgb_on_rgb: RGB(70,130,180).on(RGB(5,10,15)); "hi" => "\x1B[48;2;5;10;15;38;2;70;130;180mhi\x1B[0m");
+ test!(bold: Style::new().bold(); "hi" => "\x1B[1mhi\x1B[0m");
+ test!(underline: Style::new().underline(); "hi" => "\x1B[4mhi\x1B[0m");
+ test!(bunderline: Style::new().bold().underline(); "hi" => "\x1B[1;4mhi\x1B[0m");
+ test!(dimmed: Style::new().dimmed(); "hi" => "\x1B[2mhi\x1B[0m");
+ test!(italic: Style::new().italic(); "hi" => "\x1B[3mhi\x1B[0m");
+ test!(blink: Style::new().blink(); "hi" => "\x1B[5mhi\x1B[0m");
+ test!(reverse: Style::new().reverse(); "hi" => "\x1B[7mhi\x1B[0m");
+ test!(hidden: Style::new().hidden(); "hi" => "\x1B[8mhi\x1B[0m");
+ test!(stricken: Style::new().strikethrough(); "hi" => "\x1B[9mhi\x1B[0m");
+
+ macro_rules! test_fn {
+ ($name:ident: $style:expr; $result:expr) => {
+ #[test]
+ fn $name() {
+ let string = String::from("hi");
+ let string: &str = &string;
+ assert_eq!(
+ $style.paint_fn(|f| f.write_str(string)).to_string(),
+ $result.to_string()
+ );
+ }
+ };
+ }
+
+ test_fn!(plain_fn: Style::default(); "hi");
+ test_fn!(red_fn: Red; "\x1B[31mhi\x1B[0m");
+ test_fn!(black_fn: Black.normal(); "\x1B[30mhi\x1B[0m");
+ test_fn!(yellow_bold_fn: Yellow.bold(); "\x1B[1;33mhi\x1B[0m");
+ test_fn!(yellow_bold_2_fn: Yellow.normal().bold(); "\x1B[1;33mhi\x1B[0m");
+ test_fn!(blue_underline_fn: Blue.underline(); "\x1B[4;34mhi\x1B[0m");
+ test_fn!(green_bold_ul_fn: Green.bold().underline(); "\x1B[1;4;32mhi\x1B[0m");
+ test_fn!(green_bold_ul_2_fn: Green.underline().bold(); "\x1B[1;4;32mhi\x1B[0m");
+ test_fn!(purple_on_white_fn: Purple.on(White); "\x1B[47;35mhi\x1B[0m");
+ test_fn!(purple_on_white_2_fn: Purple.normal().on(White); "\x1B[47;35mhi\x1B[0m");
+ test_fn!(yellow_on_blue_fn: Style::new().on(Blue).fg(Yellow); "\x1B[44;33mhi\x1B[0m");
+ test_fn!(yellow_on_blue_2_fn: Cyan.on(Blue).fg(Yellow); "\x1B[44;33mhi\x1B[0m");
+ test_fn!(cyan_bold_on_white_fn: Cyan.bold().on(White); "\x1B[1;47;36mhi\x1B[0m");
+ test_fn!(cyan_ul_on_white_fn: Cyan.underline().on(White); "\x1B[4;47;36mhi\x1B[0m");
+ test_fn!(cyan_bold_ul_on_white_fn: Cyan.bold().underline().on(White); "\x1B[1;4;47;36mhi\x1B[0m");
+ test_fn!(cyan_ul_bold_on_white_fn: Cyan.underline().bold().on(White); "\x1B[1;4;47;36mhi\x1B[0m");
+ test_fn!(fixed_fn: Fixed(100); "\x1B[38;5;100mhi\x1B[0m");
+ test_fn!(fixed_on_purple_fn: Fixed(100).on(Purple); "\x1B[45;38;5;100mhi\x1B[0m");
+ test_fn!(fixed_on_fixed_fn: Fixed(100).on(Fixed(200)); "\x1B[48;5;200;38;5;100mhi\x1B[0m");
+ test_fn!(rgb_fn: RGB(70,130,180); "\x1B[38;2;70;130;180mhi\x1B[0m");
+ test_fn!(rgb_on_blue_fn: RGB(70,130,180).on(Blue); "\x1B[44;38;2;70;130;180mhi\x1B[0m");
+ test_fn!(blue_on_rgb_fn: Blue.on(RGB(70,130,180)); "\x1B[48;2;70;130;180;34mhi\x1B[0m");
+ test_fn!(rgb_on_rgb_fn: RGB(70,130,180).on(RGB(5,10,15)); "\x1B[48;2;5;10;15;38;2;70;130;180mhi\x1B[0m");
+ test_fn!(bold_fn: Style::new().bold(); "\x1B[1mhi\x1B[0m");
+ test_fn!(underline_fn: Style::new().underline(); "\x1B[4mhi\x1B[0m");
+ test_fn!(bunderline_fn: Style::new().bold().underline(); "\x1B[1;4mhi\x1B[0m");
+ test_fn!(dimmed_fn: Style::new().dimmed(); "\x1B[2mhi\x1B[0m");
+ test_fn!(italic_fn: Style::new().italic(); "\x1B[3mhi\x1B[0m");
+ test_fn!(blink_fn: Style::new().blink(); "\x1B[5mhi\x1B[0m");
+ test_fn!(reverse_fn: Style::new().reverse(); "\x1B[7mhi\x1B[0m");
+ test_fn!(hidden_fn: Style::new().hidden(); "\x1B[8mhi\x1B[0m");
+ test_fn!(stricken_fn: Style::new().strikethrough(); "\x1B[9mhi\x1B[0m");
+
+ #[test]
+ fn test_move() {
+ let string = String::from("hi");
+ assert_eq!(
+ Style::default()
+ .paint_fn(|f| f.write_str(&string))
+ .to_string(),
+ "hi"
+ );
+ }
+
+ #[test]
+ fn test_ref() {
+ let string = &String::from("hi");
+ assert_eq!(
+ Style::default()
+ .paint_fn(|f| f.write_str(string))
+ .to_string(),
+ "hi"
+ );
+ }
+
+ #[test]
+ fn test_debug() {
+ let a = vec![1, 2, 3];
+ assert_eq!(
+ Style::default()
+ .paint_fn(|f| std::fmt::Debug::fmt(&a, f))
+ .to_string(),
+ "[1, 2, 3]"
+ );
+ assert_eq!(
+ Style::default()
+ .bold()
+ .paint_fn(|f| std::fmt::Debug::fmt(&a, f))
+ .to_string(),
+ "\x1B[1m[1, 2, 3]\x1B[0m"
+ );
+ }
+
+ #[test]
+ fn test_write() {
+ assert_eq!(
+ Style::default()
+ .paint_fn(|f| write!(f, "{:.5}", 1.0))
+ .to_string(),
+ "1.00000"
+ );
+ assert_eq!(
+ Style::default()
+ .bold()
+ .paint_fn(|f| write!(f, "{:.5}", 1.0))
+ .to_string(),
+ "\x1B[1m1.00000\x1B[0m"
+ );
+ }
+
+ /// Can not write the same `impl Display` two or more times
+ /// else return error
+ #[test]
+ fn test_error() {
+ use std::fmt::Write;
+ let a = Style::default().paint("foo");
+ let _ = a.to_string();
+ let mut b = String::new();
+
+ assert!(write!(b, "{}", a).is_err());
+ }
+}
diff --git a/vendor/yansi-term/src/display.rs b/vendor/yansi-term/src/display.rs
new file mode 100644
index 000000000..afc4e2846
--- /dev/null
+++ b/vendor/yansi-term/src/display.rs
@@ -0,0 +1,80 @@
+use std::{cell::Cell, fmt};
+
+use crate::{Colour, Style};
+
+/// An `DisplayANSI` includes a format function and a `Style`
+struct DisplayANSI<F: FnOnce(&mut fmt::Formatter) -> fmt::Result> {
+ style: Style,
+ f: Cell<Option<F>>,
+}
+
+impl<F: FnOnce(&mut fmt::Formatter) -> fmt::Result> fmt::Display for DisplayANSI<F> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let written = self.style.write_prefix(f)?;
+ self.f.take().ok_or(fmt::Error).and_then(|c| c(f))?;
+ if written {
+ Style::write_reset(f)?;
+ }
+ Ok(())
+ }
+}
+
+impl Style {
+ /// Paints the given text with this style
+ #[inline]
+ pub fn paint<'a>(self, input: &'a str) -> impl fmt::Display + 'a {
+ DisplayANSI {
+ f: Cell::new(Some(move |f: &mut fmt::Formatter| f.write_str(input))),
+ style: self,
+ }
+ }
+
+ /// Paints the given format function with this style
+ #[inline]
+ pub fn paint_fn<F: FnOnce(&mut fmt::Formatter) -> fmt::Result>(
+ self,
+ f: F,
+ ) -> impl fmt::Display {
+ DisplayANSI {
+ f: Cell::new(Some(f)),
+ style: self,
+ }
+ }
+}
+
+impl Colour {
+ /// Paints the given text with this colour
+ /// This is a short-cut so you don’t have to use `Blue.normal()` just
+ /// to get blue text.
+ ///
+ /// ```
+ /// use yansi_term::Colour::Blue;
+ /// println!("{}", Blue.paint("da ba dee"));
+ /// ```
+ #[inline]
+ pub fn paint<'a>(self, input: &'a str) -> impl fmt::Display + 'a {
+ self.normal().paint(input)
+ }
+
+ /// Paints the given format function with this colour
+ #[inline]
+ pub fn paint_fn<F: FnOnce(&mut fmt::Formatter) -> fmt::Result>(
+ self,
+ f: F,
+ ) -> impl fmt::Display {
+ self.normal().paint_fn(f)
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn no_control_codes_for_plain() {
+ let one = Style::default().paint("one");
+ let two = Style::default().paint("two");
+ let output = format!("{}{}", one, two);
+ assert_eq!(output, "onetwo");
+ }
+}
diff --git a/vendor/yansi-term/src/lib.rs b/vendor/yansi-term/src/lib.rs
new file mode 100644
index 000000000..588ce6344
--- /dev/null
+++ b/vendor/yansi-term/src/lib.rs
@@ -0,0 +1,168 @@
+//! > Adapted from [`rust-ansi-term`](https://github.com/ogham/rust-ansi-term)
+//! >
+//! > Refactor for use [`fmt::Display`](https://doc.rust-lang.org/std/fmt/trait.Display.html)
+//! and `FnOnce(&mut fmt::Formatter) -> fmt::Result`
+//! This is a library for controlling colours and formatting, such as
+//! red bold text or blue underlined text, on ANSI terminals.
+//!
+//!
+//! ## Basic usage
+//!
+//! There are three main types in this crate that you need to be
+//! concerned with: [`ANSIString`], [`Style`], and [`Colour`].
+//!
+//! A `Style` holds stylistic information: foreground and background colours,
+//! whether the text should be bold, or blinking, or other properties. The
+//! [`Colour`] enum represents the available colours. And an [`ANSIString`] is a
+//! string paired with a [`Style`].
+//!
+//! [`Color`] is also available as an alias to `Colour`.
+//!
+//! To format a string, call the `paint` method on a `Style` or a `Colour`,
+//! passing in the string you want to format as the argument. For example,
+//! here’s how to get some red text:
+//!
+//! ```
+//! use yansi_term::Colour::Red;
+//!
+//! println!("This is in red: {}", Red.paint("a red string"));
+//! ```
+//!
+//! It’s important to note that the `paint` method does *not* actually return a
+//! string with the ANSI control characters surrounding it. Instead, it returns
+//! that has a [`Display`] implementation that, when formatted, returns the characters.
+//! ```
+//! use yansi_term::Colour::Red;
+//!
+//! let red_string = Red.paint("a red string").to_string();
+//! ```
+//!
+//!
+//! ## Bold, underline, background, and other styles
+//!
+//! For anything more complex than plain foreground colour changes, you need to
+//! construct `Style` values themselves, rather than beginning with a `Colour`.
+//! You can do this by chaining methods based on a new `Style`, created with
+//! [`Style::new()`]. Each method creates a new style that has that specific
+//! property set. For example:
+//!
+//! ```
+//! use yansi_term::Style;
+//!
+//! println!("How about some {} and {}?",
+//! Style::new().bold().paint("bold"),
+//! Style::new().underline().paint("underline"));
+//! ```
+//!
+//! For brevity, these methods have also been implemented for `Colour` values,
+//! so you can give your styles a foreground colour without having to begin with
+//! an empty `Style` value:
+//!
+//! ```
+//! use yansi_term::Colour::{Blue, Yellow};
+//!
+//! println!("Demonstrating {} and {}!",
+//! Blue.bold().paint("blue bold"),
+//! Yellow.underline().paint("yellow underline"));
+//!
+//! println!("Yellow on blue: {}", Yellow.on(Blue).paint("wow!"));
+//! ```
+//!
+//! The complete list of styles you can use are: [`bold`], [`dimmed`], [`italic`],
+//! [`underline`], [`blink`], [`reverse`], [`hidden`], [`strikethrough`], and [`on`] for
+//! background colours.
+//!
+//! In some cases, you may find it easier to change the foreground on an
+//! existing `Style` rather than starting from the appropriate `Colour`.
+//! You can do this using the [`fg`] method:
+//!
+//! ```
+//! use yansi_term::Style;
+//! use yansi_term::Colour::{Blue, Cyan, Yellow};
+//!
+//! println!("Yellow on blue: {}", Style::new().on(Blue).fg(Yellow).paint("yow!"));
+//! println!("Also yellow on blue: {}", Cyan.on(Blue).fg(Yellow).paint("zow!"));
+//! ```
+//!
+//! You can turn a `Colour` into a `Style` with the [`normal`] method.
+//! This will produce the exact same `ANSIString` as if you just used the
+//! `paint` method on the `Colour` directly, but it’s useful in certain cases:
+//! for example, you may have a method that returns `Styles`, and need to
+//! represent both the “red bold” and “red, but not bold” styles with values of
+//! the same type. The `Style` struct also has a [`Default`] implementation if you
+//! want to have a style with *nothing* set.
+//!
+//! ```
+//! use yansi_term::Style;
+//! use yansi_term::Colour::Red;
+//!
+//! Red.normal().paint("yet another red string");
+//! Style::default().paint("a completely regular string");
+//! ```
+//!
+//!
+//! ## Extended colours
+//!
+//! You can access the extended range of 256 colours by using the `Colour::Fixed`
+//! variant, which takes an argument of the colour number to use. This can be
+//! included wherever you would use a `Colour`:
+//!
+//! ```
+//! use yansi_term::Colour::Fixed;
+//!
+//! Fixed(134).paint("A sort of light purple");
+//! Fixed(221).on(Fixed(124)).paint("Mustard in the ketchup");
+//! ```
+//!
+//! The first sixteen of these values are the same as the normal and bold
+//! standard colour variants. There’s nothing stopping you from using these as
+//! `Fixed` colours instead, but there’s nothing to be gained by doing so
+//! either.
+//!
+//! You can also access full 24-bit colour by using the `Colour::RGB` variant,
+//! which takes separate `u8` arguments for red, green, and blue:
+//!
+//! ```
+//! use yansi_term::Colour::RGB;
+//!
+//! RGB(70, 130, 180).paint("Steel blue");
+//! ```
+
+//! [`Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html
+//! [`Default`]: https://doc.rust-lang.org/std/default/trait.Default.html
+//! [`Style`]: struct.Style.html
+//! [`Style::new()`]: struct.Style.html#method.new
+//! [`Color`]: enum.Color.html
+//! [`Colour`]: enum.Colour.html
+//!
+//! [`bold`]: struct.Style.html#method.bold
+//! [`dimmed`]: struct.Style.html#method.dimmed
+//! [`italic`]: struct.Style.html#method.italic
+//! [`underline`]: struct.Style.html#method.underline
+//! [`blink`]: struct.Style.html#method.blink
+//! [`reverse`]: struct.Style.html#method.reverse
+//! [`hidden`]: struct.Style.html#method.hidden
+//! [`strikethrough`]: struct.Style.html#method.strikethrough
+//! [`fg`]: struct.Style.html#method.fg
+//! [`on`]: struct.Style.html#method.on
+
+#[cfg(target_os = "windows")]
+extern crate winapi;
+#[cfg(test)]
+#[macro_use]
+extern crate doc_comment;
+
+#[cfg(test)]
+doctest!("../README.md");
+
+mod ansi;
+mod style;
+pub use style::{Colour, Style};
+
+/// Color is a type alias for `Colour`.
+pub use Colour as Color;
+
+mod display;
+
+mod windows;
+pub use windows::*;
diff --git a/vendor/yansi-term/src/style.rs b/vendor/yansi-term/src/style.rs
new file mode 100644
index 000000000..aaef739f9
--- /dev/null
+++ b/vendor/yansi-term/src/style.rs
@@ -0,0 +1,541 @@
+/// A style is a collection of properties that can format a string
+/// using ANSI escape codes.
+///
+/// # Examples
+///
+/// ```
+/// use yansi_term::{Style, Colour};
+///
+/// let style = Style::new().bold().on(Colour::Black);
+/// println!("{}", style.paint("Bold on black"));
+/// ```
+#[derive(PartialEq, Clone, Copy, Default, Debug)]
+#[cfg_attr(
+ feature = "derive_serde_style",
+ derive(serde::Deserialize, serde::Serialize)
+)]
+pub struct Style {
+ /// The style's foreground colour, if it has one.
+ pub foreground: Option<Colour>,
+
+ /// The style's background colour, if it has one.
+ pub background: Option<Colour>,
+
+ /// Whether this style is bold.
+ pub is_bold: bool,
+
+ /// Whether this style is dimmed.
+ pub is_dimmed: bool,
+
+ /// Whether this style is italic.
+ pub is_italic: bool,
+
+ /// Whether this style is underlined.
+ pub is_underline: bool,
+
+ /// Whether this style is blinking.
+ pub is_blink: bool,
+
+ /// Whether this style has reverse colours.
+ pub is_reverse: bool,
+
+ /// Whether this style is hidden.
+ pub is_hidden: bool,
+
+ /// Whether this style is struckthrough.
+ pub is_strikethrough: bool,
+}
+
+impl Style {
+ /// Creates a new Style with no properties set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Style;
+ ///
+ /// let style = Style::new();
+ /// println!("{}", style.paint("hi"));
+ /// ```
+ pub fn new() -> Style {
+ Style::default()
+ }
+
+ /// Returns a `Style` with the bold property set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Style;
+ ///
+ /// let style = Style::new().bold();
+ /// println!("{}", style.paint("hey"));
+ /// ```
+ pub fn bold(mut self) -> Self {
+ self.is_bold = true;
+ self
+ }
+
+ /// Returns a `Style` with the dimmed property set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Style;
+ ///
+ /// let style = Style::new().dimmed();
+ /// println!("{}", style.paint("sup"));
+ /// ```
+ pub fn dimmed(mut self) -> Self {
+ self.is_dimmed = true;
+ self
+ }
+
+ /// Returns a `Style` with the italic property set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Style;
+ ///
+ /// let style = Style::new().italic();
+ /// println!("{}", style.paint("greetings"));
+ /// ```
+ pub fn italic(mut self) -> Self {
+ self.is_italic = true;
+ self
+ }
+
+ /// Returns a `Style` with the underline property set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Style;
+ ///
+ /// let style = Style::new().underline();
+ /// println!("{}", style.paint("salutations"));
+ /// ```
+ pub fn underline(mut self) -> Self {
+ self.is_underline = true;
+ self
+ }
+
+ /// Returns a `Style` with the blink property set.
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Style;
+ ///
+ /// let style = Style::new().blink();
+ /// println!("{}", style.paint("wazzup"));
+ /// ```
+ pub fn blink(mut self) -> Self {
+ self.is_blink = true;
+ self
+ }
+
+ /// Returns a `Style` with the reverse property set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Style;
+ ///
+ /// let style = Style::new().reverse();
+ /// println!("{}", style.paint("aloha"));
+ /// ```
+ pub fn reverse(mut self) -> Self {
+ self.is_reverse = true;
+ self
+ }
+
+ /// Returns a `Style` with the hidden property set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Style;
+ ///
+ /// let style = Style::new().hidden();
+ /// println!("{}", style.paint("ahoy"));
+ /// ```
+ pub fn hidden(mut self) -> Self {
+ self.is_hidden = true;
+ self
+ }
+
+ /// Returns a `Style` with the strikethrough property set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Style;
+ ///
+ /// let style = Style::new().strikethrough();
+ /// println!("{}", style.paint("yo"));
+ /// ```
+ pub fn strikethrough(mut self) -> Self {
+ self.is_strikethrough = true;
+ self
+ }
+
+ /// Returns a `Style` with the foreground colour property set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::{Style, Colour};
+ ///
+ /// let style = Style::new().fg(Colour::Yellow);
+ /// println!("{}", style.paint("hi"));
+ /// ```
+ pub fn fg(mut self, foreground: Colour) -> Self {
+ self.foreground = Some(foreground);
+ self
+ }
+
+ /// Returns a `Style` with the background colour property set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::{Style, Colour};
+ ///
+ /// let style = Style::new().on(Colour::Blue);
+ /// println!("{}", style.paint("eyyyy"));
+ /// ```
+ pub fn on(mut self, background: Colour) -> Self {
+ self.background = Some(background);
+ self
+ }
+
+ /// Return true if this `Style` has no actual styles, and can be written
+ /// without any control characters.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Style;
+ ///
+ /// assert_eq!(true, Style::default().is_plain());
+ /// assert_eq!(false, Style::default().bold().is_plain());
+ /// ```
+ pub fn is_plain(&self) -> bool {
+ *self == Style::default()
+ }
+}
+
+/// A colour is one specific type of ANSI escape code, and can refer
+/// to either the foreground or background colour.
+///
+/// These use the standard numeric sequences.
+/// See <http://invisible-island.net/xterm/ctlseqs/ctlseqs.html>
+#[derive(PartialEq, Clone, Copy, Debug)]
+#[cfg_attr(
+ feature = "derive_serde_style",
+ derive(serde::Deserialize, serde::Serialize)
+)]
+pub enum Colour {
+ /// Colour #0 (foreground code `30`, background code `40`).
+ ///
+ /// This is not necessarily the background colour, and using it as one may
+ /// render the text hard to read on terminals with dark backgrounds.
+ Black,
+
+ /// Colour #1 (foreground code `31`, background code `41`).
+ Red,
+
+ /// Colour #2 (foreground code `32`, background code `42`).
+ Green,
+
+ /// Colour #3 (foreground code `33`, background code `43`).
+ Yellow,
+
+ /// Colour #4 (foreground code `34`, background code `44`).
+ Blue,
+
+ /// Colour #5 (foreground code `35`, background code `45`).
+ Purple,
+
+ /// Colour #6 (foreground code `36`, background code `46`).
+ Cyan,
+
+ /// Colour #7 (foreground code `37`, background code `47`).
+ ///
+ /// As above, this is not necessarily the foreground colour, and may be
+ /// hard to read on terminals with light backgrounds.
+ White,
+
+ /// A colour number from 0 to 255, for use in 256-colour terminal
+ /// environments.
+ ///
+ /// - Colours 0 to 7 are the `Black` to `White` variants respectively.
+ /// These colours can usually be changed in the terminal emulator.
+ /// - Colours 8 to 15 are brighter versions of the eight colours above.
+ /// These can also usually be changed in the terminal emulator, or it
+ /// could be configured to use the original colours and show the text in
+ /// bold instead. It varies depending on the program.
+ /// - Colours 16 to 231 contain several palettes of bright colours,
+ /// arranged in six squares measuring six by six each.
+ /// - Colours 232 to 255 are shades of grey from black to white.
+ ///
+ /// It might make more sense to look at a [colour chart][cc].
+ ///
+ /// [cc]: https://upload.wikimedia.org/wikipedia/commons/1/15/Xterm_256color_chart.svg
+ Fixed(u8),
+
+ /// A 24-bit RGB color, as specified by ISO-8613-3.
+ RGB(u8, u8, u8),
+}
+
+impl Colour {
+ /// Returns a `Style` with the foreground colour set to this colour.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Colour;
+ ///
+ /// let style = Colour::Red.normal();
+ /// println!("{}", style.paint("hi"));
+ /// ```
+ pub fn normal(self) -> Style {
+ Style {
+ foreground: Some(self),
+ ..Style::default()
+ }
+ }
+
+ /// Returns a `Style` with the foreground colour set to this colour and the
+ /// bold property set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Colour;
+ ///
+ /// let style = Colour::Green.bold();
+ /// println!("{}", style.paint("hey"));
+ /// ```
+ pub fn bold(self) -> Style {
+ Style {
+ foreground: Some(self),
+ is_bold: true,
+ ..Style::default()
+ }
+ }
+
+ /// Returns a `Style` with the foreground colour set to this colour and the
+ /// dimmed property set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Colour;
+ ///
+ /// let style = Colour::Yellow.dimmed();
+ /// println!("{}", style.paint("sup"));
+ /// ```
+ pub fn dimmed(self) -> Style {
+ Style {
+ foreground: Some(self),
+ is_dimmed: true,
+ ..Style::default()
+ }
+ }
+
+ /// Returns a `Style` with the foreground colour set to this colour and the
+ /// italic property set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Colour;
+ ///
+ /// let style = Colour::Blue.italic();
+ /// println!("{}", style.paint("greetings"));
+ /// ```
+ pub fn italic(self) -> Style {
+ Style {
+ foreground: Some(self),
+ is_italic: true,
+ ..Style::default()
+ }
+ }
+
+ /// Returns a `Style` with the foreground colour set to this colour and the
+ /// underline property set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Colour;
+ ///
+ /// let style = Colour::Purple.underline();
+ /// println!("{}", style.paint("salutations"));
+ /// ```
+ pub fn underline(self) -> Style {
+ Style {
+ foreground: Some(self),
+ is_underline: true,
+ ..Style::default()
+ }
+ }
+
+ /// Returns a `Style` with the foreground colour set to this colour and the
+ /// blink property set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Colour;
+ ///
+ /// let style = Colour::Cyan.blink();
+ /// println!("{}", style.paint("wazzup"));
+ /// ```
+ pub fn blink(self) -> Style {
+ Style {
+ foreground: Some(self),
+ is_blink: true,
+ ..Style::default()
+ }
+ }
+
+ /// Returns a `Style` with the foreground colour set to this colour and the
+ /// reverse property set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Colour;
+ ///
+ /// let style = Colour::Black.reverse();
+ /// println!("{}", style.paint("aloha"));
+ /// ```
+ pub fn reverse(self) -> Style {
+ Style {
+ foreground: Some(self),
+ is_reverse: true,
+ ..Style::default()
+ }
+ }
+
+ /// Returns a `Style` with the foreground colour set to this colour and the
+ /// hidden property set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Colour;
+ ///
+ /// let style = Colour::White.hidden();
+ /// println!("{}", style.paint("ahoy"));
+ /// ```
+ pub fn hidden(self) -> Style {
+ Style {
+ foreground: Some(self),
+ is_hidden: true,
+ ..Style::default()
+ }
+ }
+
+ /// Returns a `Style` with the foreground colour set to this colour and the
+ /// strikethrough property set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Colour;
+ ///
+ /// let style = Colour::Fixed(244).strikethrough();
+ /// println!("{}", style.paint("yo"));
+ /// ```
+ pub fn strikethrough(self) -> Style {
+ Style {
+ foreground: Some(self),
+ is_strikethrough: true,
+ ..Style::default()
+ }
+ }
+
+ /// Returns a `Style` with the foreground colour set to this colour and the
+ /// background colour property set to the given colour.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use yansi_term::Colour;
+ ///
+ /// let style = Colour::RGB(31, 31, 31).on(Colour::White);
+ /// println!("{}", style.paint("eyyyy"));
+ /// ```
+ pub fn on(self, background: Colour) -> Style {
+ Style {
+ foreground: Some(self),
+ background: Some(background),
+ ..Style::default()
+ }
+ }
+}
+
+impl From<Colour> for Style {
+ /// You can turn a `Colour` into a `Style` with the foreground colour set
+ /// with the `From` trait.
+ ///
+ /// ```
+ /// use yansi_term::{Style, Colour};
+ /// let green_foreground = Style::default().fg(Colour::Green);
+ /// assert_eq!(green_foreground, Colour::Green.normal());
+ /// assert_eq!(green_foreground, Colour::Green.into());
+ /// assert_eq!(green_foreground, Style::from(Colour::Green));
+ /// ```
+ fn from(colour: Colour) -> Style {
+ colour.normal()
+ }
+}
+
+#[cfg(test)]
+#[cfg(feature = "derive_serde_style")]
+mod serde_json_tests {
+ use super::{Colour, Style};
+
+ #[test]
+ fn colour_serialization() {
+ let colours = &[
+ Colour::Red,
+ Colour::Blue,
+ Colour::RGB(123, 123, 123),
+ Colour::Fixed(255),
+ ];
+
+ assert_eq!(
+ serde_json::to_string(&colours).unwrap(),
+ String::from("[\"Red\",\"Blue\",{\"RGB\":[123,123,123]},{\"Fixed\":255}]")
+ );
+ }
+
+ #[test]
+ fn colour_deserialization() {
+ let colours = &[
+ Colour::Red,
+ Colour::Blue,
+ Colour::RGB(123, 123, 123),
+ Colour::Fixed(255),
+ ];
+
+ for colour in colours {
+ let serialized = serde_json::to_string(&colour).unwrap();
+ let deserialized: Colour = serde_json::from_str(&serialized).unwrap();
+
+ assert_eq!(colour, &deserialized);
+ }
+ }
+
+ #[test]
+ fn style_serialization() {
+ let style = Style::default();
+
+ assert_eq!(serde_json::to_string(&style).unwrap(), "{\"foreground\":null,\"background\":null,\"is_bold\":false,\"is_dimmed\":false,\"is_italic\":false,\"is_underline\":false,\"is_blink\":false,\"is_reverse\":false,\"is_hidden\":false,\"is_strikethrough\":false}".to_string());
+ }
+}
diff --git a/vendor/yansi-term/src/windows.rs b/vendor/yansi-term/src/windows.rs
new file mode 100644
index 000000000..3df9ff4ac
--- /dev/null
+++ b/vendor/yansi-term/src/windows.rs
@@ -0,0 +1,61 @@
+/// Enables ANSI code support on Windows 10.
+///
+/// This uses Windows API calls to alter the properties of the console that
+/// the program is running in.
+///
+/// https://msdn.microsoft.com/en-us/library/windows/desktop/mt638032(v=vs.85).aspx
+///
+/// Returns a `Result` with the Windows error code if unsuccessful.
+#[cfg(windows)]
+pub fn enable_ansi_support() -> Result<(), u32> {
+ // ref: https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#EXAMPLE_OF_ENABLING_VIRTUAL_TERMINAL_PROCESSING @@ https://archive.is/L7wRJ#76%
+
+ use std::{ffi::OsStr, iter::once, os::windows::ffi::OsStrExt, ptr::null_mut};
+ use winapi::um::{
+ consoleapi::{GetConsoleMode, SetConsoleMode},
+ errhandlingapi::GetLastError,
+ fileapi::{CreateFileW, OPEN_EXISTING},
+ handleapi::INVALID_HANDLE_VALUE,
+ winnt::{FILE_SHARE_WRITE, GENERIC_READ, GENERIC_WRITE},
+ };
+
+ const ENABLE_VIRTUAL_TERMINAL_PROCESSING: u32 = 0x0004;
+
+ unsafe {
+ // ref: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
+ // Using `CreateFileW("CONOUT$", ...)` to retrieve the console handle works correctly even if STDOUT and/or STDERR are redirected
+ let console_out_name: Vec<u16> =
+ OsStr::new("CONOUT$").encode_wide().chain(once(0)).collect();
+ let console_handle = CreateFileW(
+ console_out_name.as_ptr(),
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_WRITE,
+ null_mut(),
+ OPEN_EXISTING,
+ 0,
+ null_mut(),
+ );
+ if console_handle == INVALID_HANDLE_VALUE {
+ return Err(GetLastError());
+ }
+
+ // ref: https://docs.microsoft.com/en-us/windows/console/getconsolemode
+ let mut console_mode: u32 = 0;
+ if 0 == GetConsoleMode(console_handle, &mut console_mode) {
+ return Err(GetLastError());
+ }
+
+ // VT processing not already enabled?
+ if console_mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0 {
+ // https://docs.microsoft.com/en-us/windows/console/setconsolemode
+ if 0 == SetConsoleMode(
+ console_handle,
+ console_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING,
+ ) {
+ return Err(GetLastError());
+ }
+ }
+ }
+
+ return Ok(());
+}