fancy_log/
logs.rs

1/* src/logs.rs */
2// SPDX-License-Identifier: MIT
3// Copyright (c) 2025 Canmi
4
5use chrono::Local;
6use once_cell::sync::Lazy;
7use serde::Deserialize;
8use std::io::Write;
9use std::sync::Mutex;
10use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
13#[serde(rename_all = "lowercase")]
14pub enum LogLevel {
15    Error, // 1
16    Warn,  // 2
17    Info,  // 3
18    Debug, // 4
19}
20
21impl LogLevel {
22    fn as_u8(&self) -> u8 {
23        match self {
24            LogLevel::Error => 1,
25            LogLevel::Warn => 2,
26            LogLevel::Info => 3,
27            LogLevel::Debug => 4,
28        }
29    }
30}
31
32static LOG_LEVEL: Lazy<Mutex<LogLevel>> = Lazy::new(|| Mutex::new(LogLevel::Info));
33
34pub fn set_log_level(new_level: LogLevel) {
35    let mut level = LOG_LEVEL.lock().unwrap();
36    *level = new_level;
37}
38
39pub fn log(level: LogLevel, content: &str) {
40    let current_level = LOG_LEVEL.lock().unwrap();
41    if level.as_u8() > current_level.as_u8() {
42        return;
43    }
44
45    let mut stream = match level {
46        LogLevel::Warn | LogLevel::Error => StandardStream::stderr(ColorChoice::Auto),
47        _ => StandardStream::stdout(ColorChoice::Auto),
48    };
49
50    let now = Local::now().format("%H:%M:%S").to_string();
51
52    match level {
53        LogLevel::Info => {
54            let _ = stream.set_color(ColorSpec::new().set_fg(Some(Color::White)));
55            let _ = write!(stream, "{} ", now);
56            let _ = stream.reset();
57            let _ = writeln!(stream, "{}", content);
58        }
59        LogLevel::Debug => {
60            let _ = stream.set_color(ColorSpec::new().set_fg(Some(Color::Blue)));
61            let _ = writeln!(stream, "{} {}", now, content);
62        }
63        LogLevel::Warn => {
64            let _ = stream.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)));
65            let _ = writeln!(stream, "{} {}", now, content);
66        }
67        LogLevel::Error => {
68            let _ = stream.set_color(ColorSpec::new().set_fg(Some(Color::Red)));
69            let _ = writeln!(stream, "{} {}", now, content);
70        }
71    }
72
73    let _ = stream.reset();
74}