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 icu_provider::prelude::*;
8
9#[cfg(feature = "datagen")]
10use icu_provider::datagen;
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<P0: AnyProvider, P1: AnyProvider> AnyProvider for EitherProvider<P0, P1> {
26    #[inline]
27    fn load_any(&self, key: DataKey, req: DataRequest) -> Result<AnyResponse, DataError> {
28        use EitherProvider::*;
29        match self {
30            A(p) => p.load_any(key, req),
31            B(p) => p.load_any(key, req),
32        }
33    }
34}
35
36impl<P0: BufferProvider, P1: BufferProvider> BufferProvider for EitherProvider<P0, P1> {
37    #[inline]
38    fn load_buffer(
39        &self,
40        key: DataKey,
41        req: DataRequest,
42    ) -> Result<DataResponse<BufferMarker>, DataError> {
43        use EitherProvider::*;
44        match self {
45            A(p) => p.load_buffer(key, req),
46            B(p) => p.load_buffer(key, req),
47        }
48    }
49}
50
51impl<M: DataMarker, P0: DynamicDataProvider<M>, P1: DynamicDataProvider<M>> DynamicDataProvider<M>
52    for EitherProvider<P0, P1>
53{
54    #[inline]
55    fn load_data(&self, key: DataKey, req: DataRequest) -> Result<DataResponse<M>, DataError> {
56        use EitherProvider::*;
57        match self {
58            A(p) => p.load_data(key, req),
59            B(p) => p.load_data(key, req),
60        }
61    }
62}
63
64impl<M: KeyedDataMarker, P0: DataProvider<M>, P1: DataProvider<M>> DataProvider<M>
65    for EitherProvider<P0, P1>
66{
67    #[inline]
68    fn load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError> {
69        use EitherProvider::*;
70        match self {
71            A(p) => p.load(req),
72            B(p) => p.load(req),
73        }
74    }
75}
76
77#[cfg(feature = "datagen")]
78impl<
79        M: DataMarker,
80        P0: datagen::IterableDynamicDataProvider<M>,
81        P1: datagen::IterableDynamicDataProvider<M>,
82    > datagen::IterableDynamicDataProvider<M> for EitherProvider<P0, P1>
83{
84    #[inline]
85    fn supported_locales_for_key(
86        &self,
87        key: DataKey,
88    ) -> Result<alloc::vec::Vec<DataLocale>, DataError> {
89        use EitherProvider::*;
90        match self {
91            A(p) => p.supported_locales_for_key(key),
92            B(p) => p.supported_locales_for_key(key),
93        }
94    }
95}
96
97#[cfg(feature = "datagen")]
98impl<
99        M: KeyedDataMarker,
100        P0: datagen::IterableDataProvider<M>,
101        P1: datagen::IterableDataProvider<M>,
102    > datagen::IterableDataProvider<M> for EitherProvider<P0, P1>
103{
104    #[inline]
105    fn supported_locales(&self) -> Result<alloc::vec::Vec<DataLocale>, DataError> {
106        use EitherProvider::*;
107        match self {
108            A(p) => p.supported_locales(),
109            B(p) => p.supported_locales(),
110        }
111    }
112}