use std::fmt;
use thiserror::Error;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum ErrorPolicy {
FastFail,
#[default]
Accumulate,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Stage {
ResolveInput,
ResolveOutput,
Open,
Parse,
Serialize,
}
impl fmt::Display for Stage {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Stage::ResolveInput => write!(f, "ResolveInput"),
Stage::ResolveOutput => write!(f, "ResolveOutput"),
Stage::Open => write!(f, "Open"),
Stage::Parse => write!(f, "Parse"),
Stage::Serialize => write!(f, "Serialize"),
}
}
}
#[derive(Debug)]
pub struct SingleIoError {
pub stage: Stage,
pub target: String,
pub error: Box<dyn std::error::Error + Send + Sync>,
}
impl fmt::Display for SingleIoError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{}] {}: {}", self.stage, self.target, self.error)
}
}
impl std::error::Error for SingleIoError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(self.error.as_ref())
}
}
#[derive(Debug, Error)]
pub struct AggregateError {
pub errors: Vec<SingleIoError>,
}
impl fmt::Display for AggregateError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "I/O encountered {} error(s):", self.errors.len())?;
for (i, e) in self.errors.iter().enumerate() {
writeln!(f, " #{}: {}", i + 1, e)?;
}
Ok(())
}
}
impl AggregateError {
pub fn single(error: SingleIoError) -> Self {
Self {
errors: vec![error],
}
}
pub fn is_empty(&self) -> bool {
self.errors.is_empty()
}
pub fn len(&self) -> usize {
self.errors.len()
}
}
impl From<SingleIoError> for AggregateError {
fn from(error: SingleIoError) -> Self {
Self::single(error)
}
}
#[cfg(feature = "miette")]
mod miette_impl;
#[cfg(feature = "miette")]
pub use miette_impl::*;