bbk47_toolbox/
logger.rs

1use std::cmp::Ordering;
2use std::io::{self, Write};
3use std::sync::Mutex;
4
5#[derive(PartialEq, Eq)]
6pub enum LogLevel {
7    Debug,
8    Info,
9    Warn,
10    Error,
11}
12
13
14
15impl PartialOrd for LogLevel {
16    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
17        match (self, other) {
18            (&LogLevel::Error, &LogLevel::Error) => Some(Ordering::Equal),
19            (&LogLevel::Error, _) => Some(Ordering::Greater),
20            (_, &LogLevel::Error) => Some(Ordering::Less),
21            (&LogLevel::Warn, &LogLevel::Warn) => Some(Ordering::Equal),
22            (&LogLevel::Warn, _) => Some(Ordering::Greater),
23            (_, &LogLevel::Warn) => Some(Ordering::Less),
24            (&LogLevel::Info, &LogLevel::Info) => Some(Ordering::Equal),
25            (&LogLevel::Info, _) => Some(Ordering::Greater),
26            (_, &LogLevel::Info) => Some(Ordering::Less),
27            (&LogLevel::Debug, &LogLevel::Debug) => Some(Ordering::Equal),
28        }
29    }
30}
31
32impl Ord for LogLevel {
33    fn cmp(&self, other: &Self) -> Ordering {
34        match (self, other) {
35            (&LogLevel::Error, &LogLevel::Error) 
36            | (&LogLevel::Warn, &LogLevel::Warn)
37            | (&LogLevel::Info, &LogLevel::Info)
38            | (&LogLevel::Debug, &LogLevel::Debug) => Ordering::Equal,
39            (&LogLevel::Error, _) => Ordering::Greater,
40            (_, &LogLevel::Error) => Ordering::Less,
41            (&LogLevel::Warn, &LogLevel::Info) 
42            | (&LogLevel::Warn, &LogLevel::Debug) 
43            | (&LogLevel::Info, &LogLevel::Debug) => Ordering::Greater,
44            (_, _) => Ordering::Less,
45        }
46    }
47}
48
49
50pub struct Logger {
51    level: LogLevel,
52    writer: Mutex<Box<dyn Write + Send>>,
53}
54
55impl Logger {
56    pub fn new(level: LogLevel) -> Self {
57        Logger {
58            level,
59            writer: Mutex::new(Box::new(io::stdout())),
60        }
61    }
62
63    pub fn set_writer(&self, writer: Box<dyn Write + Send>) {
64        *self.writer.lock().unwrap() = writer;
65    }
66
67    fn log(&self, level: LogLevel, message: &str) {
68        if level >= self.level {
69            let mut writer = self.writer.lock().unwrap();
70            writeln!(writer.as_mut(), "{}: {}", level_str(level), message).unwrap();
71        }
72    }
73
74    pub fn debug(&self, message: &str) {
75        self.log(LogLevel::Debug, message);
76    }
77
78    pub fn info(&self, message: &str) {
79        self.log(LogLevel::Info, message);
80    }
81
82    pub fn warn(&self, message: &str) {
83        self.log(LogLevel::Warn, message);
84    }
85
86    pub fn error(&self, message: &str) {
87        self.log(LogLevel::Error, message);
88    }
89}
90
91fn level_str(level: LogLevel) -> &'static str {
92    match level {
93        LogLevel::Debug => "DEBUG",
94        LogLevel::Info => "INFO",
95        LogLevel::Warn => "WARN",
96        LogLevel::Error => "ERROR",
97    }
98}
99
100// fn main() {
101//     let logger = Logger::new(LogLevel::Info);
102
103//     // 记录 INFO 级别的日志
104//     logger.info("Hello, world!");
105
106//     // 记录 DEBUG 级别的日志(但由于日志级别设为 INFO,因此不会输出)
107//     logger.debug("This is a debug message.");
108
109//     // 将日志写入文件
110//     logger.set_writer(Box::new(BufWriter::new(File::create("log.txt").unwrap())));
111
112//     // 记录 WARN 级别的日志,将会输出到文件中
113//     logger.warn("Something went wrong.");
114// }