rust_cli_test/
error.rs

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}