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
use crate::progress::Progress;
use console::{style, Color};
use log::{set_max_level, Level, LevelFilter, Log, Metadata, Record};
use std::io::{stderr, Write};
pub struct Logger {
level: LevelFilter,
}
impl Logger {
pub fn new(level: LevelFilter) -> Box<Self> {
set_max_level(LevelFilter::Trace);
Self { level }.into()
}
pub fn error(msg: &str) {
Self {
level: LevelFilter::Error,
}
.log(
&Record::builder()
.args(format_args!("{}", msg))
.level(Level::Error)
.build(),
);
}
}
impl Log for Logger {
fn enabled(&self, metadata: &Metadata<'_>) -> bool {
metadata.level() <= self.level
}
fn log(&self, record: &Record<'_>) {
if !self.enabled(record.metadata()) {
return;
}
let level = record.metadata().level();
let (level_name, level_color) = match level {
Level::Error => ("ERROR", Color::Red),
Level::Warn => ("WARN ", Color::Yellow),
Level::Info => ("INFO ", Color::Green),
Level::Debug => ("DEBUG", Color::Cyan),
Level::Trace => ("TRACE", Color::Magenta),
};
let msg = format!(
"{}{}{} {}",
style("[").white().dim(),
style(level_name).fg(level_color),
style("]").white().dim(),
style(record.args()),
);
if let Some(pb) = Progress::get() {
if level != Level::Info {
pb.println(msg);
} else {
pb.inc(1);
pb.set_message(&record.args().to_string());
}
} else {
writeln!(stderr(), "{}", msg).ok();
}
}
fn flush(&self) {}
}
#[cfg(test)]
pub mod tests {
use super::*;
use log::{MetadataBuilder, Record};
#[test]
fn logger_success() {
let l = Logger::new(LevelFilter::Info);
let record = Record::builder()
.args(format_args!("Error!"))
.level(Level::Error)
.build();
l.log(&record);
let err_metadata = MetadataBuilder::new().level(Level::Error).build();
assert!(l.enabled(&err_metadata));
let dbg_metadata = MetadataBuilder::new().level(Level::Debug).build();
assert!(!l.enabled(&dbg_metadata));
l.flush();
}
}