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