aopt/parser/
failure.rs

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}