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 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
96pub 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
103pub 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}