Skip to main content

log_full/
colors.rs

1//! 颜色输出模块
2//! 
3//! 提供增强的颜色输出功能
4
5use std::collections::HashMap;
6
7/// 颜色主题
8#[derive(Debug, Clone)]
9pub enum ColorTheme {
10    /// 默认主题
11    Default,
12    /// 暗色主题
13    Dark,
14    /// 亮色主题
15    Light,
16    /// 自定义主题
17    Custom(HashMap<String, String>),
18}
19
20/// 日志级别颜色映射
21#[derive(Debug, Clone)]
22pub struct LevelColors {
23    pub error: String,
24    pub warn: String,
25    pub info: String,
26    pub debug: String,
27    pub trace: String,
28}
29
30/// 颜色配置
31#[derive(Debug, Clone)]
32pub struct ColorConfig {
33    /// 是否启用颜色
34    pub enabled: bool,
35    /// 颜色主题
36    pub theme: ColorTheme,
37    /// 级别颜色
38    pub level_colors: LevelColors,
39    /// 关键词颜色映射
40    pub keyword_colors: HashMap<String, String>,
41    /// 时间戳颜色
42    pub timestamp_color: String,
43    /// 文件名颜色
44    pub filename_color: String,
45    /// 行号颜色
46    pub line_number_color: String,
47}
48
49impl Default for LevelColors {
50    fn default() -> Self {
51        Self {
52            error: "red".to_string(),
53            warn: "yellow".to_string(),
54            info: "green".to_string(),
55            debug: "blue".to_string(),
56            trace: "magenta".to_string(),
57        }
58    }
59}
60
61impl Default for ColorConfig {
62    fn default() -> Self {
63        Self {
64            enabled: true,
65            theme: ColorTheme::Default,
66            level_colors: LevelColors::default(),
67            keyword_colors: HashMap::new(),
68            timestamp_color: "cyan".to_string(),
69            filename_color: "white".to_string(),
70            line_number_color: "bright_black".to_string(),
71        }
72    }
73}
74
75/// 颜色应用器
76pub struct ColorApplier {
77    config: ColorConfig,
78}
79
80impl ColorApplier {
81    /// 创建新的颜色应用器
82    pub fn new(config: ColorConfig) -> Self {
83        Self { config }
84    }
85    
86    /// 应用级别颜色
87    pub fn apply_level_color(&self, _level: &str, text: &str) -> String {
88        text.to_string()
89    }
90    
91    /// 应用关键词颜色
92    pub fn apply_keyword_color(&self, _keyword: &str, text: &str) -> String {
93        text.to_string()
94    }
95    
96    /// 应用时间戳颜色
97    pub fn apply_timestamp_color(&self, text: &str) -> String {
98        text.to_string()
99    }
100    
101    /// 应用文件名颜色
102    pub fn apply_filename_color(&self, text: &str) -> String {
103        text.to_string()
104    }
105    
106    /// 应用行号颜色
107    pub fn apply_line_number_color(&self, text: &str) -> String {
108        text.to_string()
109    }
110    
111
112    
113    /// 检测终端是否支持颜色
114    pub fn supports_color() -> bool {
115        false
116    }
117    
118    /// 强制启用/禁用颜色
119    pub fn set_override(&self, _enabled: bool) {
120        // No color support
121    }
122}
123
124/// 颜色配置构建器
125pub struct ColorConfigBuilder {
126    config: ColorConfig,
127}
128
129impl ColorConfigBuilder {
130    /// 创建新的颜色配置构建器
131    pub fn new() -> Self {
132        Self {
133            config: ColorConfig::default(),
134        }
135    }
136    
137    /// 启用/禁用颜色
138    pub fn enabled(mut self, enabled: bool) -> Self {
139        self.config.enabled = enabled;
140        self
141    }
142    
143    /// 设置主题
144    pub fn theme(mut self, theme: ColorTheme) -> Self {
145        self.config.theme = theme;
146        self
147    }
148    
149    /// 设置错误级别颜色
150    pub fn error_color<S: Into<String>>(mut self, color: S) -> Self {
151        self.config.level_colors.error = color.into();
152        self
153    }
154    
155    /// 设置警告级别颜色
156    pub fn warn_color<S: Into<String>>(mut self, color: S) -> Self {
157        self.config.level_colors.warn = color.into();
158        self
159    }
160    
161    /// 设置信息级别颜色
162    pub fn info_color<S: Into<String>>(mut self, color: S) -> Self {
163        self.config.level_colors.info = color.into();
164        self
165    }
166    
167    /// 设置调试级别颜色
168    pub fn debug_color<S: Into<String>>(mut self, color: S) -> Self {
169        self.config.level_colors.debug = color.into();
170        self
171    }
172    
173    /// 设置跟踪级别颜色
174    pub fn trace_color<S: Into<String>>(mut self, color: S) -> Self {
175        self.config.level_colors.trace = color.into();
176        self
177    }
178    
179    /// 添加关键词颜色
180    pub fn keyword_color<K: Into<String>, C: Into<String>>(mut self, keyword: K, color: C) -> Self {
181        self.config.keyword_colors.insert(keyword.into(), color.into());
182        self
183    }
184    
185    /// 设置时间戳颜色
186    pub fn timestamp_color<S: Into<String>>(mut self, color: S) -> Self {
187        self.config.timestamp_color = color.into();
188        self
189    }
190    
191    /// 设置文件名颜色
192    pub fn filename_color<S: Into<String>>(mut self, color: S) -> Self {
193        self.config.filename_color = color.into();
194        self
195    }
196    
197    /// 设置行号颜色
198    pub fn line_number_color<S: Into<String>>(mut self, color: S) -> Self {
199        self.config.line_number_color = color.into();
200        self
201    }
202    
203    /// 构建颜色配置
204    pub fn build(self) -> ColorConfig {
205        self.config
206    }
207}
208
209/// 预定义颜色主题
210impl ColorTheme {
211    /// 获取暗色主题
212    pub fn dark() -> Self {
213        ColorTheme::Dark
214    }
215    
216    /// 获取亮色主题
217    pub fn light() -> Self {
218        ColorTheme::Light
219    }
220    
221    /// 创建自定义主题
222    pub fn custom(colors: HashMap<String, String>) -> Self {
223        ColorTheme::Custom(colors)
224    }
225}
226
227#[cfg(test)]
228mod tests {
229    use super::*;
230    
231    #[test]
232    fn test_color_config_builder() {
233        let config = ColorConfigBuilder::new()
234            .enabled(true)
235            .error_color("bright_red")
236            .warn_color("bright_yellow")
237            .keyword_color("ERROR", "red")
238            .timestamp_color("blue")
239            .build();
240            
241        assert!(config.enabled);
242        assert_eq!(config.level_colors.error, "bright_red");
243        assert_eq!(config.level_colors.warn, "bright_yellow");
244        assert_eq!(config.keyword_colors.get("ERROR"), Some(&"red".to_string()));
245        assert_eq!(config.timestamp_color, "blue");
246    }
247    
248    #[test]
249    fn test_color_applier() {
250        let config = ColorConfig::default();
251        let applier = ColorApplier::new(config);
252        
253        let colored_text = applier.apply_level_color("ERROR", "Test message");
254        // 返回原始文本
255        assert_eq!(colored_text, "Test message");
256    }
257}