use alloc::borrow::Cow;
use core::{
any::{Any, type_name},
fmt::Debug,
};
use crate::cause::Cause;
use crate::error::UniError;
pub trait UniKind: Debug + Any + Send + Sync {
fn value(&self, _cause: Option<Cause<'_>>) -> Cow<'static, str> {
Cow::Borrowed("")
}
fn context(&self, _cause: Option<Cause<'_>>) -> Option<Cow<'static, str>> {
None
}
fn code(&self, _cause: Option<Cause<'_>>) -> i32 {
-1
}
fn code2(&self, _cause: Option<Cause<'_>>) -> i32 {
-1
}
fn type_name(&self) -> &'static str {
type_name::<Self>()
}
fn into_error(self) -> UniError<Self>
where
Self: Sized,
{
UniError::from_kind(self)
}
}
impl dyn UniKind {
pub fn downcast_ref<K: UniKind>(&self) -> Option<&K> {
let err: &dyn Any = self;
err.downcast_ref()
}
}
impl UniKind for () {}
pub trait UniKindCode: UniKind {
type Code;
fn typed_code(&self, cause: Option<Cause<'_>>) -> Self::Code;
}
impl<C> dyn UniKindCode<Code = C> {
pub fn downcast_ref<K: UniKindCode<Code = C>>(&self) -> Option<&K> {
let err: &dyn Any = self;
err.downcast_ref()
}
}
pub trait UniKindCodes: UniKindCode {
type Code2;
fn typed_code2(&self, cause: Option<Cause<'_>>) -> Self::Code2;
}
impl<C, C2> dyn UniKindCodes<Code = C, Code2 = C2> {
pub fn downcast_ref<K: UniKindCodes<Code = C, Code2 = C2>>(&self) -> Option<&K> {
let err: &dyn Any = self;
err.downcast_ref()
}
}