• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use alloc::format;
2 
3 #[no_mangle]
diplomat_init()4 unsafe extern "C" fn diplomat_init() {
5     #[cfg(debug_assertions)]
6     std::panic::set_hook(Box::new(panic_handler));
7     #[cfg(feature = "log")]
8     log::set_logger(&ConsoleLogger)
9         .map(|()| log::set_max_level(log::LevelFilter::Debug))
10         .unwrap();
11 }
12 
panic_handler(info: &std::panic::PanicInfo)13 fn panic_handler(info: &std::panic::PanicInfo) {
14     let msg = match info.payload().downcast_ref::<&'static str>() {
15         Some(&s) => s,
16         None => match info.payload().downcast_ref::<String>() {
17             Some(s) => s.as_str(),
18             None => "Box<Any>",
19         },
20     };
21 
22     let msg = match info.location() {
23         Some(l) => format!(
24             "wasm panicked at {}:{}:{}:\n{msg}",
25             l.file(),
26             l.line(),
27             l.column(),
28         ),
29         None => format!("wasm panicked at <unknown location>:\n{msg}"),
30     };
31 
32     extern "C" {
33         fn diplomat_throw_error_js(ptr: *const u8, len: usize);
34     }
35 
36     unsafe { diplomat_throw_error_js(msg.as_ptr(), msg.len()) }
37 }
38 
39 #[cfg(feature = "log")]
40 struct ConsoleLogger;
41 
42 #[cfg(feature = "log")]
43 impl log::Log for ConsoleLogger {
44     #[inline]
enabled(&self, metadata: &log::Metadata) -> bool45     fn enabled(&self, metadata: &log::Metadata) -> bool {
46         metadata.level() <= log::max_level()
47     }
48 
log(&self, record: &log::Record)49     fn log(&self, record: &log::Record) {
50         if !self.enabled(record.metadata()) {
51             return;
52         }
53 
54         let out = match record.level() {
55             log::Level::Error => {
56                 extern "C" {
57                     fn diplomat_console_error_js(ptr: *const u8, len: usize);
58                 }
59                 diplomat_console_error_js
60             }
61             log::Level::Warn => {
62                 extern "C" {
63                     fn diplomat_console_warn_js(ptr: *const u8, len: usize);
64                 }
65                 diplomat_console_warn_js
66             }
67             log::Level::Info => {
68                 extern "C" {
69                     fn diplomat_console_info_js(ptr: *const u8, len: usize);
70                 }
71                 diplomat_console_info_js
72             }
73             log::Level::Debug => {
74                 extern "C" {
75                     fn diplomat_console_log_js(ptr: *const u8, len: usize);
76                 }
77                 diplomat_console_log_js
78             }
79             log::Level::Trace => {
80                 extern "C" {
81                     fn diplomat_console_debug_js(ptr: *const u8, len: usize);
82                 }
83                 diplomat_console_debug_js
84             }
85         };
86 
87         let msg = alloc::format!("{}", record.args());
88 
89         unsafe { out(msg.as_ptr(), msg.len()) };
90     }
91 
flush(&self)92     fn flush(&self) {}
93 }
94