Skip to main content

topcoat_core/
error.rs

1use std::{
2    fmt::{Debug, Display},
3    ops::{Deref, DerefMut},
4};
5
6pub type Result<T, E = Error> = ::core::result::Result<T, E>;
7
8/// Error type used by Topcoat APIs.
9///
10/// This is a thin wrapper around [`anyhow::Error`] that provides a shared
11/// application error type while still allowing callers to inspect, downcast,
12/// and mutate the underlying error when needed.
13#[derive(Debug)]
14pub struct Error(anyhow::Error);
15
16impl Error {
17    /// Attempt to downcast the error object to a concrete type.
18    ///
19    /// # Errors
20    ///
21    /// Returns `Err(Self)` if the stored error is not an instance of `E`,
22    /// handing back the original error unchanged.
23    #[inline]
24    pub fn downcast<E>(self) -> Result<E, Self>
25    where
26        E: Display + Debug + Send + Sync + 'static,
27    {
28        self.0.downcast::<E>().map_err(Self)
29    }
30
31    /// Downcast this error object by reference.
32    #[inline]
33    #[must_use]
34    pub fn downcast_ref<E>(&self) -> Option<&E>
35    where
36        E: Display + Debug + Send + Sync + 'static,
37    {
38        self.0.downcast_ref::<E>()
39    }
40
41    /// Downcast this error object by mutable reference.
42    #[inline]
43    pub fn downcast_mut<E>(&mut self) -> Option<&mut E>
44    where
45        E: Display + Debug + Send + Sync + 'static,
46    {
47        self.0.downcast_mut::<E>()
48    }
49}
50
51impl Display for Error {
52    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53        Display::fmt(&self.0, f)
54    }
55}
56
57impl Deref for Error {
58    type Target = anyhow::Error;
59
60    fn deref(&self) -> &Self::Target {
61        &self.0
62    }
63}
64
65impl DerefMut for Error {
66    fn deref_mut(&mut self) -> &mut Self::Target {
67        &mut self.0
68    }
69}
70
71impl<T> From<T> for Error
72where
73    T: Into<anyhow::Error>,
74{
75    fn from(value: T) -> Self {
76        Self(value.into())
77    }
78}