#[macro_use]
extern crate cfg_if;
use std::panic;
cfg_if! {
if #[cfg(target_arch = "wasm32")] {
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
mod logger;
#[wasm_bindgen]
extern {
#[wasm_bindgen(js_namespace = console, js_name="error")]
fn console_error(msg: String);
type Error;
#[wasm_bindgen(constructor)]
fn new() -> Error;
#[wasm_bindgen(structural, method, getter)]
fn stack(error: &Error) -> String;
}
fn process(info: &panic::PanicInfo) -> String{
let mut msg = info.to_string();
msg.push_str("\n\nStack:\n\n");
let e = Error::new();
let stack = e.stack();
msg.push_str(&stack);
msg.push_str("\n\n");
msg
}
fn console_hook(info: &panic::PanicInfo){
console_error(process(info));
}
fn popup_hook(info: &panic::PanicInfo){
logger::error(process(info));
}
fn init(logger_type:Type){
match logger_type {
Type::Console=>{
panic::set_hook(Box::new(console_hook));
}
Type::Popup=>{
logger::init_logger();
panic::set_hook(Box::new(popup_hook));
}
Type::Native=>{
panic!("Native logger not supported under wasm");
}
}
}
pub use logger::show_logs;
} else {
use std::io::{self, Write};
fn hook(info: &panic::PanicInfo) {
let _ = writeln!(io::stderr(), "{info}");
}
fn init(_logger_type:Type){
panic::set_hook(Box::new(hook));
}
pub fn show_logs(){
panic!("Native (non-WASM) platform build doesn't support panic logs");
}
}
}
pub enum Type {
Console,
Popup,
Native,
}
#[inline]
pub fn set_once(logger_type: Type) {
use std::sync::Once;
static SET_HOOK: Once = Once::new();
SET_HOOK.call_once(|| init(logger_type));
}