1use super::ForkByErrorPredicate;
6use alloc::{collections::BTreeSet, vec::Vec};
7#[cfg(feature = "export")]
8use icu_provider::export::ExportableProvider;
9use icu_provider::prelude::*;
10
11#[derive(Debug, PartialEq, Eq)]
19pub struct ForkByErrorProvider<P0, P1, F>(P0, P1, F);
20
21impl<P0, P1, F> ForkByErrorProvider<P0, P1, F> {
22 pub fn new_with_predicate(p0: P0, p1: P1, predicate: F) -> Self {
27 Self(p0, p1, predicate)
28 }
29
30 pub fn inner(&self) -> (&P0, &P1) {
32 (&self.0, &self.1)
33 }
34
35 pub fn inner_mut(&mut self) -> (&mut P0, &mut P1) {
37 (&mut self.0, &mut self.1)
38 }
39
40 pub fn into_inner(self) -> (P0, P1) {
42 (self.0, self.1)
43 }
44}
45
46impl<M, P0, P1, F> DataProvider<M> for ForkByErrorProvider<P0, P1, F>
47where
48 M: DataMarker,
49 P0: DataProvider<M>,
50 P1: DataProvider<M>,
51 F: ForkByErrorPredicate,
52{
53 fn load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError> {
54 let result = self.0.load(req);
55 match result {
56 Ok(ok) => return Ok(ok),
57 Err(err) if !self.2.test(M::INFO, Some(req), err) => return Err(err),
58 _ => (),
59 };
60 self.1.load(req)
61 }
62}
63
64impl<M, P0, P1, F> DryDataProvider<M> for ForkByErrorProvider<P0, P1, F>
65where
66 M: DataMarker,
67 P0: DryDataProvider<M>,
68 P1: DryDataProvider<M>,
69 F: ForkByErrorPredicate,
70{
71 fn dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError> {
72 let result = self.0.dry_load(req);
73 match result {
74 Ok(ok) => return Ok(ok),
75 Err(err) if !self.2.test(M::INFO, Some(req), err) => return Err(err),
76 _ => (),
77 };
78 self.1.dry_load(req)
79 }
80}
81
82impl<M, P0, P1, F> DynamicDataProvider<M> for ForkByErrorProvider<P0, P1, F>
83where
84 M: DynamicDataMarker,
85 P0: DynamicDataProvider<M>,
86 P1: DynamicDataProvider<M>,
87 F: ForkByErrorPredicate,
88{
89 fn load_data(
90 &self,
91 marker: DataMarkerInfo,
92 req: DataRequest,
93 ) -> Result<DataResponse<M>, DataError> {
94 let result = self.0.load_data(marker, req);
95 match result {
96 Ok(ok) => return Ok(ok),
97 Err(err) if !self.2.test(marker, Some(req), err) => return Err(err),
98 _ => (),
99 };
100 self.1.load_data(marker, req)
101 }
102}
103
104impl<M, P0, P1, F> DynamicDryDataProvider<M> for ForkByErrorProvider<P0, P1, F>
105where
106 M: DynamicDataMarker,
107 P0: DynamicDryDataProvider<M>,
108 P1: DynamicDryDataProvider<M>,
109 F: ForkByErrorPredicate,
110{
111 fn dry_load_data(
112 &self,
113 marker: DataMarkerInfo,
114 req: DataRequest,
115 ) -> Result<DataResponseMetadata, DataError> {
116 let result = self.0.dry_load_data(marker, req);
117 match result {
118 Ok(ok) => return Ok(ok),
119 Err(err) if !self.2.test(marker, Some(req), err) => return Err(err),
120 _ => (),
121 };
122 self.1.dry_load_data(marker, req)
123 }
124}
125
126impl<M, P0, P1, F> IterableDynamicDataProvider<M> for ForkByErrorProvider<P0, P1, F>
127where
128 M: DynamicDataMarker,
129 P0: IterableDynamicDataProvider<M>,
130 P1: IterableDynamicDataProvider<M>,
131 F: ForkByErrorPredicate,
132{
133 fn iter_ids_for_marker(
134 &self,
135 marker: DataMarkerInfo,
136 ) -> Result<BTreeSet<DataIdentifierCow<'_>>, DataError> {
137 let result = self.0.iter_ids_for_marker(marker);
138 match result {
139 Ok(ok) => return Ok(ok),
140 Err(err) if !self.2.test(marker, None, err) => return Err(err),
141 _ => (),
142 };
143 self.1.iter_ids_for_marker(marker)
144 }
145}
146
147#[cfg(feature = "export")]
148impl<P0, P1, F> ExportableProvider for ForkByErrorProvider<P0, P1, F>
149where
150 P0: ExportableProvider,
151 P1: ExportableProvider,
152 F: ForkByErrorPredicate + Sync,
153{
154 fn supported_markers(&self) -> alloc::collections::BTreeSet<DataMarkerInfo> {
155 let mut markers = self.0.supported_markers();
156 markers.extend(self.1.supported_markers());
157 markers
158 }
159}
160
161#[derive(Debug)]
169pub struct MultiForkByErrorProvider<P, F> {
170 providers: Vec<P>,
171 predicate: F,
172}
173
174impl<P, F> MultiForkByErrorProvider<P, F> {
175 pub fn new_with_predicate(providers: Vec<P>, predicate: F) -> Self {
180 Self {
181 providers,
182 predicate,
183 }
184 }
185
186 pub fn inner(&self) -> &[P] {
188 &self.providers
189 }
190
191 pub fn with_inner_mut(&mut self, f: impl FnOnce(&mut Vec<P>)) {
193 f(&mut self.providers)
194 }
195
196 pub fn into_inner(self) -> Vec<P> {
198 self.providers
199 }
200
201 pub fn push(&mut self, provider: P) {
203 self.providers.push(provider);
204 }
205}
206
207impl<M, P, F> DataProvider<M> for MultiForkByErrorProvider<P, F>
208where
209 M: DataMarker,
210 P: DataProvider<M>,
211 F: ForkByErrorPredicate,
212{
213 fn load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError> {
214 let mut last_error = F::UNIT_ERROR.with_marker(M::INFO);
215 for provider in self.providers.iter() {
216 let result = provider.load(req);
217 match result {
218 Ok(ok) => return Ok(ok),
219 Err(err) if !self.predicate.test(M::INFO, Some(req), err) => return Err(err),
220 Err(err) => last_error = err,
221 };
222 }
223 Err(last_error)
224 }
225}
226
227impl<M, P, F> DryDataProvider<M> for MultiForkByErrorProvider<P, F>
228where
229 M: DataMarker,
230 P: DryDataProvider<M>,
231 F: ForkByErrorPredicate,
232{
233 fn dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError> {
234 let mut last_error = F::UNIT_ERROR.with_marker(M::INFO);
235 for provider in self.providers.iter() {
236 let result = provider.dry_load(req);
237 match result {
238 Ok(ok) => return Ok(ok),
239 Err(err) if !self.predicate.test(M::INFO, Some(req), err) => return Err(err),
240 Err(err) => last_error = err,
241 };
242 }
243 Err(last_error)
244 }
245}
246
247impl<M, P, F> DynamicDataProvider<M> for MultiForkByErrorProvider<P, F>
248where
249 M: DynamicDataMarker,
250 P: DynamicDataProvider<M>,
251 F: ForkByErrorPredicate,
252{
253 fn load_data(
254 &self,
255 marker: DataMarkerInfo,
256 req: DataRequest,
257 ) -> Result<DataResponse<M>, DataError> {
258 let mut last_error = F::UNIT_ERROR.with_marker(marker);
259 for provider in self.providers.iter() {
260 let result = provider.load_data(marker, req);
261 match result {
262 Ok(ok) => return Ok(ok),
263 Err(err) if !self.predicate.test(marker, Some(req), err) => return Err(err),
264 Err(err) => last_error = err,
265 };
266 }
267 Err(last_error)
268 }
269}
270
271impl<M, P, F> DynamicDryDataProvider<M> for MultiForkByErrorProvider<P, F>
272where
273 M: DynamicDataMarker,
274 P: DynamicDryDataProvider<M>,
275 F: ForkByErrorPredicate,
276{
277 fn dry_load_data(
278 &self,
279 marker: DataMarkerInfo,
280 req: DataRequest,
281 ) -> Result<DataResponseMetadata, DataError> {
282 let mut last_error = F::UNIT_ERROR.with_marker(marker);
283 for provider in self.providers.iter() {
284 let result = provider.dry_load_data(marker, req);
285 match result {
286 Ok(ok) => return Ok(ok),
287 Err(err) if !self.predicate.test(marker, Some(req), err) => return Err(err),
288 Err(err) => last_error = err,
289 };
290 }
291 Err(last_error)
292 }
293}
294
295impl<M, P, F> IterableDynamicDataProvider<M> for MultiForkByErrorProvider<P, F>
296where
297 M: DynamicDataMarker,
298 P: IterableDynamicDataProvider<M>,
299 F: ForkByErrorPredicate,
300{
301 fn iter_ids_for_marker(
302 &self,
303 marker: DataMarkerInfo,
304 ) -> Result<BTreeSet<DataIdentifierCow<'_>>, DataError> {
305 let mut last_error = F::UNIT_ERROR.with_marker(marker);
306 for provider in self.providers.iter() {
307 let result = provider.iter_ids_for_marker(marker);
308 match result {
309 Ok(ok) => return Ok(ok),
310 Err(err) if !self.predicate.test(marker, None, err) => return Err(err),
311 Err(err) => last_error = err,
312 };
313 }
314 Err(last_error)
315 }
316}
317
318#[cfg(feature = "export")]
319impl<P, F> ExportableProvider for MultiForkByErrorProvider<P, F>
320where
321 P: ExportableProvider,
322 F: ForkByErrorPredicate + Sync,
323{
324 fn supported_markers(&self) -> alloc::collections::BTreeSet<DataMarkerInfo> {
325 self.providers
326 .iter()
327 .flat_map(|p| p.supported_markers())
328 .collect()
329 }
330}