• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // This file is part of ICU4X. For terms of use, please see the file
2 // called LICENSE at the top level of the ICU4X source tree
3 // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4 
5 use super::ForkByErrorPredicate;
6 use alloc::{collections::BTreeSet, vec::Vec};
7 #[cfg(feature = "export")]
8 use icu_provider::export::ExportableProvider;
9 use icu_provider::prelude::*;
10 
11 /// A provider that returns data from one of two child providers based on a predicate function.
12 ///
13 /// This is an abstract forking provider that must be provided with a type implementing the
14 /// [`ForkByErrorPredicate`] trait.
15 ///
16 /// [`ForkByErrorProvider`] does not support forking between [`DataProvider`]s. However, it
17 /// supports forking between [`BufferProvider`], and [`DynamicDataProvider`].
18 #[derive(Debug, PartialEq, Eq)]
19 pub struct ForkByErrorProvider<P0, P1, F>(P0, P1, F);
20 
21 impl<P0, P1, F> ForkByErrorProvider<P0, P1, F> {
22     /// Create a new provider that forks between the two children.
23     ///
24     /// The `predicate` argument should be an instance of a struct implementing
25     /// [`ForkByErrorPredicate`].
new_with_predicate(p0: P0, p1: P1, predicate: F) -> Self26     pub fn new_with_predicate(p0: P0, p1: P1, predicate: F) -> Self {
27         Self(p0, p1, predicate)
28     }
29 
30     /// Returns references to the inner providers.
inner(&self) -> (&P0, &P1)31     pub fn inner(&self) -> (&P0, &P1) {
32         (&self.0, &self.1)
33     }
34 
35     /// Returns mutable references to the inner providers.
inner_mut(&mut self) -> (&mut P0, &mut P1)36     pub fn inner_mut(&mut self) -> (&mut P0, &mut P1) {
37         (&mut self.0, &mut self.1)
38     }
39 
40     /// Returns ownership of the inner providers to the caller.
into_inner(self) -> (P0, P1)41     pub fn into_inner(self) -> (P0, P1) {
42         (self.0, self.1)
43     }
44 }
45 
46 impl<M, P0, P1, F> DataProvider<M> for ForkByErrorProvider<P0, P1, F>
47 where
48     M: DataMarker,
49     P0: DataProvider<M>,
50     P1: DataProvider<M>,
51     F: ForkByErrorPredicate,
52 {
load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError>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 
64 impl<M, P0, P1, F> DryDataProvider<M> for ForkByErrorProvider<P0, P1, F>
65 where
66     M: DataMarker,
67     P0: DryDataProvider<M>,
68     P1: DryDataProvider<M>,
69     F: ForkByErrorPredicate,
70 {
dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError>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 
82 impl<M, P0, P1, F> DynamicDataProvider<M> for ForkByErrorProvider<P0, P1, F>
83 where
84     M: DynamicDataMarker,
85     P0: DynamicDataProvider<M>,
86     P1: DynamicDataProvider<M>,
87     F: ForkByErrorPredicate,
88 {
load_data( &self, marker: DataMarkerInfo, req: DataRequest, ) -> Result<DataResponse<M>, DataError>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 
104 impl<M, P0, P1, F> DynamicDryDataProvider<M> for ForkByErrorProvider<P0, P1, F>
105 where
106     M: DynamicDataMarker,
107     P0: DynamicDryDataProvider<M>,
108     P1: DynamicDryDataProvider<M>,
109     F: ForkByErrorPredicate,
110 {
dry_load_data( &self, marker: DataMarkerInfo, req: DataRequest, ) -> Result<DataResponseMetadata, DataError>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 
126 impl<M, P0, P1, F> IterableDynamicDataProvider<M> for ForkByErrorProvider<P0, P1, F>
127 where
128     M: DynamicDataMarker,
129     P0: IterableDynamicDataProvider<M>,
130     P1: IterableDynamicDataProvider<M>,
131     F: ForkByErrorPredicate,
132 {
iter_ids_for_marker( &self, marker: DataMarkerInfo, ) -> Result<BTreeSet<DataIdentifierCow>, DataError>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")]
148 impl<P0, P1, F> ExportableProvider for ForkByErrorProvider<P0, P1, F>
149 where
150     P0: ExportableProvider,
151     P1: ExportableProvider,
152     F: ForkByErrorPredicate + Sync,
153 {
supported_markers(&self) -> alloc::collections::BTreeSet<DataMarkerInfo>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 /// A provider that returns data from the first child provider passing a predicate function.
162 ///
163 /// This is an abstract forking provider that must be provided with a type implementing the
164 /// [`ForkByErrorPredicate`] trait.
165 ///
166 /// [`MultiForkByErrorProvider`] does not support forking between [`DataProvider`]s. However, it
167 /// supports forking between [`BufferProvider`], and [`DynamicDataProvider`].
168 #[derive(Debug)]
169 pub struct MultiForkByErrorProvider<P, F> {
170     providers: Vec<P>,
171     predicate: F,
172 }
173 
174 impl<P, F> MultiForkByErrorProvider<P, F> {
175     /// Create a new provider that forks between the vector of children.
176     ///
177     /// The `predicate` argument should be an instance of a struct implementing
178     /// [`ForkByErrorPredicate`].
new_with_predicate(providers: Vec<P>, predicate: F) -> Self179     pub fn new_with_predicate(providers: Vec<P>, predicate: F) -> Self {
180         Self {
181             providers,
182             predicate,
183         }
184     }
185 
186     /// Returns a slice of the inner providers.
inner(&self) -> &[P]187     pub fn inner(&self) -> &[P] {
188         &self.providers
189     }
190 
191     /// Exposes a mutable vector of providers to a closure so it can be mutated.
with_inner_mut(&mut self, f: impl FnOnce(&mut Vec<P>))192     pub fn with_inner_mut(&mut self, f: impl FnOnce(&mut Vec<P>)) {
193         f(&mut self.providers)
194     }
195 
196     /// Returns ownership of the inner providers to the caller.
into_inner(self) -> Vec<P>197     pub fn into_inner(self) -> Vec<P> {
198         self.providers
199     }
200 
201     /// Adds an additional child provider.
push(&mut self, provider: P)202     pub fn push(&mut self, provider: P) {
203         self.providers.push(provider);
204     }
205 }
206 
207 impl<M, P, F> DataProvider<M> for MultiForkByErrorProvider<P, F>
208 where
209     M: DataMarker,
210     P: DataProvider<M>,
211     F: ForkByErrorPredicate,
212 {
load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError>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 
227 impl<M, P, F> DryDataProvider<M> for MultiForkByErrorProvider<P, F>
228 where
229     M: DataMarker,
230     P: DryDataProvider<M>,
231     F: ForkByErrorPredicate,
232 {
dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError>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 
247 impl<M, P, F> DynamicDataProvider<M> for MultiForkByErrorProvider<P, F>
248 where
249     M: DynamicDataMarker,
250     P: DynamicDataProvider<M>,
251     F: ForkByErrorPredicate,
252 {
load_data( &self, marker: DataMarkerInfo, req: DataRequest, ) -> Result<DataResponse<M>, DataError>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 
271 impl<M, P, F> DynamicDryDataProvider<M> for MultiForkByErrorProvider<P, F>
272 where
273     M: DynamicDataMarker,
274     P: DynamicDryDataProvider<M>,
275     F: ForkByErrorPredicate,
276 {
dry_load_data( &self, marker: DataMarkerInfo, req: DataRequest, ) -> Result<DataResponseMetadata, DataError>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 
295 impl<M, P, F> IterableDynamicDataProvider<M> for MultiForkByErrorProvider<P, F>
296 where
297     M: DynamicDataMarker,
298     P: IterableDynamicDataProvider<M>,
299     F: ForkByErrorPredicate,
300 {
iter_ids_for_marker( &self, marker: DataMarkerInfo, ) -> Result<BTreeSet<DataIdentifierCow>, DataError>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")]
319 impl<P, F> ExportableProvider for MultiForkByErrorProvider<P, F>
320 where
321     P: ExportableProvider,
322     F: ForkByErrorPredicate + Sync,
323 {
supported_markers(&self) -> alloc::collections::BTreeSet<DataMarkerInfo>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 }
331