use core::any::Any;
use core::fmt;
use std::sync::Arc;
use crate::HandlerId;
pub struct PanicInfo<'a> {
handler_id: HandlerId,
payload: &'a (dyn Any + Send + 'static),
}
impl<'a> PanicInfo<'a> {
#[inline]
pub(crate) fn new(handler_id: HandlerId, payload: &'a (dyn Any + Send + 'static)) -> Self {
Self {
handler_id,
payload,
}
}
#[inline]
#[must_use]
pub fn handler_id(&self) -> HandlerId {
self.handler_id
}
#[inline]
#[must_use]
pub fn payload(&self) -> &(dyn Any + Send + 'static) {
self.payload
}
#[inline]
#[must_use]
pub fn message(&self) -> Option<&str> {
if let Some(s) = self.payload.downcast_ref::<&'static str>() {
Some(*s)
} else if let Some(s) = self.payload.downcast_ref::<String>() {
Some(s.as_str())
} else {
None
}
}
}
impl fmt::Debug for PanicInfo<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("PanicInfo")
.field("handler_id", &self.handler_id)
.field("message", &self.message())
.finish()
}
}
pub(crate) type PanicCallback = dyn Fn(&PanicInfo<'_>) + Send + Sync + 'static;
pub(crate) struct PanicCallbackHolder {
inner: Arc<PanicCallback>,
}
impl PanicCallbackHolder {
#[inline]
pub(crate) fn new<F>(callback: F) -> Self
where
F: Fn(&PanicInfo<'_>) + Send + Sync + 'static,
{
Self {
inner: Arc::new(callback),
}
}
#[inline]
pub(crate) fn invoke(&self, info: &PanicInfo<'_>) {
(self.inner)(info);
}
}