i3status_rs/
errors.rs

1use std::borrow::Cow;
2use std::fmt;
3use std::sync::Arc;
4
5pub use std::error::Error as StdError;
6
7/// Result type returned from functions that can have our `Error`s.
8pub type Result<T, E = Error> = std::result::Result<T, E>;
9
10type ErrorMsg = Cow<'static, str>;
11
12/// Error type
13#[derive(Debug, Clone)]
14pub struct Error {
15    pub message: Option<ErrorMsg>,
16    pub cause: Option<Arc<dyn StdError + Send + Sync + 'static>>,
17}
18
19impl Error {
20    pub fn new<T: Into<ErrorMsg>>(message: T) -> Self {
21        Self {
22            message: Some(message.into()),
23            cause: None,
24        }
25    }
26}
27
28pub trait ErrorContext<T> {
29    fn error<M: Into<ErrorMsg>>(self, message: M) -> Result<T>;
30    fn or_error<M: Into<ErrorMsg>, F: FnOnce() -> M>(self, f: F) -> Result<T>;
31}
32
33impl<T, E: StdError + Send + Sync + 'static> ErrorContext<T> for Result<T, E> {
34    fn error<M: Into<ErrorMsg>>(self, message: M) -> Result<T> {
35        self.map_err(|e| Error {
36            message: Some(message.into()),
37            cause: Some(Arc::new(e)),
38        })
39    }
40
41    fn or_error<M: Into<ErrorMsg>, F: FnOnce() -> M>(self, f: F) -> Result<T> {
42        self.map_err(|e| Error {
43            message: Some(f().into()),
44            cause: Some(Arc::new(e)),
45        })
46    }
47}
48
49impl<T> ErrorContext<T> for Option<T> {
50    fn error<M: Into<ErrorMsg>>(self, message: M) -> Result<T> {
51        self.ok_or_else(|| Error {
52            message: Some(message.into()),
53            cause: None,
54        })
55    }
56
57    fn or_error<M: Into<ErrorMsg>, F: FnOnce() -> M>(self, f: F) -> Result<T> {
58        self.ok_or_else(|| Error {
59            message: Some(f().into()),
60            cause: None,
61        })
62    }
63}
64
65impl fmt::Display for Error {
66    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67        f.write_str(self.message.as_deref().unwrap_or("Error"))?;
68
69        if let Some(cause) = &self.cause {
70            write!(f, ". Cause: {cause}")?;
71        }
72
73        Ok(())
74    }
75}
76
77impl From<Error> for zbus::fdo::Error {
78    fn from(err: Error) -> Self {
79        Self::Failed(err.to_string())
80    }
81}
82
83impl StdError for Error {}
84
85pub trait ToSerdeError<T> {
86    fn serde_error<E: serde::de::Error>(self) -> Result<T, E>;
87}
88
89impl<T, F> ToSerdeError<T> for Result<T, F>
90where
91    F: fmt::Display,
92{
93    fn serde_error<E: serde::de::Error>(self) -> Result<T, E> {
94        self.map_err(E::custom)
95    }
96}
97
98pub struct BoxErrorWrapper(pub Box<dyn StdError + Send + Sync + 'static>);
99
100impl fmt::Debug for BoxErrorWrapper {
101    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102        fmt::Debug::fmt(&self.0, f)
103    }
104}
105
106impl fmt::Display for BoxErrorWrapper {
107    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108        fmt::Display::fmt(&self.0, f)
109    }
110}
111
112impl StdError for BoxErrorWrapper {}