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: &P0) => p.load_any(key, req),
31 B(p: &P1) => 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: &P0) => p.load_buffer(key, req),
46 B(p: &P1) => 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: &P0) => p.load_data(key, req),
59 B(p: &P1) => 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: &P0) => p.load(req),
72 B(p: &P1) => 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}
113