#[cfg(any(feature = "alloc", feature = "std"))]
use alloc::{borrow::Cow, string::String};
use core::fmt;
pub struct Error<E> {
#[cfg(any(feature = "alloc", feature = "std"))]
pub context: Cow<'static, str>,
#[cfg(not(any(feature = "alloc", feature = "std")))]
pub context: &'static str,
pub source: E,
}
impl<E> Error<E> {
#[inline]
pub fn new(context: &'static str, source: E) -> Self {
Self {
#[cfg(any(feature = "alloc", feature = "std"))]
context: Cow::Borrowed(context),
#[cfg(not(any(feature = "alloc", feature = "std")))]
context,
source,
}
}
#[cfg(any(feature = "alloc", feature = "std"))]
#[inline]
pub fn new_owned(context: String, source: E) -> Self {
Self {
context: Cow::Owned(context),
source,
}
}
#[inline]
pub fn context(&self) -> &str {
#[cfg(any(feature = "alloc", feature = "std"))]
{
&self.context
}
#[cfg(not(any(feature = "alloc", feature = "std")))]
{
self.context
}
}
#[inline]
pub fn into_source(self) -> E {
self.source
}
#[inline]
pub fn map<F, E2>(self, f: F) -> Error<E2>
where
F: FnOnce(E) -> E2,
{
Error {
context: self.context,
source: f(self.source),
}
}
}
impl<E: fmt::Display> fmt::Display for Error<E> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}: {}", self.context(), self.source)
}
}
impl<E: fmt::Debug> fmt::Debug for Error<E> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Error")
.field("context", &self.context())
.field("source", &self.source)
.finish()
}
}
impl<E: Clone> Clone for Error<E> {
#[inline]
fn clone(&self) -> Self {
Self {
#[cfg(any(feature = "alloc", feature = "std"))]
context: self.context.clone(),
#[cfg(not(any(feature = "alloc", feature = "std")))]
context: self.context,
source: self.source.clone(),
}
}
}
impl<E: PartialEq> PartialEq for Error<E> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.context() == other.context() && self.source == other.source
}
}
impl<E: Eq> Eq for Error<E> {}
#[cfg(feature = "std")]
impl<E: std::error::Error + 'static> std::error::Error for Error<E> {
#[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.source)
}
}