1use std::ops::Deref;
2use std::ops::DerefMut;
3
4use crate::Error;
5
6#[derive(Debug, Default)]
7pub struct FailManager {
8 fails: Vec<Error>,
9}
10
11impl FailManager {
12 pub fn push(&mut self, err: Error) -> &mut Self {
13 self.fails.push(err);
14 self
15 }
16
17 pub fn cause(mut self, new_err: Error) -> Error {
18 if self.is_empty() {
19 new_err
20 } else {
21 let mut err = self.fails.remove(0);
22
23 for fail in self.fails {
24 err = err.cause(fail);
25 }
26 new_err.cause_by(err)
27 }
28 }
29
30 pub fn cause_uid(self, new_err: Error) -> Error {
31 if self.is_empty() {
32 new_err
33 } else {
34 let mut fails = self
35 .fails
36 .into_iter()
37 .filter(|v| new_err.uid() == v.uid() || v.uid().is_none());
38
39 if let Some(fail) = fails.next() {
40 let mut err = fail;
41
42 for fail in fails {
43 err = err.cause(fail);
44 }
45 new_err.cause_by(err)
46 } else {
47 new_err
48 }
49 }
50 }
51
52 pub fn process_check<T, E>(self, ret: Result<T, E>) -> Result<T, Error>
53 where
54 E: Into<Error>,
55 {
56 match ret {
57 Ok(v) => Ok(v),
58 Err(e) => Err(self.cause_uid(e.into())),
59 }
60 }
61}
62
63impl Deref for FailManager {
64 type Target = Vec<Error>;
65
66 fn deref(&self) -> &Self::Target {
67 &self.fails
68 }
69}
70
71impl DerefMut for FailManager {
72 fn deref_mut(&mut self) -> &mut Self::Target {
73 &mut self.fails
74 }
75}