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