#![doc = include_str!("README.md")] #![cfg_attr(feature = "backtrace", feature(backtrace))] mod context; pub use context::{Context, IntoContext, ToContext}; mod report; pub use report::{Report, ReportFmt}; use report::{report_write, Indentation}; mod explain; pub use explain::Explain; pub type Result = std::result::Result; /// Does not implement [`std::error::Error`] to allow a [`From`] implementation for all other error types. #[derive(Debug)] pub struct How { /// When true, the error will cause branchers to abort. classified: bool, context: Vec, #[cfg(feature = "backtrace")] backtrace: std::backtrace::Backtrace, } impl How { pub fn new(context: impl IntoContext) -> Self { Self { classified: false, context: vec![context.into_context()], #[cfg(feature = "backtrace")] backtrace: std::backtrace::Backtrace::capture(), } } pub fn clone_without_backtrace(&self) -> Self { Self { classified: self.classified, context: self.context.clone(), #[cfg(feature = "backtrace")] backtrace: std::backtrace::Backtrace::disabled(), } } #[inline] pub const fn classified(mut self) -> Self { self.classified = true; self } pub fn context(mut self, context: impl IntoContext) -> Self { self.context.push(context.into_context()); self } #[inline] pub const fn is_classified(&self) -> bool { self.classified } } impl std::fmt::Display for How { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut opts = ReportFmt::default().indent_first(false); report_write!(f, &opts, "Parsing failed")?; for context in self.context.iter().rev() { write!(f, "\n{}└ ", Indentation(opts.indentation()))?; context.fmt(f, &opts)?; opts = opts.indent(); } #[cfg(feature = "backtrace")] { write!(f, "\n{}", self.backtrace)?; }; Ok(()) } } impl From for How where E: std::error::Error, { fn from(value: E) -> Self { Self::new(value.to_string()) } }