aranya_trouble/
lib.rs

1//! This crate exports a wrapper type to implement [`core::error::Error`] for a third-party type.
2
3#![no_std]
4#![warn(missing_docs)]
5
6use core::{fmt, ops::Deref};
7
8/// A wrapper around some error `E` so that it implements [`core::error::Error`].
9///
10/// This is useful for third-party types that have not adapted to the recently stabilized
11/// `error-in-core` feature and thus do not implement the trait when `std` is not available.
12#[derive(Copy, Clone)]
13#[repr(transparent)]
14pub struct Trouble<E>(pub E);
15
16impl<E: 'static> Trouble<E> {
17    /// Cast a reference to add `Trouble` around it.
18    pub fn cast(err: &E) -> &Self {
19        // SAFETY: `err` and `Self` have the same memory layout.
20        unsafe { &*core::ptr::from_ref(err).cast() }
21    }
22}
23
24impl<E: fmt::Display> fmt::Display for Trouble<E> {
25    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26        self.0.fmt(f)
27    }
28}
29
30impl<E: fmt::Debug> fmt::Debug for Trouble<E> {
31    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32        self.0.fmt(f)
33    }
34}
35
36impl<E: fmt::Display + fmt::Debug> core::error::Error for Trouble<E> {}
37
38impl<E> Deref for Trouble<E> {
39    type Target = E;
40
41    fn deref(&self) -> &Self::Target {
42        &self.0
43    }
44}