sdml_errors/diagnostics/color.rs
1/*!
2A common helper type to determine color output.
3 */
4
5use codespan_reporting::term::termcolor::ColorChoice;
6
7// ------------------------------------------------------------------------------------------------
8// Public Types
9// ------------------------------------------------------------------------------------------------
10
11#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
12pub enum UseColor {
13 Always,
14 Auto,
15 Never,
16}
17
18///
19/// A common environment variable for command-line tools, if set to any value color should not
20/// be used.
21///
22pub const COLOR_NO_COLOR_ENV: &str = "NO_COLOR";
23
24///
25/// A Rusty environment variable for command-line tools, if set to `0` color
26/// should not be used, if set to `1` color should be used, otherwise it's up to
27/// the tool to decide.
28///
29/// Note that the variable `NO_COLOR` overrides `CLI_COLOR`.
30///
31pub const COLOR_CLI_COLOR_ENV: &str = "CLI_COLOR";
32
33// ------------------------------------------------------------------------------------------------
34// Private Types
35// ------------------------------------------------------------------------------------------------
36
37const COLOR_CLI_COLOR_ON: &str = "1";
38
39const COLOR_CLI_COLOR_OFF: &str = "0";
40
41// ------------------------------------------------------------------------------------------------
42// Implementations
43// ------------------------------------------------------------------------------------------------
44
45impl Default for UseColor {
46 fn default() -> Self {
47 Self::Auto
48 }
49}
50
51impl From<UseColor> for ColorChoice {
52 fn from(value: UseColor) -> Self {
53 match value {
54 UseColor::Always => Self::Always,
55 UseColor::Auto => Self::Auto,
56 UseColor::Never => Self::Never,
57 }
58 }
59}
60
61impl UseColor {
62 pub fn from_env() -> Self {
63 match (Self::from_no_color_env(), Self::from_cli_color_env()) {
64 (Some(no_color), _) => no_color,
65 (None, Some(cli_color)) => cli_color,
66 (None, None) => Self::default(),
67 }
68 }
69
70 #[inline(always)]
71 pub fn use_color(&self) -> bool {
72 matches!(self, Self::Always | Self::Auto)
73 }
74
75 #[inline(always)]
76 pub fn from_no_color_env() -> Option<Self> {
77 std::env::var(COLOR_NO_COLOR_ENV).map(|_| Self::Never).ok()
78 }
79
80 #[inline(always)]
81 pub fn from_cli_color_env() -> Option<Self> {
82 std::env::var(COLOR_NO_COLOR_ENV)
83 .map(|v| {
84 if v == COLOR_CLI_COLOR_OFF {
85 Self::Never
86 } else if v == COLOR_CLI_COLOR_ON {
87 Self::Always
88 } else {
89 Self::Auto
90 }
91 })
92 .ok()
93 }
94}