sapp_console_log/
lib.rs

1#[cfg(test)] #[macro_use] extern crate log;
2use log::{Log, Level, Record, Metadata, SetLoggerError};
3
4#[cfg(target_arch = "wasm32")]
5extern crate sapp_wasm as sapp;
6
7#[cfg(not(target_arch = "wasm32"))]
8pub mod console {
9    pub fn debug(_msg: &str) {
10        panic!("console::debug only implemented for wasm32 target");
11    }
12    
13    pub fn log(_msg: &str) {
14        panic!("console::log only implemented for wasm32 target");
15    }
16
17    pub fn info(_msg: &str) {
18        panic!("console::info only implemented for wasm32 target");
19    }
20
21    pub fn warn(_msg: &str) {
22        panic!("console::warn only implemented for wasm32 target");
23    }
24    
25    pub fn error(_msg: &str) {
26        panic!("console::error only implemented for wasm32 target");
27    }
28}
29
30#[cfg(target_arch = "wasm32")]
31pub mod console {
32    pub fn debug(msg: &str) {
33        use std::ffi::CString;
34        let string = CString::new(msg).unwrap();
35        unsafe { sapp::console_debug(string.as_ptr()); }
36    }
37    
38    pub fn log(msg: &str) {
39        use std::ffi::CString;
40        let string = CString::new(msg).unwrap();
41        unsafe { sapp::console_log(string.as_ptr()); }
42    }
43
44    pub fn info(msg: &str) {
45        use std::ffi::CString;
46        let string = CString::new(msg).unwrap();
47        unsafe { sapp::console_info(string.as_ptr()); }
48    }
49
50    pub fn warn(msg: &str) {
51        use std::ffi::CString;
52        let string = CString::new(msg).unwrap();
53        unsafe { sapp::console_warn(string.as_ptr()); }
54    }
55    
56    pub fn error(msg: &str) {
57        use std::ffi::CString;
58        let string = CString::new(msg).unwrap();
59        unsafe { sapp::console_error(string.as_ptr()); }
60    }
61}
62
63fn log_record(record: &Record) {
64    // pick the console.log() variant for the appropriate logging level
65    let console_send = match record.level() {
66        Level::Error => console::error,
67        Level::Warn => console::warn,
68        Level::Info => console::info,
69        Level::Debug => console::log,
70        Level::Trace => console::debug,
71    };
72
73    console_send(&format!("{}", record.args()));
74}
75
76static LOGGER: WasmLogger = WasmLogger {};
77
78struct WasmLogger {}
79
80impl Log for WasmLogger {
81    fn enabled(&self, metadata: &Metadata) -> bool {
82        metadata.level() <= log::max_level()
83    }
84
85    fn log(&self, record: &Record) {
86        if !self.enabled(record.metadata()) {
87            return;
88        }
89
90        log_record(record);
91    }
92
93    fn flush(&self) {}
94}
95
96/// Initializes the global logger setting `max_log_level` to the given value.
97pub fn init_with_level(level: Level) -> Result<(), SetLoggerError> {
98    log::set_logger(&LOGGER)?;
99    log::set_max_level(level.to_level_filter());
100    Ok(())
101}
102
103/// Initializes the global logger with `max_log_level` set to `Level::Debug` (the only supported level for now).
104pub fn init() -> Result<(), SetLoggerError> {
105    init_with_level(Level::Debug)
106}
107
108#[cfg(test)]
109mod tests {
110    #[test]
111    fn it_works() -> Result<(), log::SetLoggerError> {
112        super::init()?;
113        Ok(debug!("test"))
114    }
115}