88 lines
2.2 KiB
Rust
88 lines
2.2 KiB
Rust
#![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<T, E = How> = std::result::Result<T, E>;
|
|
|
|
/// 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<Context>,
|
|
#[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<E> From<E> for How
|
|
where
|
|
E: std::error::Error,
|
|
{
|
|
fn from(value: E) -> Self {
|
|
Self::new(value.to_string())
|
|
}
|
|
}
|