tracing_systemd/format/
color.rs1#![cfg(feature = "colors")]
5
6use nu_ansi_term::{Color, Style};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
10#[cfg_attr(docsrs, doc(cfg(feature = "colors")))]
11pub enum ColorMode {
12 #[default]
15 Auto,
16 Always,
18 Never,
20}
21
22impl ColorMode {
23 pub(crate) fn resolve(self, is_terminal: bool, no_color_set: bool) -> bool {
26 match self {
27 Self::Always => true,
28 Self::Never => false,
29 Self::Auto => is_terminal && !no_color_set,
30 }
31 }
32
33 pub(crate) fn resolve_now(self, is_terminal: bool) -> bool {
35 self.resolve(is_terminal, std::env::var_os("NO_COLOR").is_some())
36 }
37}
38
39#[derive(Debug, Clone, Copy)]
56#[cfg_attr(docsrs, doc(cfg(feature = "colors")))]
57#[allow(missing_docs)] pub struct ColorTheme {
59 pub trace: Style,
60 pub debug: Style,
61 pub info: Style,
62 pub warn: Style,
63 pub error: Style,
64 pub span_name: Style,
65 pub field_name: Style,
66 pub field_value: Style,
67 pub target: Style,
68 pub thread_id: Style,
69}
70
71impl ColorTheme {
72 #[must_use]
76 pub fn monochrome() -> Self {
77 Self {
78 trace: Style::new(),
79 debug: Style::new(),
80 info: Style::new(),
81 warn: Style::new(),
82 error: Style::new(),
83 span_name: Style::new(),
84 field_name: Style::new(),
85 field_value: Style::new(),
86 target: Style::new(),
87 thread_id: Style::new(),
88 }
89 }
90
91 pub(crate) fn level_style(&self, level: tracing::Level) -> Style {
93 match level {
94 tracing::Level::TRACE => self.trace,
95 tracing::Level::DEBUG => self.debug,
96 tracing::Level::INFO => self.info,
97 tracing::Level::WARN => self.warn,
98 tracing::Level::ERROR => self.error,
99 }
100 }
101}
102
103impl Default for ColorTheme {
104 fn default() -> Self {
106 Self {
107 trace: Style::new().fg(Color::Magenta),
108 debug: Style::new().fg(Color::Blue),
109 info: Style::new().fg(Color::Green),
110 warn: Style::new().fg(Color::Yellow),
111 error: Style::new().fg(Color::Red),
112 span_name: Style::new(),
113 field_name: Style::new(),
114 field_value: Style::new(),
115 target: Style::new(),
116 thread_id: Style::new(),
117 }
118 }
119}
120
121#[cfg(test)]
122mod tests {
123 use super::*;
124
125 #[test]
126 fn auto_resolves_against_tty_and_no_color() {
127 assert!(ColorMode::Auto.resolve(true, false));
128 assert!(!ColorMode::Auto.resolve(true, true));
129 assert!(!ColorMode::Auto.resolve(false, false));
130 assert!(!ColorMode::Auto.resolve(false, true));
131 }
132
133 #[test]
134 fn always_overrides_tty_and_env() {
135 assert!(ColorMode::Always.resolve(false, true));
136 assert!(ColorMode::Always.resolve(true, true));
137 }
138
139 #[test]
140 fn never_overrides_tty_and_env() {
141 assert!(!ColorMode::Never.resolve(true, false));
142 }
143
144 #[test]
145 fn level_style_picks_correct_style() {
146 let theme = ColorTheme::default();
147 assert_eq!(theme.level_style(tracing::Level::INFO), theme.info);
148 assert_eq!(theme.level_style(tracing::Level::ERROR), theme.error);
149 }
150
151 #[test]
152 fn monochrome_has_empty_styles() {
153 let theme = ColorTheme::monochrome();
154 let plain = Style::new();
155 assert_eq!(theme.info, plain);
156 assert_eq!(theme.error, plain);
157 assert_eq!(theme.span_name, plain);
158 }
159}