1use std::fmt::{self, Debug, Display, Formatter};
2
3pub struct Error {
4 msg: String,
5}
6
7impl Error {
8 pub fn new<M: Into<String>>(msg: M) -> Self {
9 Error { msg: msg.into() }
10 }
11}
12
13impl Display for Error {
14 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
15 write!(f, "{}", self.msg)
16 }
17}
18
19impl Debug for Error {
20 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
21 write!(f, "{}", self.msg)
22 }
23}
24
25impl std::error::Error for Error {
26 fn description(&self) -> &str {
27 self.msg.as_str()
28 }
29}
30
31pub trait ErrorExt {
32 fn wrap(self) -> Error;
33 fn context<C: Display + Send + Sync + 'static>(self, ctx: C) -> Error;
34}
35
36impl<E: std::error::Error + Send + Sync + 'static> ErrorExt for E {
37 fn wrap(self) -> Error {
38 Error { msg: self.to_string() }
39 }
40
41 fn context<C: Display + Send + Sync + 'static>(self, ctx: C) -> Error {
42 let msg = format!("{}: {}", ctx, self.to_string());
43 Error { msg }
44 }
45}
46
47pub trait ResultExt<T> {
48 fn wrap(self) -> Result<T, Error>;
49 fn context<C: Display + Send + Sync + 'static>(self, ctx: C) -> Result<T, Error>;
50}
51
52impl<T, E: std::error::Error + Send + Sync + 'static> ResultExt<T> for Result<T, E> {
53 fn wrap(self) -> Result<T, Error> {
54 self.map_err(|e| e.wrap())
55 }
56
57 fn context<C: Display + Send + Sync + 'static>(self, ctx: C) -> Result<T, Error> {
58 self.map_err(|e| e.context(ctx))
59 }
60}