use std::{any, path::Path, time::Duration};
use crate::{
attachment::{
FromTo, Unsupported, {self},
},
ty, AttachExt, Context, Report, ThinContext,
};
use crate::{attachment::DisplayDuration, Field};
#[derive(Debug, thiserror::Error)]
#[error("{0}")]
pub struct BoxError(Box<dyn std::error::Error + 'static + Send + Sync>);
#[derive(Debug, thiserror::Error)]
#[error("{0}")]
pub struct BoxCoreError(Box<dyn CoreError>);
#[derive(ThinContext)]
#[bigerror(crate)]
pub struct DecodeError;
#[derive(ThinContext)]
#[bigerror(crate)]
pub struct EncodeError;
#[derive(ThinContext)]
#[bigerror(crate)]
pub struct DeriveError;
#[derive(ThinContext)]
#[bigerror(crate)]
pub struct AuthError;
#[derive(ThinContext)]
#[bigerror(crate)]
pub struct NetworkError;
#[derive(ThinContext)]
#[bigerror(crate)]
pub struct ParseError;
#[derive(ThinContext)]
#[bigerror(crate)]
pub struct NotFound;
#[derive(ThinContext)]
#[bigerror(crate)]
pub struct DbError;
#[derive(ThinContext)]
#[bigerror(crate)]
pub struct FsError;
#[derive(ThinContext)]
#[bigerror(crate)]
pub struct SetupError;
#[derive(ThinContext)]
#[bigerror(crate)]
pub struct ConversionError;
#[derive(ThinContext)]
#[bigerror(crate)]
pub struct InvalidInput;
#[derive(ThinContext)]
#[bigerror(crate)]
pub struct InvalidStatus;
#[derive(ThinContext)]
#[bigerror(crate)]
pub struct InvalidState;
#[derive(ThinContext)]
#[bigerror(crate)]
pub struct ConfigError;
#[derive(ThinContext)]
#[bigerror(crate)]
pub struct BuildError;
#[derive(Debug, thiserror::Error)]
#[error("{}", Field::new("timeout", DisplayDuration(*.0)))]
pub struct Timeout(pub Duration);
#[derive(ThinContext)]
#[bigerror(crate)]
pub struct AssertionError;
pub trait CoreError: core::fmt::Debug + core::fmt::Display + Send + Sync + 'static {}
impl<T> CoreError for T where T: core::fmt::Debug + core::fmt::Display + Send + Sync + 'static {}
impl BoxError {
#[track_caller]
pub fn new<E>(err: E) -> Report<Self>
where
E: std::error::Error + 'static + Send + Sync,
{
Report::new(Self(Box::new(err)))
}
#[track_caller]
pub fn from(err: Box<dyn std::error::Error + 'static + Send + Sync>) -> Report<Self> {
Report::new(Self(err))
}
}
impl BoxCoreError {
#[track_caller]
pub fn new<E: CoreError>(err: E) -> Report<Self> {
Report::new(Self(Box::new(err)))
}
#[track_caller]
pub fn from(err: Box<dyn CoreError>) -> Report<Self> {
Report::new(Self(err))
}
}
impl InvalidInput {
#[track_caller]
pub fn with_path(path: impl AsRef<Path>) -> Report<Self> {
let path = path.as_ref().display().to_string();
Report::new(Self).attach_kv("path", path)
}
#[track_caller]
pub fn type_name<T: ?Sized>() -> Report<Self> {
let type_name = any::type_name::<T>();
Report::new(Self).attach_printable(format!("type: {type_name}"))
}
#[track_caller]
pub fn unsupported() -> Report<Self> {
Report::new(Self).attach_printable(Unsupported)
}
}
impl ConversionError {
#[track_caller]
pub fn new<F, T>() -> Report<Self> {
Report::new(Self).attach_printable(FromTo(ty!(F), ty!(T)))
}
#[track_caller]
pub fn from<F, T>(ctx: impl Context) -> Report<Self> {
Self::from_ctx(ctx).attach_printable(FromTo(ty!(F), ty!(T)))
}
#[track_caller]
pub fn set<F, T>(report: Report<impl Context>) -> Report<Self> {
report
.change_context(Self)
.attach_printable(FromTo(ty!(F), ty!(T)))
}
}
impl NotFound {
#[track_caller]
pub fn with_field(field: &'static str) -> Report<Self> {
Report::new(Self).attach_printable(Field::new(field, attachment::Missing))
}
}
impl ParseError {
#[track_caller]
pub fn with_field(field: &'static str) -> Report<Self> {
Report::new(Self).attach_printable(Field::new(field, attachment::Invalid))
}
}