use core::error::Error;
use core::fmt::Debug;
use core::fmt::Display;
pub struct MercError {
inner: Box<InnerMercError>,
}
impl MercError {
#[must_use]
pub fn downcast_ref<E: Error + 'static>(&self) -> Option<&E> {
self.inner.error.downcast_ref::<E>()
}
}
struct InnerMercError {
error: Box<dyn Error + Send + Sync + 'static>,
backtrace: std::backtrace::Backtrace,
}
impl<E> From<E> for MercError
where
Box<dyn Error + Send + Sync + 'static>: From<E>,
{
#[cold]
fn from(error: E) -> Self {
MercError {
inner: Box::new(InnerMercError {
error: error.into(),
backtrace: std::backtrace::Backtrace::capture(),
}),
}
}
}
impl Display for MercError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
writeln!(f, "{}", self.inner.error)?;
Ok(())
}
}
impl Debug for MercError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
writeln!(f, "{:?}", self.inner.error)?;
{
let backtrace = &self.inner.backtrace;
if let std::backtrace::BacktraceStatus::Captured = backtrace.status() {
writeln!(f, "{backtrace}")?;
}
}
Ok(())
}
}