Skip to content

Commit

Permalink
Add StdError impls for core and alloc errors
Browse files Browse the repository at this point in the history
  • Loading branch information
djkoloski committed Aug 11, 2024
1 parent 71178af commit 421fafd
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 40 deletions.
43 changes: 3 additions & 40 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ use std as alloc;

#[cfg(feature = "alloc")]
mod boxed_error;
// #[cfg(not(feature = "std"))]
mod std_error;
#[cfg(feature = "alloc")]
mod thin_box;

Expand All @@ -47,47 +49,8 @@ use core::{
};
#[cfg(feature = "std")]
pub use std::error::Error as StdError;

#[cfg(not(feature = "std"))]
/// An error that can be debugged and displayed.
///
/// With the `std` feature enabled, this is a re-export of the [`Error`] trait
/// instead.
///
/// [`Error`]: std::error::Error
pub trait StdError: fmt::Debug + fmt::Display {
/// The lower-level source of this error, if any.
fn source(&self) -> Option<&(dyn StdError + 'static)> {
None
}
}

#[cfg(not(feature = "std"))]
// SAFETY: The metadata type of `dyn StdError` is `DynMetadata<dyn StdError>`.
unsafe impl ptr_meta::Pointee for dyn StdError {
type Metadata = ptr_meta::DynMetadata<dyn StdError>;
}

#[cfg(not(feature = "std"))]
// SAFETY: The metadata type of `dyn StdError + Send` is
// `DynMetadata<dyn StdError + Send>`.
unsafe impl ptr_meta::Pointee for dyn StdError + Send {
type Metadata = ptr_meta::DynMetadata<dyn StdError + Send>;
}

#[cfg(not(feature = "std"))]
// SAFETY: The metadata type of `dyn StdError + Sync` is
// `DynMetadata<dyn StdError + Sync>`.
unsafe impl ptr_meta::Pointee for dyn StdError + Sync {
type Metadata = ptr_meta::DynMetadata<dyn StdError + Sync>;
}

#[cfg(not(feature = "std"))]
// SAFETY: The metadata type of `dyn StdError + Send + Sync` is
// `DynMetadata<dyn StdError + Send + Sync>`.
unsafe impl ptr_meta::Pointee for dyn StdError + Send + Sync {
type Metadata = ptr_meta::DynMetadata<dyn StdError + Send + Sync>;
}
pub use self::std_error::StdError;

/// A type which can add an additional trace to itself.
pub trait Trace: Sized + Send + Sync + 'static {
Expand Down
117 changes: 117 additions & 0 deletions src/std_error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
use core::{
alloc::LayoutError,
array::TryFromSliceError,
cell::{BorrowError, BorrowMutError},
char::{CharTryFromError, DecodeUtf16Error, ParseCharError, TryFromCharError},
ffi::{
FromBytesUntilNulError,
FromBytesWithNulError,
},
fmt,
num::{ParseFloatError, ParseIntError, TryFromIntError}, str::{ParseBoolError, Utf8Error},
time::TryFromFloatSecsError,
};
#[cfg(feature = "alloc")]
use crate::alloc::{
collections::TryReserveError,
ffi::{
NulError,
FromVecWithNulError,
IntoStringError,
},
string::{FromUtf16Error, FromUtf8Error},
};

/// An error that can be debugged and displayed.
///
/// With the `std` feature enabled, this is a re-export of the [`Error`] trait
/// instead.
///
/// [`Error`]: std::error::Error
pub trait StdError: fmt::Debug + fmt::Display {
/// The lower-level source of this error, if any.
fn source(&self) -> Option<&(dyn StdError + 'static)> {
None
}
}

// SAFETY: The metadata type of `dyn StdError` is `DynMetadata<dyn StdError>`.
unsafe impl ptr_meta::Pointee for dyn StdError {
type Metadata = ptr_meta::DynMetadata<dyn StdError>;
}

// SAFETY: The metadata type of `dyn StdError + Send` is
// `DynMetadata<dyn StdError + Send>`.
unsafe impl ptr_meta::Pointee for dyn StdError + Send {
type Metadata = ptr_meta::DynMetadata<dyn StdError + Send>;
}

// SAFETY: The metadata type of `dyn StdError + Sync` is
// `DynMetadata<dyn StdError + Sync>`.
unsafe impl ptr_meta::Pointee for dyn StdError + Sync {
type Metadata = ptr_meta::DynMetadata<dyn StdError + Sync>;
}

// SAFETY: The metadata type of `dyn StdError + Send + Sync` is
// `DynMetadata<dyn StdError + Send + Sync>`.
unsafe impl ptr_meta::Pointee for dyn StdError + Send + Sync {
type Metadata = ptr_meta::DynMetadata<dyn StdError + Send + Sync>;
}

impl<T: StdError> StdError for &'_ T {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
T::source(self)
}
}

#[cfg(feature = "alloc")]
impl<T: StdError> StdError for crate::alloc::boxed::Box<T> {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
T::source(self)
}
}

#[cfg(feature = "alloc")]
impl<T: StdError> StdError for crate::alloc::sync::Arc<T> {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
T::source(self)
}
}

macro_rules! impl_std_error {
($($tys:ty),* $(,)?) => {
$(
impl StdError for $tys {}
)*
}
}

impl_std_error! {
LayoutError,
TryFromSliceError,
BorrowError,
BorrowMutError,
CharTryFromError,
DecodeUtf16Error,
ParseCharError,
TryFromCharError,
FromBytesUntilNulError,
FromBytesWithNulError,
fmt::Error,
ParseFloatError,
ParseIntError,
TryFromIntError,
ParseBoolError,
Utf8Error,
FromUtf8Error,
FromUtf16Error,
TryFromFloatSecsError,
}

#[cfg(feature = "alloc")]
impl_std_error! {
TryReserveError,
NulError,
FromVecWithNulError,
IntoStringError,
}

0 comments on commit 421fafd

Please sign in to comment.