use core::fmt;
use std::{error::Error, panic};
use color_eyre::eyre::{EyreHandler, Report};
use tracing::{Level, Span};
pub fn wrap_hook(base_hook: HookFunc) -> HookFunc {
Box::new(move |e| {
Box::new(PrettyHandler {
base: base_hook(e),
level: Level::ERROR,
span: Span::current(),
location: None,
})
})
}
pub fn extract_span(report: &Report) -> Option<&Span> {
report.handler().downcast_ref::<PrettyHandler>().map(|h| &h.span)
}
pub fn extract_location(report: &Report) -> Option<&'static panic::Location<'static>> {
report.handler().downcast_ref::<PrettyHandler>().and_then(|h| h.location)
}
pub fn extract_severity(report: &Report) -> Level {
report.handler().downcast_ref::<PrettyHandler>().map(|h| h.level).unwrap_or(Level::ERROR)
}
pub fn set_severity(report: &mut Report, level: Level) {
if let Some(handler) = report.handler_mut().downcast_mut::<PrettyHandler>() {
handler.level = level;
}
}
struct PrettyHandler {
base: Box<dyn EyreHandler>,
span: Span,
level: Level,
location: Option<&'static panic::Location<'static>>,
}
impl EyreHandler for PrettyHandler {
fn debug(&self, error: &(dyn Error + 'static), f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.base.debug(error, f)
}
fn display(&self, error: &(dyn Error + 'static), f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.base.display(error, f)
}
fn track_caller(&mut self, location: &'static panic::Location<'static>) {
self.base.track_caller(location);
self.location = Some(location);
}
}
type HookFunc = Box<dyn Fn(&(dyn Error + 'static)) -> Box<dyn EyreHandler> + Send + Sync + 'static>;