1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
// This file is part of ICU4X. For terms of use, please see the file
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
use super::*;
use alloc::boxed::Box;
use icu_provider::prelude::*;
impl<D> FilterDataProvider<D, fn(DataIdentifierBorrowed) -> bool> {
/// Creates a [`FilterDataProvider`] that does not do any filtering.
///
/// Filters can be added using [`Self::with_filter`].
pub fn new(provider: D, filter_name: &'static str) -> Self {
Self {
inner: provider,
predicate: |_| true,
filter_name,
}
}
}
impl<D, F> FilterDataProvider<D, F>
where
F: Fn(DataIdentifierBorrowed) -> bool + Sync,
{
/// Filter out data requests with certain langids according to the predicate function. The
/// predicate should return `true` to allow a langid and `false` to reject a langid.
///
/// # Examples
///
/// ```
/// use icu_locale::LanguageIdentifier;
/// use icu_locale::{langid, subtags::language};
/// use icu_provider::hello_world::*;
/// use icu_provider::prelude::*;
/// use icu_provider_adapters::filter::FilterDataProvider;
///
/// let provider = FilterDataProvider::new(HelloWorldProvider, "Demo no-English filter")
/// .with_filter(|id| id.locale.language != language!("en"));
///
/// // German requests should succeed:
/// let de = DataIdentifierCow::from_locale(langid!("de").into());
/// let response: Result<DataResponse<HelloWorldV1Marker>, _> =
/// provider.load(DataRequest {
/// id: de.as_borrowed(),
/// ..Default::default()
/// });
/// assert!(matches!(response, Ok(_)));
///
/// // English requests should fail:
/// let en = DataIdentifierCow::from_locale(langid!("en-US").into());
/// let response: Result<DataResponse<HelloWorldV1Marker>, _> =
/// provider.load(DataRequest {
/// id: en.as_borrowed(),
/// ..Default::default()
/// });
/// let response: Result<DataResponse<HelloWorldV1Marker>, _> =
/// provider.load(DataRequest {
/// id: en.as_borrowed(),
/// ..Default::default()
/// });
/// assert!(matches!(
/// response,
/// Err(DataError {
/// kind: DataErrorKind::IdentifierNotFound,
/// ..
/// })
/// ));
///
/// // English should not appear in the iterator result:
/// let available_ids = provider
/// .iter_ids()
/// .expect("Should successfully make an iterator of supported locales");
/// assert!(available_ids.contains(&DataIdentifierCow::from_locale(langid!("de").into())));
/// assert!(!available_ids.contains(&DataIdentifierCow::from_locale(langid!("en").into())));
/// ```
#[allow(clippy::type_complexity)]
pub fn with_filter<'a>(
self,
predicate: impl Fn(DataIdentifierBorrowed) -> bool + Sync + 'a,
) -> FilterDataProvider<D, Box<dyn Fn(DataIdentifierBorrowed) -> bool + Sync + 'a>>
where
F: 'a,
{
let old_predicate = self.predicate;
FilterDataProvider {
inner: self.inner,
predicate: Box::new(move |id| -> bool {
if !(old_predicate)(id) {
return false;
}
predicate(id)
}),
filter_name: self.filter_name,
}
}
}