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