extern crate alloc;
use alloc::borrow::Cow;
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::{
any::Any,
error::Error,
fmt::{Debug, Display},
};
use crate::gerr::{ErrorLocation, Source};
pub trait IdSource: Any + Debug + Display + Send + Sync {}
impl<T> IdSource for T where T: Any + Debug + Display + Send + Sync {}
pub trait DataSource: Any + Debug + Send + Sync {}
impl<T> DataSource for T where T: Any + Debug + Send + Sync {}
pub struct GErrSource {
pub id: Option<Box<dyn IdSource>>,
#[cfg(feature = "serde")]
pub id_json: Option<serde_json::Value>,
pub code: Option<Cow<'static, str>>,
pub message: Cow<'static, str>,
pub sources: Option<Vec<Source>>,
pub tags: Option<Vec<Cow<'static, str>>>,
pub data: Option<Box<dyn DataSource>>,
pub help: Option<Cow<'static, str>>,
#[cfg(feature = "serde")]
pub data_json: Option<serde_json::Value>,
pub location: Option<ErrorLocation>,
}
impl Debug for GErrSource {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut debug = f.debug_struct("GErrSource");
debug.field("id", &self.id);
#[cfg(feature = "serde")]
debug.field("id_json", &self.id_json);
debug
.field("code", &self.code)
.field("message", &self.message)
.field("sources", &self.sources)
.field("tags", &self.tags)
.field("data", &self.data);
#[cfg(feature = "serde")]
debug.field("data_json", &self.data_json);
debug
.field("help", &self.help)
.field("location", &self.location);
debug.finish()
}
}
impl Display for GErrSource {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if let Some(code) = self.code.as_deref() {
write!(f, "{code} - {}", self.message)
} else {
write!(f, "{}", self.message)
}
}
}
impl Error for GErrSource {
fn source(&self) -> Option<&(dyn Error + 'static)> {
if let Some(ref sources) = self.sources
&& !sources.is_empty()
{
return sources.first().map(|s| match s {
Source::Err(e) => &**e as &(dyn Error + 'static),
Source::GErr(e) => &**e as &(dyn Error + 'static),
});
}
None
}
}