|
1 |
| -use core::fmt::{Debug, Display}; |
2 |
| -use downcast_rs::{impl_downcast, DowncastSync}; |
| 1 | +use alloc::boxed::Box; |
| 2 | +use core::{ |
| 3 | + any::{type_name, Any}, |
| 4 | + fmt::{Debug, Display}, |
| 5 | +}; |
3 | 6 |
|
4 | 7 | /// Trait that allows the host to return custom error.
|
5 | 8 | ///
|
@@ -56,5 +59,47 @@ use downcast_rs::{impl_downcast, DowncastSync};
|
56 | 59 | /// _ => panic!(),
|
57 | 60 | /// }
|
58 | 61 | /// ```
|
59 |
| -pub trait HostError: 'static + Display + Debug + DowncastSync {} |
60 |
| -impl_downcast!(HostError); |
| 62 | +pub trait HostError: 'static + Display + Debug + Any + Send + Sync {} |
| 63 | + |
| 64 | +impl dyn HostError { |
| 65 | + /// Returns `true` if `self` is of type `T`. |
| 66 | + pub fn is<T: HostError>(&self) -> bool { |
| 67 | + (self as &dyn Any).is::<T>() |
| 68 | + } |
| 69 | + |
| 70 | + /// Downcasts the [`HostError`] into a shared reference to a `T` if possible. |
| 71 | + /// |
| 72 | + /// Returns `None` otherwise. |
| 73 | + #[inline] |
| 74 | + pub fn downcast_ref<T: HostError>(&self) -> Option<&T> { |
| 75 | + (self as &dyn Any).downcast_ref::<T>() |
| 76 | + } |
| 77 | + |
| 78 | + /// Downcasts the [`HostError`] into an exclusive reference to a `T` if possible. |
| 79 | + /// |
| 80 | + /// Returns `None` otherwise. |
| 81 | + #[inline] |
| 82 | + pub fn downcast_mut<T: HostError>(&mut self) -> Option<&mut T> { |
| 83 | + (self as &mut dyn Any).downcast_mut::<T>() |
| 84 | + } |
| 85 | + |
| 86 | + /// Consumes `self` to downcast the [`HostError`] into the `T` if possible. |
| 87 | + /// |
| 88 | + /// # Errors |
| 89 | + /// |
| 90 | + /// If `self` cannot be downcast to `T`. |
| 91 | + #[inline] |
| 92 | + pub fn downcast<T: HostError>(self: Box<Self>) -> Result<Box<T>, Box<Self>> { |
| 93 | + if self.is::<T>() { |
| 94 | + let Ok(value) = (self as Box<dyn Any>).downcast::<T>() else { |
| 95 | + unreachable!( |
| 96 | + "failed to downcast `HostError` to T (= {})", |
| 97 | + type_name::<T>() |
| 98 | + ); |
| 99 | + }; |
| 100 | + Ok(value) |
| 101 | + } else { |
| 102 | + Err(self) |
| 103 | + } |
| 104 | + } |
| 105 | +} |
0 commit comments