Skip to content

Commit

Permalink
gnu_legacy: with GNU, write fg first, else bg first. (#54)
Browse files Browse the repository at this point in the history
  • Loading branch information
sylvestre authored Dec 18, 2023
1 parent f1c83ff commit 6c7e262
Showing 1 changed file with 78 additions and 28 deletions.
106 changes: 78 additions & 28 deletions src/ansi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,42 @@ impl Style {
// The foreground and background colors, 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 {
if written_anything {
write!(f, ";")?;

#[cfg(feature = "gnu_legacy")]
// with GNU, write foreground first, else background first.
{
if let Some(fg) = self.foreground {
if written_anything {
write!(f, ";")?;
}
written_anything = true;
fg.write_foreground_code(f)?;
}
written_anything = true;
bg.write_background_code(f)?;
}

if let Some(fg) = self.foreground {
if written_anything {
write!(f, ";")?;
if let Some(bg) = self.background {
if written_anything {
write!(f, ";")?;
}
bg.write_background_code(f)?;
}
fg.write_foreground_code(f)?;
}
#[cfg(not(feature = "gnu_legacy"))]
{
if let Some(bg) = self.background {
if written_anything {
write!(f, ";")?;
}
written_anything = true;
bg.write_background_code(f)?;
}

if let Some(fg) = self.foreground {
if written_anything {
write!(f, ";")?;
}
fg.write_foreground_code(f)?;
}
}
// All the codes end with an `m`, because reasons.
write!(f, "m")?;

Expand Down Expand Up @@ -397,6 +418,8 @@ macro_rules! test {
mod test {
use crate::style::Color::*;
use crate::style::Style;
use crate::Color;
use std::default::Default;

test!(plain: Style::default(); "text/plain" => "text/plain");
test!(red: Red; "hi" => "\x1B[31mhi\x1B[0m");
Expand Down Expand Up @@ -452,13 +475,28 @@ mod test {
assert_eq!(White.normal().infix(Blue.normal()).to_string(), "\x1B[34m");
assert_eq!(Blue.bold().infix(Blue.bold()).to_string(), "");
}

#[test]
fn test_write_prefix_no_gnu_compat_order() {
let style = Style {
foreground: Some(Color::Red),
background: Some(Color::Blue),
..Default::default()
};
assert_eq!(
style.paint("file").to_string(),
"\u{1b}[44;31mfile\u{1b}[0m".to_string()
);
}
}

#[cfg(test)]
#[cfg(feature = "gnu_legacy")]
mod gnu_legacy_test {
use crate::style::Color::*;
use crate::style::Style;
use crate::Color;
use std::default::Default;

test!(plain: Style::default(); "text/plain" => "text/plain");
test!(red: Red; "hi" => "\x1B[31mhi\x1B[0m");
Expand All @@ -468,25 +506,24 @@ mod gnu_legacy_test {
test!(blue_underline: Blue.underline(); "hi" => "\x1B[04;34mhi\x1B[0m");
test!(green_bold_ul: Green.bold().underline(); "hi" => "\x1B[01;04;32mhi\x1B[0m");
test!(green_bold_ul_2: Green.underline().bold(); "hi" => "\x1B[01;04;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_reset: Cyan.on(Blue).reset_before_style().fg(Yellow); "hi" => "\x1B[0m\x1B[44;33mhi\x1B[0m");
test!(yellow_on_blue_reset_2: Cyan.on(Blue).fg(Yellow).reset_before_style(); "hi" => "\x1B[0m\x1B[44;33mhi\x1B[0m");
test!(magenta_on_white: Magenta.on(White); "hi" => "\x1B[47;35mhi\x1B[0m");
test!(magenta_on_white_2: Magenta.normal().on(White); "hi" => "\x1B[47;35mhi\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[01;47;36mhi\x1B[0m");
test!(cyan_ul_on_white: Cyan.underline().on(White); "hi" => "\x1B[04;47;36mhi\x1B[0m");
test!(cyan_bold_ul_on_white: Cyan.bold().underline().on(White); "hi" => "\x1B[01;04;47;36mhi\x1B[0m");
test!(cyan_ul_bold_on_white: Cyan.underline().bold().on(White); "hi" => "\x1B[01;04;47;36mhi\x1B[0m");
test!(purple_on_white: Purple.on(White); "hi" => "\x1B[35;47mhi\x1B[0m");
test!(purple_on_white_2: Purple.normal().on(White); "hi" => "\x1B[35;47mhi\x1B[0m");
test!(yellow_on_blue: Style::new().on(Blue).fg(Yellow); "hi" => "\x1B[33;44mhi\x1B[0m");
test!(yellow_on_blue_reset_2: Cyan.on(Blue).fg(Yellow).reset_before_style(); "hi" => "\x1B[0m\x1B[33;44mhi\x1B[0m");
test!(magenta_on_white: Magenta.on(White); "hi" => "\x1B[35;47mhi\x1B[0m");
test!(magenta_on_white_2: Magenta.normal().on(White); "hi" => "\x1B[35;47mhi\x1B[0m");
test!(yellow_on_blue_2: Cyan.on(Blue).fg(Yellow); "hi" => "\x1B[33;44mhi\x1B[0m");
test!(cyan_bold_on_white: Cyan.bold().on(White); "hi" => "\x1B[01;36;47mhi\x1B[0m");
test!(cyan_ul_on_white: Cyan.underline().on(White); "hi" => "\x1B[04;36;47mhi\x1B[0m");
test!(cyan_bold_ul_on_white: Cyan.bold().underline().on(White); "hi" => "\x1B[01;04;36;47mhi\x1B[0m");
test!(cyan_ul_bold_on_white: Cyan.underline().bold().on(White); "hi" => "\x1B[01;04;36;47mhi\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!(fixed_on_purple: Fixed(100).on(Purple); "hi" => "\x1B[38;5;100;45mhi\x1B[0m");
test!(fixed_on_fixed: Fixed(100).on(Fixed(200)); "hi" => "\x1B[38;5;100;48;5;200mhi\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!(rgb_on_blue: Rgb(70,130,180).on(Blue); "hi" => "\x1B[38;2;70;130;180;44mhi\x1B[0m");
test!(blue_on_rgb: Blue.on(Rgb(70,130,180)); "hi" => "\x1B[34;48;2;70;130;180mhi\x1B[0m");
test!(rgb_on_rgb: Rgb(70,130,180).on(Rgb(5,10,15)); "hi" => "\x1B[38;2;70;130;180;48;2;5;10;15mhi\x1B[0m");
test!(bold: Style::new().bold(); "hi" => "\x1B[01mhi\x1B[0m");
test!(bold_with_reset: Style::new().reset_before_style().bold(); "hi" => "\x1B[0m\x1B[01mhi\x1B[0m");
test!(bold_with_reset_2: Style::new().bold().reset_before_style(); "hi" => "\x1B[0m\x1B[01mhi\x1B[0m");
Expand All @@ -498,5 +535,18 @@ mod gnu_legacy_test {
test!(reverse: Style::new().reverse(); "hi" => "\x1B[07mhi\x1B[0m");
test!(hidden: Style::new().hidden(); "hi" => "\x1B[08mhi\x1B[0m");
test!(stricken: Style::new().strikethrough(); "hi" => "\x1B[09mhi\x1B[0m");
test!(lr_on_lr: LightRed.on(LightRed); "hi" => "\x1B[101;91mhi\x1B[0m");
test!(lr_on_lr: LightRed.on(LightRed); "hi" => "\x1B[91;101mhi\x1B[0m");

#[test]
fn test_write_prefix_gnu_compat_order() {
let style = Style {
foreground: Some(Color::Red),
background: Some(Color::Blue),
..Default::default()
};
assert_eq!(
style.paint("file").to_string(),
"\u{1b}[31;44mfile\u{1b}[0m".to_string()
);
}
}

0 comments on commit 6c7e262

Please sign in to comment.