mod mode;
mod utils;
pub use mode::*;
pub use utils::{escape_text, Unescaped};
use std::panic;
use std::sync::Once;
fn handle<M>(mode: &M, info: &panic::PanicInfo)
where
M: PresentationMode,
{
let msg = format!("Application panicked: {info}");
web_sys::console::error_1(&msg.into());
let details = PanicDetails::from(info);
if let Err(err) = mode.present(details) {
web_sys::console::error_2(&"Panic hook failed".into(), &err.as_ref().into());
}
}
pub trait IntoPanicHook {
fn into_panic_hook(self) -> Box<dyn Fn(&panic::PanicInfo) + 'static + Sync + Send>;
}
impl<T> IntoPanicHook for T
where
T: PresentationMode + 'static + Send + Sync,
{
fn into_panic_hook(self) -> Box<dyn Fn(&panic::PanicInfo) + 'static + Sync + Send> {
Box::new(move |info| handle(&self, info))
}
}
static SET_HOOK: Once = Once::new();
pub fn set_once<F, M>(f: F)
where
F: FnOnce() -> M,
M: PresentationMode + 'static + Send + Sync,
{
SET_HOOK.call_once(move || panic::set_hook(f().into_panic_hook()))
}
#[inline]
pub fn set_once_default() {
set_once(|| Basic)
}