1use core::any::Any;
2use core::error::Error;
3
4use crate::{Config, DataSource, GErr, IdSource, iterator::GErrNode};
5
6impl<C: Config, D> GErr<C, D>
7where
8 C::Id: IdSource + 'static,
9 D: DataSource + 'static,
10{
11 #[inline]
13 pub fn iter_by_code<'a, 'b>(
14 &'a self,
15 code: &'b str,
16 ) -> impl Iterator<Item = GErrNode<'a, C, D>> + 'a
17 where
18 'b: 'a,
19 {
20 self.iter().filter(move |item| match item {
21 GErrNode::Root(gerr) => gerr.code().is_some_and(|p| p == code),
22
23 GErrNode::LeafGErr(gerr) => gerr.code.as_ref().is_some_and(|p| p == code),
24
25 _ => false,
26 })
27 }
28
29 #[inline]
31 pub fn iter_by_tag<'a, 'b>(
32 &'a self,
33 tag: &'b str,
34 ) -> impl Iterator<Item = GErrNode<'a, C, D>> + 'a
35 where
36 'b: 'a,
37 {
38 self.iter().filter(move |item| match item {
39 GErrNode::Root(gerr) => gerr
40 .tags()
41 .is_some_and(|tags| tags.iter().any(|t| t == tag)),
42
43 GErrNode::LeafGErr(gerr) => gerr
44 .tags
45 .as_ref()
46 .is_some_and(|tags| tags.iter().any(|t| t == tag)),
47
48 _ => false,
49 })
50 }
51
52 #[inline]
54 pub fn iter_id<T>(&self) -> impl Iterator<Item = GErrNode<'_, C, D>>
55 where
56 T: Any,
57 {
58 self.iter().filter(|item| match item {
59 GErrNode::Root(gerr) => gerr.id().is_some_and(|id| (id as &dyn Any).is::<T>()),
60
61 GErrNode::LeafGErr(gerr) => gerr
62 .id
63 .as_ref()
64 .is_some_and(|id| (&**id as &dyn Any).is::<T>()),
65
66 _ => false,
67 })
68 }
69
70 #[inline]
72 pub fn iter_by_id<'a, 'b, T>(&'a self, value: &'b T) -> impl Iterator<Item = GErrNode<'a, C, D>>
73 where
74 T: Any + PartialEq,
75 'b: 'a,
76 {
77 self.iter().filter(move |item| match item {
78 GErrNode::Root(gerr) => gerr.id().is_some_and(|id| {
79 (id as &dyn Any)
80 .downcast_ref::<T>()
81 .is_some_and(|id| id == value)
82 }),
83 GErrNode::LeafGErr(gerr) => gerr.id.as_ref().is_some_and(|id| {
84 (&**id as &dyn Any)
85 .downcast_ref::<T>()
86 .is_some_and(|id| id == value)
87 }),
88
89 _ => false,
90 })
91 }
92
93 #[inline]
95 pub fn iter_data<T>(&self) -> impl Iterator<Item = GErrNode<'_, C, D>>
96 where
97 T: Any,
98 {
99 self.iter().filter(|item| match item {
100 GErrNode::Root(gerr) => gerr.data().is_some_and(|data| (data as &dyn Any).is::<T>()),
101
102 GErrNode::LeafGErr(gerr) => gerr
103 .data
104 .as_ref()
105 .is_some_and(|data| (&**data as &dyn Any).is::<T>()),
106
107 _ => false,
108 })
109 }
110
111 #[inline]
113 pub fn iter_by_data<'a, 'b, T>(
114 &'a self,
115 value: &'b T,
116 ) -> impl Iterator<Item = GErrNode<'a, C, D>>
117 where
118 T: Any + PartialEq,
119 'b: 'a,
120 {
121 self.iter().filter(move |item| match item {
122 GErrNode::Root(gerr) => gerr
123 .data()
124 .and_then(|data| (data as &dyn Any).downcast_ref::<T>())
125 .is_some_and(|data| data == value),
126
127 GErrNode::LeafGErr(gerr) => gerr
128 .data
129 .as_ref()
130 .and_then(|data| (&**data as &dyn Any).downcast_ref::<T>())
131 .is_some_and(|data| data == value),
132
133 _ => false,
134 })
135 }
136
137 #[inline]
139 pub fn iter_source<E>(&self) -> impl Iterator<Item = GErrNode<'_, C, D>>
140 where
141 E: Error + 'static,
142 {
143 self.iter().filter_map(|item| match item {
144 GErrNode::LeafErr(err) if err.is::<E>() => Some(item),
145
146 GErrNode::LeafGErr(gerr) if (gerr as &dyn Error).is::<E>() => Some(item),
147
148 _ => None,
149 })
150 }
151}