summaryrefslogtreecommitdiffstats
path: root/vendor/yansi-term/src/ansi.rs
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/ansi.rs
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/ansi.rs')
-rw-r--r--vendor/yansi-term/src/ansi.rs290
1 files changed, 290 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());
+ }
+}