1use std::error::Error;
5use std::fmt;
6
7type Cause = Box<dyn Error + Send + Sync>;
8
9#[derive(Debug)]
12pub struct Failure {
13 doing: String,
14 cause: Cause,
15}
16
17impl Failure {
18 pub fn new(doing: impl Into<String>, cause: impl Into<Cause>) -> Self {
19 Self {
20 doing: doing.into(),
21 cause: cause.into(),
22 }
23 }
24}
25
26impl fmt::Display for Failure {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 write!(f, "{}: {}", self.doing, self.cause)
29 }
30}
31
32impl Error for Failure {
33 fn source(&self) -> Option<&(dyn Error + 'static)> {
34 Some(&*self.cause)
35 }
36}
37
38pub trait Doing<T> {
40 fn doing(self, what: impl FnOnce() -> String) -> Result<T, Failure>;
41}
42
43impl<T, E: Into<Cause>> Doing<T> for Result<T, E> {
44 fn doing(self, what: impl FnOnce() -> String) -> Result<T, Failure> {
45 self.map_err(|cause| Failure::new(what(), cause))
46 }
47}