summaryrefslogtreecommitdiffstats
path: root/vendor/icu_provider_adapters/src/fork/by_error.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:32 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:32 +0000
commit4547b622d8d29df964fa2914213088b148c498fc (patch)
tree9fc6b25f3c3add6b745be9a2400a6e96140046e9 /vendor/icu_provider_adapters/src/fork/by_error.rs
parentReleasing progress-linux version 1.66.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-4547b622d8d29df964fa2914213088b148c498fc.tar.xz
rustc-4547b622d8d29df964fa2914213088b148c498fc.zip
Merging upstream version 1.67.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/icu_provider_adapters/src/fork/by_error.rs')
-rw-r--r--vendor/icu_provider_adapters/src/fork/by_error.rs287
1 files changed, 287 insertions, 0 deletions
diff --git a/vendor/icu_provider_adapters/src/fork/by_error.rs b/vendor/icu_provider_adapters/src/fork/by_error.rs
new file mode 100644
index 000000000..5069229fa
--- /dev/null
+++ b/vendor/icu_provider_adapters/src/fork/by_error.rs
@@ -0,0 +1,287 @@
+// This file is part of ICU4X. For terms of use, please see the file
+// called LICENSE at the top level of the ICU4X source tree
+// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+use super::ForkByErrorPredicate;
+use alloc::vec::Vec;
+#[cfg(feature = "datagen")]
+use icu_provider::datagen;
+use icu_provider::prelude::*;
+
+/// A provider that returns data from one of two child providers based on a predicate function.
+///
+/// This is an abstract forking provider that must be provided with a type implementing the
+/// [`ForkByErrorPredicate`] trait.
+///
+/// [`ForkByErrorProvider`] does not support forking between [`DataProvider`]s. However, it
+/// supports forking between [`AnyProvider`], [`BufferProvider`], and [`DynamicDataProvider`].
+#[derive(Debug, PartialEq, Eq)]
+pub struct ForkByErrorProvider<P0, P1, F>(P0, P1, F);
+
+impl<P0, P1, F> ForkByErrorProvider<P0, P1, F> {
+ /// Create a new provider that forks between the two children.
+ ///
+ /// The `predicate` argument should be an instance of a struct implementing
+ /// [`ForkByErrorPredicate`].
+ pub fn new_with_predicate(p0: P0, p1: P1, predicate: F) -> Self {
+ Self(p0, p1, predicate)
+ }
+
+ /// Returns references to the inner providers.
+ pub fn inner(&self) -> (&P0, &P1) {
+ (&self.0, &self.1)
+ }
+
+ /// Returns ownership of the inner providers to the caller.
+ pub fn into_inner(self) -> (P0, P1) {
+ (self.0, self.1)
+ }
+}
+
+impl<P0, P1, F> BufferProvider for ForkByErrorProvider<P0, P1, F>
+where
+ P0: BufferProvider,
+ P1: BufferProvider,
+ F: ForkByErrorPredicate,
+{
+ fn load_buffer(
+ &self,
+ key: DataKey,
+ req: DataRequest,
+ ) -> Result<DataResponse<BufferMarker>, DataError> {
+ let result = self.0.load_buffer(key, req);
+ match result {
+ Ok(ok) => return Ok(ok),
+ Err(err) if !self.2.test(key, Some(req), err) => return Err(err),
+ _ => (),
+ };
+ self.1.load_buffer(key, req)
+ }
+}
+
+impl<P0, P1, F> AnyProvider for ForkByErrorProvider<P0, P1, F>
+where
+ P0: AnyProvider,
+ P1: AnyProvider,
+ F: ForkByErrorPredicate,
+{
+ fn load_any(&self, key: DataKey, req: DataRequest) -> Result<AnyResponse, DataError> {
+ let result = self.0.load_any(key, req);
+ match result {
+ Ok(ok) => return Ok(ok),
+ Err(err) if !self.2.test(key, Some(req), err) => return Err(err),
+ _ => (),
+ };
+ self.1.load_any(key, req)
+ }
+}
+
+impl<M, P0, P1, F> DynamicDataProvider<M> for ForkByErrorProvider<P0, P1, F>
+where
+ M: DataMarker,
+ P0: DynamicDataProvider<M>,
+ P1: DynamicDataProvider<M>,
+ F: ForkByErrorPredicate,
+{
+ fn load_data(&self, key: DataKey, req: DataRequest) -> Result<DataResponse<M>, DataError> {
+ let result = self.0.load_data(key, req);
+ match result {
+ Ok(ok) => return Ok(ok),
+ Err(err) if !self.2.test(key, Some(req), err) => return Err(err),
+ _ => (),
+ };
+ self.1.load_data(key, req)
+ }
+}
+
+#[cfg(feature = "datagen")]
+impl<M, P0, P1, F> datagen::IterableDynamicDataProvider<M> for ForkByErrorProvider<P0, P1, F>
+where
+ M: DataMarker,
+ P0: datagen::IterableDynamicDataProvider<M>,
+ P1: datagen::IterableDynamicDataProvider<M>,
+ F: ForkByErrorPredicate,
+{
+ fn supported_locales_for_key(&self, key: DataKey) -> Result<Vec<DataLocale>, DataError> {
+ let result = self.0.supported_locales_for_key(key);
+ match result {
+ Ok(ok) => return Ok(ok),
+ Err(err) if !self.2.test(key, None, err) => return Err(err),
+ _ => (),
+ };
+ self.1.supported_locales_for_key(key)
+ }
+}
+
+/// A provider that returns data from the first child provider passing a predicate function.
+///
+/// This is an abstract forking provider that must be provided with a type implementing the
+/// [`ForkByErrorPredicate`] trait.
+///
+/// [`MultiForkByErrorProvider`] does not support forking between [`DataProvider`]s. However, it
+/// supports forking between [`AnyProvider`], [`BufferProvider`], and [`DynamicDataProvider`].
+pub struct MultiForkByErrorProvider<P, F> {
+ providers: Vec<P>,
+ predicate: F,
+}
+
+impl<P, F> MultiForkByErrorProvider<P, F> {
+ /// Create a new provider that forks between the vector of children.
+ ///
+ /// The `predicate` argument should be an instance of a struct implementing
+ /// [`ForkByErrorPredicate`].
+ pub fn new_with_predicate(providers: Vec<P>, predicate: F) -> Self {
+ Self {
+ providers,
+ predicate,
+ }
+ }
+
+ /// Returns a slice of the inner providers.
+ pub fn inner(&self) -> &[P] {
+ &self.providers
+ }
+
+ /// Returns ownership of the inner providers to the caller.
+ pub fn into_inner(self) -> Vec<P> {
+ self.providers
+ }
+}
+
+impl<P, F> BufferProvider for MultiForkByErrorProvider<P, F>
+where
+ P: BufferProvider,
+ F: ForkByErrorPredicate,
+{
+ fn load_buffer(
+ &self,
+ key: DataKey,
+ req: DataRequest,
+ ) -> Result<DataResponse<BufferMarker>, DataError> {
+ for provider in self.providers.iter() {
+ let result = provider.load_buffer(key, req);
+ match result {
+ Ok(ok) => return Ok(ok),
+ Err(err) if !self.predicate.test(key, Some(req), err) => return Err(err),
+ _ => (),
+ };
+ }
+ Err(DataErrorKind::MissingDataKey.with_key(key))
+ }
+}
+
+impl<P, F> AnyProvider for MultiForkByErrorProvider<P, F>
+where
+ P: AnyProvider,
+ F: ForkByErrorPredicate,
+{
+ fn load_any(&self, key: DataKey, req: DataRequest) -> Result<AnyResponse, DataError> {
+ for provider in self.providers.iter() {
+ let result = provider.load_any(key, req);
+ match result {
+ Ok(ok) => return Ok(ok),
+ Err(err) if !self.predicate.test(key, Some(req), err) => return Err(err),
+ _ => (),
+ };
+ }
+ Err(DataErrorKind::MissingDataKey.with_key(key))
+ }
+}
+
+impl<M, P, F> DynamicDataProvider<M> for MultiForkByErrorProvider<P, F>
+where
+ M: DataMarker,
+ P: DynamicDataProvider<M>,
+ F: ForkByErrorPredicate,
+{
+ fn load_data(&self, key: DataKey, req: DataRequest) -> Result<DataResponse<M>, DataError> {
+ for provider in self.providers.iter() {
+ let result = provider.load_data(key, req);
+ match result {
+ Ok(ok) => return Ok(ok),
+ Err(err) if !self.predicate.test(key, Some(req), err) => return Err(err),
+ _ => (),
+ };
+ }
+ Err(DataErrorKind::MissingDataKey.with_key(key))
+ }
+}
+
+#[cfg(feature = "datagen")]
+impl<M, P, F> datagen::IterableDynamicDataProvider<M> for MultiForkByErrorProvider<P, F>
+where
+ M: DataMarker,
+ P: datagen::IterableDynamicDataProvider<M>,
+ F: ForkByErrorPredicate,
+{
+ fn supported_locales_for_key(&self, key: DataKey) -> Result<Vec<DataLocale>, DataError> {
+ for provider in self.providers.iter() {
+ let result = provider.supported_locales_for_key(key);
+ match result {
+ Ok(ok) => return Ok(ok),
+ Err(err) if !self.predicate.test(key, None, err) => return Err(err),
+ _ => (),
+ };
+ }
+ Err(DataErrorKind::MissingDataKey.with_key(key))
+ }
+}
+
+#[cfg(feature = "datagen")]
+impl<P, MFrom, MTo, F> datagen::DataConverter<MFrom, MTo> for MultiForkByErrorProvider<P, F>
+where
+ P: datagen::DataConverter<MFrom, MTo>,
+ F: ForkByErrorPredicate,
+ MFrom: DataMarker,
+ MTo: DataMarker,
+{
+ fn convert(
+ &self,
+ key: DataKey,
+ mut from: DataPayload<MFrom>,
+ ) -> Result<DataPayload<MTo>, (DataPayload<MFrom>, DataError)> {
+ for provider in self.providers.iter() {
+ let result = provider.convert(key, from);
+ match result {
+ Ok(ok) => return Ok(ok),
+ Err(e) => {
+ let (returned, err) = e;
+ if !self.predicate.test(key, None, err) {
+ return Err((returned, err));
+ }
+ from = returned;
+ }
+ };
+ }
+ Err((from, DataErrorKind::MissingDataKey.with_key(key)))
+ }
+}
+
+#[cfg(feature = "datagen")]
+impl<P0, P1, F, MFrom, MTo> datagen::DataConverter<MFrom, MTo> for ForkByErrorProvider<P0, P1, F>
+where
+ P0: datagen::DataConverter<MFrom, MTo>,
+ P1: datagen::DataConverter<MFrom, MTo>,
+ F: ForkByErrorPredicate,
+ MFrom: DataMarker,
+ MTo: DataMarker,
+{
+ fn convert(
+ &self,
+ key: DataKey,
+ mut from: DataPayload<MFrom>,
+ ) -> Result<DataPayload<MTo>, (DataPayload<MFrom>, DataError)> {
+ let result = self.0.convert(key, from);
+ match result {
+ Ok(ok) => return Ok(ok),
+ Err(e) => {
+ let (returned, err) = e;
+ if !self.2.test(key, None, err) {
+ return Err((returned, err));
+ }
+ from = returned;
+ }
+ };
+ self.1.convert(key, from)
+ }
+}