use derive_more as dm;
#[cfg(not(feature = "std"))]
use core::time::Duration;
#[cfg(feature = "std")]
use std::{path::Path, time::Duration};
#[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format};
use crate::{
Index, Report, ThinContext,
attachment::{self, Display, FromTo, Unsupported, simple_type_name},
ty,
};
#[cfg(feature = "std")]
use crate::AttachExt;
use crate::{Field, attachment::DisplayDuration};
#[derive(Debug, dm::Display)]
#[display("{_0}")]
pub struct BoxError(Box<dyn core::error::Error + 'static + Send + Sync>);
impl ::core::error::Error for BoxError {}
#[derive(ThinContext)]
#[bigerror(crate)]
pub struct DecodeError;
#[derive(ThinContext)]
#[bigerror(crate)]
pub struct EncodeError;
#[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, dm::Display)]
#[display("{}", Field::new("timeout", DisplayDuration(self.0)))]
pub struct Timeout(pub Duration);
impl ::core::error::Error for Timeout {}
#[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: core::error::Error + 'static + Send + Sync,
{
Report::new(Self(Box::new(err)))
}
#[track_caller]
pub fn from(err: Box<dyn core::error::Error + 'static + Send + Sync>) -> Report<Self> {
Report::new(Self(err))
}
}
impl FsError {
#[cfg(feature = "std")]
#[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)
}
}
impl InvalidInput {
#[cfg(feature = "std")]
#[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 = simple_type_name::<T>();
Report::new(Self).attach(format!("type: {type_name}"))
}
#[track_caller]
pub fn unsupported() -> Report<Self> {
Report::new(Self).attach(Unsupported)
}
}
impl ConversionError {
#[track_caller]
pub fn new<F, T>() -> Report<Self> {
Report::new(Self).attach(FromTo(ty!(F), ty!(T)))
}
#[track_caller]
pub fn from<F, T>(ctx: impl core::error::Error + Send + Sync + 'static) -> Report<Self> {
Self::report(ctx).attach(FromTo(ty!(F), ty!(T)))
}
}
impl NotFound {
#[track_caller]
pub fn with_field(field: &'static str) -> Report<Self> {
Report::new(Self).attach(Field::new(field, attachment::Missing))
}
pub fn with_index<T, K: Display>(key: K) -> Report<Self> {
Self::attach_kv(Index(key), ty!(T))
}
}
impl ParseError {
#[track_caller]
pub fn with_field(field: &'static str) -> Report<Self> {
Report::new(Self).attach(Field::new(field, attachment::Invalid))
}
}