use std::sync::{Mutex, Once};
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum LogLevel {
V,
D,
I,
W,
E,
S,
}
impl LogLevel {
pub fn index(&self) -> u32 {
match self {
LogLevel::V => 0,
LogLevel::D => 1,
LogLevel::I => 2,
LogLevel::W => 3,
LogLevel::E => 4,
LogLevel::S => 5,
}
}
pub fn greater_than(&self, o: &Self) -> bool {
return self.index() > o.index();
}
pub fn greater_or_equal(&self, o: &Self) -> bool {
return self.index() >= o.index();
}
pub fn less_than(&self, o: &Self) -> bool {
return self.index() < o.index();
}
pub fn less_or_equal(&self, o: &Self) -> bool {
return self.index() <= o.index();
}
}
static INIT: Once = Once::new();
static mut LOG_LEVEL: Option<Mutex<LogLevel>> = None;
fn init() {
INIT.call_once(|| unsafe { LOG_LEVEL = Some(Mutex::new(LogLevel::I)) });
}
pub fn set_log_level(level: LogLevel) {
init();
unsafe {
if let Some(ref mutex) = LOG_LEVEL {
let mut ll = mutex.lock().unwrap();
*ll = level;
}
}
}
pub fn get_log_level() -> LogLevel {
init();
unsafe {
if let Some(ref mutex) = LOG_LEVEL {
let ll = mutex.lock().unwrap();
match *ll {
LogLevel::V => LogLevel::V,
LogLevel::D => LogLevel::D,
LogLevel::I => LogLevel::I,
LogLevel::W => LogLevel::W,
LogLevel::E => LogLevel::E,
LogLevel::S => LogLevel::S,
}
} else {
LogLevel::I
}
}
}
fn p(current_level: LogLevel, log_level: &LogLevel, msg: &str) {
if log_level.less_than(¤t_level) {
return;
}
println!("{msg}");
}
pub fn v(msg: &str) {
let current_level = get_log_level();
p(current_level, &LogLevel::V, msg)
}
pub fn d(msg: &str) {
let current_level = get_log_level();
p(current_level, &LogLevel::D, msg)
}
pub fn i(msg: &str) {
let current_level = get_log_level();
p(current_level, &LogLevel::I, msg)
}
pub fn w(msg: &str) {
let current_level = get_log_level();
p(current_level, &LogLevel::W, msg)
}
pub fn e(msg: &str) {
let current_level = get_log_level();
p(current_level, &LogLevel::E, msg)
}
#[cfg(test)]
mod tests {
use crate::set_log_level;
use super::*;
#[test]
fn log() {
set_log_level(LogLevel::V);
println!("log_level:{:?}", get_log_level());
v("verbose");
d("debug");
i("info");
w("warn");
e("error");
set_log_level(LogLevel::D);
println!("log_level:{:?}", get_log_level());
v("verbose");
d("debug");
i("info");
w("warn");
e("error");
set_log_level(LogLevel::I);
println!("log_level:{:?}", get_log_level());
v("verbose");
d("debug");
i("info");
w("warn");
e("error");
set_log_level(LogLevel::W);
println!("log_level:{:?}", get_log_level());
v("verbose");
d("debug");
i("info");
w("warn");
e("error");
set_log_level(LogLevel::E);
println!("log_level:{:?}", get_log_level());
v("verbose");
d("debug");
i("info");
w("warn");
e("error");
set_log_level(LogLevel::S);
println!("log_level:{:?}", get_log_level());
v("verbose");
d("debug");
i("info");
w("warn");
e("error");
}
}