use std::any::Any;
use std::panic::{AssertUnwindSafe, catch_unwind};
pub(crate) type Panic = Box<dyn Any + Send + 'static>;
#[inline(always)]
pub(crate) fn catch(f: impl FnOnce()) -> Option<Panic> {
catch_unwind(AssertUnwindSafe(f)).err()
}
pub(crate) type Thin = Box<Panic>;
pub(crate) fn message(panic: &Panic) -> Option<&str> {
panic
.downcast_ref::<&str>()
.copied()
.or_else(|| panic.downcast_ref::<String>().map(String::as_str))
}
#[cold]
#[inline(never)]
pub(crate) fn lost(what: core::fmt::Arguments<'_>, panic: Panic) {
match message(&panic) {
Some(message) => log::error!("{what}: {message}"),
None => log::error!("{what}"),
}
drop_payload(panic);
}
pub(crate) fn drop_payload(panic: Panic) {
if let Err(again) = catch_unwind(AssertUnwindSafe(|| drop(panic))) {
core::mem::forget(again);
}
}