use std::any::Any;
use std::fmt::{Debug, Formatter};
use std::marker::PhantomData;
use crate::internal::*;
pub struct Error<T>(PhantomData<T>, pub ErrorId, pub Box<dyn Any>, pub fn (&Box<dyn Any>, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error>);
impl<T> Debug for Error<T>
{
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error>
{
self.3(&self.2, f)
}
}
impl<T> Error<T>
{
pub fn map<Output, F: FnOnce(Self) -> Output>(self, f: F) -> Output
{
f(self)
}
pub fn map_every<Func, ReturnType>(&self, func : &Func) -> ReturnType where T : MapEveryError<Func, ReturnType>
{
T::map_every_internal(self.1, &self.2,func).unwrap()
}
pub fn into_err_unchecked<Output>(self) -> Error<Output>
{
Error(PhantomData, self.1, self.2, self.3)
}
pub fn subtract_errors<Errors : GetErrorSet>(self) -> Error<ErrorSubtract<T, Errors>>
{
self.into_err_unchecked()
}
}
pub trait WrapError<T>
{
fn wrap_error(self) -> Error<T>;
}
impl<T : HasErrorId + 'static + Debug> WrapError<T> for T
{
fn wrap_error(self) -> Error<T> {
fn debug<S : Debug + 'static>(b : &Box<dyn Any>, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error>
{
let ref_self : &S = b.downcast_ref().unwrap();
ref_self.fmt(f)
}
Error(PhantomData, Self::ERROR_ID, Box::new(self), debug::<Self>)
}
}
impl<T> WrapError<T> for Error<T>
{
fn wrap_error(self) -> Error<T> {
self
}
}