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
use log::{Level, Log, Metadata, Record};
use wasm_bindgen::prelude::*;
pub const DEFAULT_LOGGER: ConsoleLogger = ConsoleLogger {
formatter: &format_message,
log_level: Level::Trace,
};
fn format_message(record: &Record) -> String {
if record.level() >= Level::Debug {
format!("{}: {}", record.level(), record.args())
} else {
format!("{}", record.args())
}
}
pub type RecordFormatter = Fn(&Record) -> String + Send + Sync;
pub struct ConsoleLogger {
formatter: &'static RecordFormatter,
log_level: Level,
}
impl ConsoleLogger {
pub fn new(formatter: &'static RecordFormatter, log_level: Level) -> Self {
ConsoleLogger { formatter, log_level }
}
pub fn with_level(level: Level) -> Self {
ConsoleLogger::new(&format_message, level)
}
}
impl Default for ConsoleLogger {
fn default() -> Self {
DEFAULT_LOGGER
}
}
impl Log for ConsoleLogger {
fn enabled(&self, metadata: &Metadata) -> bool {
metadata.level() <= self.log_level
}
fn log(&self, record: &Record) {
if self.enabled(record.metadata()) {
let msg = (self.formatter)(record);
match record.level() {
Level::Error => error(&msg),
Level::Warn => warn(&msg),
_ => log(&msg),
}
}
}
fn flush(&self) {}
}
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace=console)]
fn log(text: &str);
#[wasm_bindgen(js_namespace=console)]
fn warn(text: &str);
#[wasm_bindgen(js_namespace=console)]
fn error(text: &str);
}