Skip to main content

icu_provider_adapters/
either.rs

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//! Helpers for switching between multiple providers.
6
7use alloc::collections::BTreeSet;
8#[cfg(feature = "export")]
9use icu_provider::export::ExportableProvider;
10use icu_provider::prelude::*;
11
12/// A provider that is one of two types determined at runtime.
13///
14/// Data provider traits implemented by both `P0` and `P1` are implemented on
15/// `EitherProvider<P0, P1>`.
16#[allow(clippy::exhaustive_enums)] // this is stable
17#[derive(Debug)]
18pub enum EitherProvider<P0, P1> {
19    /// A value of type `P0`.
20    A(P0),
21    /// A value of type `P1`.
22    B(P1),
23}
24
25impl<M: DynamicDataMarker, P0: DynamicDataProvider<M>, P1: DynamicDataProvider<M>>
26    DynamicDataProvider<M> for EitherProvider<P0, P1>
27{
28    #[inline]
29    fn load_data(
30        &self,
31        marker: DataMarkerInfo,
32        req: DataRequest,
33    ) -> Result<DataResponse<M>, DataError> {
34        use EitherProvider::*;
35        match self {
36            A(p) => p.load_data(marker, req),
37            B(p) => p.load_data(marker, req),
38        }
39    }
40}
41
42impl<M: DynamicDataMarker, P0: DynamicDryDataProvider<M>, P1: DynamicDryDataProvider<M>>
43    DynamicDryDataProvider<M> for EitherProvider<P0, P1>
44{
45    #[inline]
46    fn dry_load_data(
47        &self,
48        marker: DataMarkerInfo,
49        req: DataRequest,
50    ) -> Result<DataResponseMetadata, DataError> {
51        use EitherProvider::*;
52        match self {
53            A(p) => p.dry_load_data(marker, req),
54            B(p) => p.dry_load_data(marker, req),
55        }
56    }
57}
58
59impl<M: DataMarker, P0: DataProvider<M>, P1: DataProvider<M>> DataProvider<M>
60    for EitherProvider<P0, P1>
61{
62    #[inline]
63    fn load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError> {
64        use EitherProvider::*;
65        match self {
66            A(p) => p.load(req),
67            B(p) => p.load(req),
68        }
69    }
70}
71
72impl<M: DataMarker, P0: DryDataProvider<M>, P1: DryDataProvider<M>> DryDataProvider<M>
73    for EitherProvider<P0, P1>
74{
75    #[inline]
76    fn dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError> {
77        use EitherProvider::*;
78        match self {
79            A(p) => p.dry_load(req),
80            B(p) => p.dry_load(req),
81        }
82    }
83}
84
85impl<
86        M: DynamicDataMarker,
87        P0: IterableDynamicDataProvider<M>,
88        P1: IterableDynamicDataProvider<M>,
89    > IterableDynamicDataProvider<M> for EitherProvider<P0, P1>
90{
91    #[inline]
92    fn iter_ids_for_marker(
93        &self,
94        marker: DataMarkerInfo,
95    ) -> Result<BTreeSet<DataIdentifierCow<'_>>, DataError> {
96        use EitherProvider::*;
97        match self {
98            A(p) => p.iter_ids_for_marker(marker),
99            B(p) => p.iter_ids_for_marker(marker),
100        }
101    }
102}
103
104impl<M: DataMarker, P0: IterableDataProvider<M>, P1: IterableDataProvider<M>>
105    IterableDataProvider<M> for EitherProvider<P0, P1>
106{
107    #[inline]
108    fn iter_ids(&self) -> Result<BTreeSet<DataIdentifierCow<'_>>, DataError> {
109        use EitherProvider::*;
110        match self {
111            A(p) => p.iter_ids(),
112            B(p) => p.iter_ids(),
113        }
114    }
115}
116
117#[cfg(feature = "export")]
118impl<P0, P1> ExportableProvider for EitherProvider<P0, P1>
119where
120    P0: ExportableProvider,
121    P1: ExportableProvider,
122{
123    fn supported_markers(&self) -> alloc::collections::BTreeSet<DataMarkerInfo> {
124        use EitherProvider::*;
125        match self {
126            A(p) => p.supported_markers(),
127            B(p) => p.supported_markers(),
128        }
129    }
130}