• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
7 use alloc::collections::BTreeSet;
8 #[cfg(feature = "export")]
9 use icu_provider::export::ExportableProvider;
10 use 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)]
18 pub enum EitherProvider<P0, P1> {
19     /// A value of type `P0`.
20     A(P0),
21     /// A value of type `P1`.
22     B(P1),
23 }
24 
25 impl<M: DynamicDataMarker, P0: DynamicDataProvider<M>, P1: DynamicDataProvider<M>>
26     DynamicDataProvider<M> for EitherProvider<P0, P1>
27 {
28     #[inline]
load_data( &self, marker: DataMarkerInfo, req: DataRequest, ) -> Result<DataResponse<M>, DataError>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 
42 impl<M: DynamicDataMarker, P0: DynamicDryDataProvider<M>, P1: DynamicDryDataProvider<M>>
43     DynamicDryDataProvider<M> for EitherProvider<P0, P1>
44 {
45     #[inline]
dry_load_data( &self, marker: DataMarkerInfo, req: DataRequest, ) -> Result<DataResponseMetadata, DataError>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 
59 impl<M: DataMarker, P0: DataProvider<M>, P1: DataProvider<M>> DataProvider<M>
60     for EitherProvider<P0, P1>
61 {
62     #[inline]
load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError>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 
72 impl<M: DataMarker, P0: DryDataProvider<M>, P1: DryDataProvider<M>> DryDataProvider<M>
73     for EitherProvider<P0, P1>
74 {
75     #[inline]
dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError>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 
85 impl<
86         M: DynamicDataMarker,
87         P0: IterableDynamicDataProvider<M>,
88         P1: IterableDynamicDataProvider<M>,
89     > IterableDynamicDataProvider<M> for EitherProvider<P0, P1>
90 {
91     #[inline]
iter_ids_for_marker( &self, marker: DataMarkerInfo, ) -> Result<BTreeSet<DataIdentifierCow>, DataError>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 
104 impl<M: DataMarker, P0: IterableDataProvider<M>, P1: IterableDataProvider<M>>
105     IterableDataProvider<M> for EitherProvider<P0, P1>
106 {
107     #[inline]
iter_ids(&self) -> Result<BTreeSet<DataIdentifierCow>, DataError>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")]
118 impl<P0, P1> ExportableProvider for EitherProvider<P0, P1>
119 where
120     P0: ExportableProvider,
121     P1: ExportableProvider,
122 {
supported_markers(&self) -> alloc::collections::BTreeSet<DataMarkerInfo>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 }
131