1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
struct Logger {
    to: Option<Box<dyn std::io::Write>>,
}
static mut LOGGER: Logger = Logger { to: None };
#[derive(PartialEq, PartialOrd, Copy, Clone, Debug)]
pub enum Level {
    Trace,
    Debug,
    Info,
    Warn,
    Error,
}
static mut LEVEL: Level = Level::Info;

impl Logger {
    /// Logs a message at the specified level.
    pub fn log(&mut self, level: Level, s: &str) {
        if level < unsafe { LEVEL } {
            return;
        }
        if let Some(ref mut to) = self.to {
            let _ = to
                .write(
                    match level {
                        Level::Trace => format!("[TRACE] {}\n", s),
                        Level::Debug => format!("[DEBUG] {}\n", s),
                        Level::Info => format!("[INFO] {}\n", s),
                        Level::Warn => format!("[WARN] {}\n", s),
                        Level::Error => format!("[ERROR] {}\n", s),
                    }
                    .as_bytes(),
                )
                .unwrap();
        }
        // self.to.write(b"\n").unwrap();
    }
}
/// Initializes the logger.
///
/// # Examples
///
/// ```
/// use xlog_rs::log;
/// log::init(std::io::stdout(), log::Level::Trace);
/// assert_eq!(log::level(), log::Level::Trace);
/// ```
pub fn init(to: impl std::io::Write + 'static, level: Level) {
    // Box::new(to);
    unsafe {
        LOGGER = Logger {
            to: Some(Box::new(to)),
        };
        LEVEL = level;
    }
}
/// Initializes the logger with a file.
pub fn with_file<'a>(name: &str) {
    // Box::new(to);
    unsafe {
        LOGGER = Logger {
            to: Some(Box::new(
                std::fs::File::options()
                    .create(true)
                    .append(true)
                    .open(name)
                    .unwrap(),
            )),
        };
    }
}
/// Sets the log level.
///
/// # Examples
///
/// ```
/// use xlog_rs::log;
/// log::set_level(log::Level::Trace);
/// assert_eq!(log::level(), log::Level::Trace);
/// ```
pub fn set_level(level: Level) {
    unsafe {
        LEVEL = level;
    }
}
/// Returns the current log level.
pub fn level() -> Level {
    unsafe { LEVEL }
}
/// Logs a message at the trace level.
pub fn trace(s: &str) {
    unsafe {
        LOGGER.log(Level::Trace, s);
    }
}
/// Logs a message at the debug level.
pub fn debug(s: &str) {
    unsafe {
        LOGGER.log(Level::Debug, s);
    }
}
/// Logs a message at the info level.
pub fn info(s: &str) {
    unsafe {
        LOGGER.log(Level::Info, s);
    }
}
/// Logs a message at the warn level.
pub fn warn(s: &str) {
    unsafe {
        LOGGER.log(Level::Warn, s);
    }
}
/// Logs a message at the error level.
pub fn error(s: &str) {
    unsafe {
        LOGGER.log(Level::Error, s);
    }
}