1use std::fmt;
2
3pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
4
5#[derive(Debug)]
6pub struct Error {
7 msg: String,
8 cause: Option<Box<dyn std::error::Error>>
9}
10
11impl Error {
12 pub fn new(msg: &str) -> Error {
13 Error {
14 msg: msg.into(),
15 cause: None
16 }
17 }
18}
19
20impl std::error::Error for Error {
21 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
22 self.cause.as_ref().map(Box::as_ref)
23 }
24}
25
26impl fmt::Display for Error {
27 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28 f.write_str(&self.msg)?;
29 if let Some(cause) = &self.cause {
30 write!(f, "\n\tcaused by: {}", cause)?;
31 }
32 Ok(())
33 }
34}
35
36pub trait ErrorExt {
37 fn wrap(self, msg: &str) -> Error;
38}
39
40impl<T: Into<Box<dyn std::error::Error>>> ErrorExt for T {
41 fn wrap(self, msg: &str) -> Error {
42 Error {
43 msg: msg.into(),
44 cause: Some(self.into())
45 }
46 }
47}
48
49pub trait ResultExt<T> {
50 fn wrap_err(self, msg: &str) -> std::result::Result<T, Error>;
51}
52
53impl<T, E: ErrorExt> ResultExt<T> for std::result::Result<T, E> {
54 fn wrap_err(self, msg: &str) -> std::result::Result<T, Error> {
55 self.map_err(|err| err.wrap(msg))
56 }
57}