Support NO_COLOR. (#782)
This commit is contained in:
parent
dfc67e54c8
commit
2c534fc69e
@ -1,4 +1,6 @@
|
||||
use parking_lot::Once;
|
||||
use std::fmt::{self, Formatter};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -21,6 +23,9 @@ pub enum Colored {
|
||||
UnderlineColor(Color),
|
||||
}
|
||||
|
||||
static ANSI_COLOR_DISABLED: AtomicBool = AtomicBool::new(false);
|
||||
static INITIALIZER: Once = Once::new();
|
||||
|
||||
impl Colored {
|
||||
/// Parse an ANSI foreground or background color.
|
||||
/// This is the string that would appear within an `ESC [ <str> m` escape sequence, as found in
|
||||
@ -64,12 +69,39 @@ impl Colored {
|
||||
|
||||
Some(output)
|
||||
}
|
||||
|
||||
/// Checks whether ansi color sequences are disabled by setting of NO_COLOR
|
||||
/// in environment as per https://no-color.org/
|
||||
pub fn ansi_color_disabled() -> bool {
|
||||
!std::env::var("NO_COLOR")
|
||||
.unwrap_or("".to_string())
|
||||
.is_empty()
|
||||
}
|
||||
|
||||
pub fn ansi_color_disabled_memoized() -> bool {
|
||||
INITIALIZER.call_once(|| {
|
||||
ANSI_COLOR_DISABLED.store(Self::ansi_color_disabled(), Ordering::SeqCst);
|
||||
});
|
||||
|
||||
ANSI_COLOR_DISABLED.load(Ordering::SeqCst)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn set_ansi_color_disabled(val: bool) {
|
||||
// Force the one-time initializer to run.
|
||||
_ = Self::ansi_color_disabled_memoized();
|
||||
ANSI_COLOR_DISABLED.store(val, Ordering::SeqCst);
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Colored {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
let color;
|
||||
|
||||
if Self::ansi_color_disabled_memoized() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
match *self {
|
||||
Colored::ForegroundColor(new_color) => {
|
||||
if new_color == Color::Reset {
|
||||
@ -125,40 +157,47 @@ impl fmt::Display for Colored {
|
||||
mod tests {
|
||||
use crate::style::{Color, Colored};
|
||||
|
||||
fn check_format_color(colored: Colored, expected: &str) {
|
||||
Colored::set_ansi_color_disabled(true);
|
||||
assert_eq!(colored.to_string(), "");
|
||||
Colored::set_ansi_color_disabled(false);
|
||||
assert_eq!(colored.to_string(), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_fg_color() {
|
||||
let colored = Colored::ForegroundColor(Color::Red);
|
||||
assert_eq!(colored.to_string(), "38;5;9");
|
||||
check_format_color(colored, "38;5;9");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_bg_color() {
|
||||
let colored = Colored::BackgroundColor(Color::Red);
|
||||
assert_eq!(colored.to_string(), "48;5;9");
|
||||
check_format_color(colored, "48;5;9");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_reset_fg_color() {
|
||||
let colored = Colored::ForegroundColor(Color::Reset);
|
||||
assert_eq!(colored.to_string(), "39");
|
||||
check_format_color(colored, "39");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_reset_bg_color() {
|
||||
let colored = Colored::BackgroundColor(Color::Reset);
|
||||
assert_eq!(colored.to_string(), "49");
|
||||
check_format_color(colored, "49");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_fg_rgb_color() {
|
||||
let colored = Colored::BackgroundColor(Color::Rgb { r: 1, g: 2, b: 3 });
|
||||
assert_eq!(colored.to_string(), "48;2;1;2;3");
|
||||
check_format_color(colored, "48;2;1;2;3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_fg_ansi_color() {
|
||||
let colored = Colored::ForegroundColor(Color::AnsiValue(255));
|
||||
assert_eq!(colored.to_string(), "38;5;255");
|
||||
check_format_color(colored, "38;5;255");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -267,4 +306,16 @@ mod tests {
|
||||
test("48;2;0;2;25;");
|
||||
test("48;2;0;2;25;3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_color() {
|
||||
std::env::set_var("NO_COLOR", "1");
|
||||
assert!(Colored::ansi_color_disabled());
|
||||
std::env::set_var("NO_COLOR", "XXX");
|
||||
assert!(Colored::ansi_color_disabled());
|
||||
std::env::set_var("NO_COLOR", "");
|
||||
assert!(!Colored::ansi_color_disabled());
|
||||
std::env::remove_var("NO_COLOR");
|
||||
assert!(!Colored::ansi_color_disabled());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user