indy_data_types/
error.rs

1use std::error::Error as StdError;
2use thiserror::Error;
3
4type DynError = Box<dyn StdError + Send + Sync + 'static>;
5
6macro_rules! define_error {
7    ($name:tt, $short:expr, $doc:tt) => {
8        #[derive(Debug, Error)]
9        #[doc=$doc]
10        pub struct $name {
11            pub context: Option<String>,
12            pub source: Option<DynError>,
13        }
14
15        impl $name {
16            #[allow(unused)]
17            pub fn from_msg<T: Into<String>>(msg: T) -> Self {
18                Self::from(msg.into())
19            }
20
21            #[allow(unused)]
22            pub fn from_err<E>(err: E) -> Self
23            where
24                E: StdError + Send + Sync + 'static,
25            {
26                Self {
27                    context: None,
28                    source: Some(Box::new(err) as DynError),
29                }
30            }
31
32            pub fn from_msg_err<M, E>(msg: M, err: E) -> Self
33            where
34                M: Into<String>,
35                E: StdError + Send + Sync + 'static,
36            {
37                Self {
38                    context: Some(msg.into()),
39                    source: Some(Box::new(err) as DynError),
40                }
41            }
42        }
43
44        impl From<&str> for $name {
45            fn from(context: &str) -> Self {
46                Self {
47                    context: Some(context.to_owned()),
48                    source: None,
49                }
50            }
51        }
52
53        impl From<String> for $name {
54            fn from(context: String) -> Self {
55                Self {
56                    context: Some(context),
57                    source: None,
58                }
59            }
60        }
61
62        impl From<Option<String>> for $name {
63            fn from(context: Option<String>) -> Self {
64                Self {
65                    context,
66                    source: None,
67                }
68            }
69        }
70
71        impl<M, E> From<(M, E)> for $name
72        where
73            M: Into<String>,
74            E: StdError + Send + Sync + 'static,
75        {
76            fn from((context, err): (M, E)) -> Self {
77                Self::from_msg_err(context, err)
78            }
79        }
80
81        impl From<$name> for String {
82            fn from(val: $name) -> String {
83                val.to_string()
84            }
85        }
86
87        impl std::fmt::Display for $name {
88            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89                write!(f, $short)?;
90                match self.context {
91                    Some(ref context) => write!(f, ": {}", context),
92                    None => Ok(()),
93                }
94            }
95        }
96    };
97}
98
99define_error!(
100    ConversionError,
101    "Conversion error",
102    "Error type for general data conversion errors"
103);
104
105define_error!(
106    EncryptionError,
107    "Encryption error",
108    "Error type for failure of encryption and decryption operations"
109);
110
111define_error!(
112    UnexpectedError,
113    "Unexpected error",
114    "Error type for eventualities that shouldn't normally occur"
115);
116
117define_error!(
118    ValidationError,
119    "Validation error",
120    "Error type for failures of `Validatable::validate`"
121);
122
123#[cfg(feature = "serde_json")]
124impl From<serde_json::error::Error> for ConversionError {
125    fn from(err: serde_json::error::Error) -> Self {
126        Self::from_msg(err.to_string())
127    }
128}
129
130impl From<std::str::Utf8Error> for ConversionError {
131    fn from(_err: std::str::Utf8Error) -> Self {
132        Self::from("UTF-8 decoding error")
133    }
134}
135
136impl From<std::string::FromUtf8Error> for ConversionError {
137    fn from(_err: std::string::FromUtf8Error) -> Self {
138        Self::from("UTF-8 decoding error")
139    }
140}
141
142impl From<ValidationError> for ConversionError {
143    fn from(err: ValidationError) -> Self {
144        Self {
145            context: err.context,
146            source: err.source,
147        }
148    }
149}
150
151impl From<ConversionError> for ValidationError {
152    fn from(err: ConversionError) -> Self {
153        Self {
154            context: err.context,
155            source: err.source,
156        }
157    }
158}
159
160impl From<UnexpectedError> for ConversionError {
161    fn from(err: UnexpectedError) -> Self {
162        Self {
163            context: err.context,
164            source: err.source,
165        }
166    }
167}
168
169impl From<UnexpectedError> for EncryptionError {
170    fn from(err: UnexpectedError) -> Self {
171        Self {
172            context: err.context,
173            source: err.source,
174        }
175    }
176}