icu_provider_adapters/filter/
mod.rs1mod impls;
38
39#[cfg(feature = "datagen")]
40use icu_provider::datagen;
41use icu_provider::prelude::*;
42
43#[allow(clippy::exhaustive_structs)] #[derive(Debug)]
53pub struct RequestFilterDataProvider<D, F>
54where
55 F: Fn(DataRequest) -> bool,
56{
57 pub inner: D,
59
60 pub predicate: F,
63
64 pub filter_name: &'static str,
66}
67
68impl<D, F, M> DynamicDataProvider<M> for RequestFilterDataProvider<D, F>
69where
70 F: Fn(DataRequest) -> bool,
71 M: DataMarker,
72 D: DynamicDataProvider<M>,
73{
74 fn load_data(&self, key: DataKey, req: DataRequest) -> Result<DataResponse<M>, DataError> {
75 if (self.predicate)(req) {
76 self.inner.load_data(key, req)
77 } else {
78 Err(DataErrorKind::FilteredResource
79 .with_str_context(self.filter_name)
80 .with_req(key, req))
81 }
82 }
83}
84
85impl<D, F, M> DataProvider<M> for RequestFilterDataProvider<D, F>
86where
87 F: Fn(DataRequest) -> bool,
88 M: KeyedDataMarker,
89 D: DataProvider<M>,
90{
91 fn load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError> {
92 if (self.predicate)(req) {
93 self.inner.load(req)
94 } else {
95 Err(DataErrorKind::FilteredResource
96 .with_str_context(self.filter_name)
97 .with_req(M::KEY, req))
98 }
99 }
100}
101
102impl<D, F> BufferProvider for RequestFilterDataProvider<D, F>
103where
104 F: Fn(DataRequest) -> bool,
105 D: BufferProvider,
106{
107 fn load_buffer(
108 &self,
109 key: DataKey,
110 req: DataRequest,
111 ) -> Result<DataResponse<BufferMarker>, DataError> {
112 if (self.predicate)(req) {
113 self.inner.load_buffer(key, req)
114 } else {
115 Err(DataErrorKind::FilteredResource
116 .with_str_context(self.filter_name)
117 .with_req(key, req))
118 }
119 }
120}
121
122impl<D, F> AnyProvider for RequestFilterDataProvider<D, F>
123where
124 F: Fn(DataRequest) -> bool,
125 D: AnyProvider,
126{
127 fn load_any(&self, key: DataKey, req: DataRequest) -> Result<AnyResponse, DataError> {
128 if (self.predicate)(req) {
129 self.inner.load_any(key, req)
130 } else {
131 Err(DataErrorKind::FilteredResource
132 .with_str_context(self.filter_name)
133 .with_req(key, req))
134 }
135 }
136}
137
138#[cfg(feature = "datagen")]
139impl<M, D, F> datagen::IterableDynamicDataProvider<M> for RequestFilterDataProvider<D, F>
140where
141 M: DataMarker,
142 F: Fn(DataRequest) -> bool,
143 D: datagen::IterableDynamicDataProvider<M>,
144{
145 fn supported_locales_for_key(
146 &self,
147 key: DataKey,
148 ) -> Result<alloc::vec::Vec<DataLocale>, DataError> {
149 self.inner.supported_locales_for_key(key).map(|vec| {
150 vec.into_iter()
152 .filter_map(|locale| {
153 if (self.predicate)(DataRequest {
154 locale: &locale,
155 metadata: Default::default(),
156 }) {
157 Some(locale)
158 } else {
159 None
160 }
161 })
162 .collect()
163 })
164 }
165}
166
167#[cfg(feature = "datagen")]
168impl<M, D, F> datagen::IterableDataProvider<M> for RequestFilterDataProvider<D, F>
169where
170 M: KeyedDataMarker,
171 F: Fn(DataRequest) -> bool,
172 D: datagen::IterableDataProvider<M>,
173{
174 fn supported_locales(&self) -> Result<alloc::vec::Vec<DataLocale>, DataError> {
175 self.inner.supported_locales().map(|vec| {
176 vec.into_iter()
178 .filter_map(|locale| {
179 if (self.predicate)(DataRequest {
180 locale: &locale,
181 metadata: Default::default(),
182 }) {
183 Some(locale)
184 } else {
185 None
186 }
187 })
188 .collect()
189 })
190 }
191}
192
193#[cfg(feature = "datagen")]
194impl<D, F, MFrom, MTo> datagen::DataConverter<MFrom, MTo> for RequestFilterDataProvider<D, F>
195where
196 D: datagen::DataConverter<MFrom, MTo>,
197 MFrom: DataMarker,
198 MTo: DataMarker,
199 F: Fn(DataRequest) -> bool,
200{
201 fn convert(
202 &self,
203 key: DataKey,
204 from: DataPayload<MFrom>,
205 ) -> Result<DataPayload<MTo>, (DataPayload<MFrom>, DataError)> {
206 self.inner.convert(key, from)
208 }
209}
210
211pub trait Filterable: Sized {
215 fn filterable(
219 self,
220 filter_name: &'static str,
221 ) -> RequestFilterDataProvider<Self, fn(DataRequest) -> bool>;
222}
223
224impl<T> Filterable for T
225where
226 T: Sized,
227{
228 fn filterable(
229 self,
230 filter_name: &'static str,
231 ) -> RequestFilterDataProvider<Self, fn(DataRequest) -> bool> {
232 fn noop(_: DataRequest) -> bool {
233 true
234 }
235 RequestFilterDataProvider {
236 inner: self,
237 predicate: noop,
238 filter_name,
239 }
240 }
241}