1use alloc::vec;
9use alloc::vec::Vec;
10use core::error::Error;
11use core::fmt::{Debug, Display};
12
13use crate::gerr::Source;
14use crate::{Config, DataSource, GErr, GErrBox, GErrSource, IdSource};
15
16impl<'a, C: Config, D> IntoIterator for &'a GErr<C, D>
17where
18 C::Id: IdSource + 'static,
19 D: DataSource + 'static,
20{
21 type Item = GErrNode<'a, C, D>;
22 type IntoIter = GErrTree<'a, C, D>;
23
24 #[inline]
25 fn into_iter(self) -> Self::IntoIter {
26 self.iter()
27 }
28}
29
30impl<'a, C: Config, D> IntoIterator for &'a GErrBox<C, D>
31where
32 C::Id: IdSource + 'static,
33 D: DataSource + 'static,
34{
35 type Item = GErrNode<'a, C, D>;
36 type IntoIter = GErrTree<'a, C, D>;
37
38 #[inline]
39 fn into_iter(self) -> Self::IntoIter {
40 (*self).iter()
41 }
42}
43
44impl<C: Config, D> GErr<C, D>
45where
46 C::Id: IdSource + 'static,
47 D: DataSource + 'static,
48{
49 #[inline]
51 pub fn iter(&self) -> GErrTree<'_, C, D> {
52 GErrTree {
53 nodes: vec![GErrNode::Root(self)],
54 }
55 }
56}
57
58pub enum GErrNode<'a, C: Config, D> {
62 Root(&'a GErr<C, D>),
64 LeafErr(&'a (dyn Error + Send + Sync + 'static)),
66 LeafGErr(&'a GErrSource),
68}
69
70impl<'a, C: Config, D> Display for GErrNode<'a, C, D>
71where
72 C::Id: IdSource + 'static,
73 D: DataSource + 'static,
74{
75 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
76 match self {
77 Self::Root(root) => write!(f, "{}", root),
78 Self::LeafErr(err) => write!(f, "{}", err),
79 Self::LeafGErr(gerr) => write!(f, "{}", gerr),
80 }
81 }
82}
83
84impl<'a, C: Config, D> Debug for GErrNode<'a, C, D>
85where
86 C::Id: IdSource + 'static,
87 D: DataSource + 'static,
88{
89 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
90 match self {
91 Self::Root(root) => write!(f, "root: {:#?}", root),
92 Self::LeafErr(err) => write!(f, "err: {:#?}", err),
93 Self::LeafGErr(gerr) => write!(f, "gerr: {:#?}", gerr),
94 }
95 }
96}
97
98pub struct GErrTree<'a, C: Config, D> {
102 nodes: Vec<GErrNode<'a, C, D>>,
103}
104
105impl<'a, C: Config, D> Iterator for GErrTree<'a, C, D>
106where
107 C::Id: IdSource + 'static,
108 D: DataSource + 'static,
109{
110 type Item = GErrNode<'a, C, D>;
111
112 fn next(&mut self) -> Option<Self::Item> {
113 let current = self.nodes.pop()?;
114
115 match ¤t {
116 GErrNode::Root(gerr) => {
117 if let Some(sources) = gerr.sources() {
118 for source in sources.iter().rev() {
119 match &source {
120 Source::Err(err) => {
121 self.nodes.push(GErrNode::LeafErr(err.as_ref()));
122 }
123
124 Source::GErr(gerr) => {
125 self.nodes.push(GErrNode::LeafGErr(gerr.as_ref()));
126 }
127 }
128 }
129 }
130 }
131
132 GErrNode::LeafErr(_) => {}
134
135 GErrNode::LeafGErr(gerr) => {
136 if let Some(sources) = gerr.sources.as_deref() {
137 for source in sources.iter().rev() {
138 match &source {
139 Source::Err(err) => {
140 self.nodes.push(GErrNode::LeafErr(err.as_ref()));
141 }
142
143 Source::GErr(gerr) => {
144 self.nodes.push(GErrNode::LeafGErr(gerr.as_ref()));
145 }
146 }
147 }
148 }
149 }
150 }
151
152 Some(current)
153 }
154}