i3status_rs/
errors.rs
1use std::borrow::Cow;
2use std::fmt;
3use std::sync::Arc;
4
5pub use std::error::Error as StdError;
6
7pub type Result<T, E = Error> = std::result::Result<T, E>;
9
10type ErrorMsg = Cow<'static, str>;
11
12#[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 {}