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 use super::*; 6 use alloc::boxed::Box; 7 use icu_provider::prelude::*; 8 9 impl<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`]. new(provider: D, filter_name: &'static str) -> Self13 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 22 impl<D, F> FilterDataProvider<D, F> 23 where 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!(matches!(response, 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!(matches!( 64 /// response, 65 /// Err(DataError { 66 /// kind: DataErrorKind::IdentifierNotFound, 67 /// .. 68 /// }) 69 /// )); 70 /// 71 /// // English should not appear in the iterator result: 72 /// let available_ids = provider 73 /// .iter_ids() 74 /// .expect("Should successfully make an iterator of supported locales"); 75 /// assert!(available_ids 76 /// .contains(&DataIdentifierCow::from_locale(langid!("de").into()))); 77 /// assert!(!available_ids 78 /// .contains(&DataIdentifierCow::from_locale(langid!("en").into()))); 79 /// ``` 80 #[allow(clippy::type_complexity)] with_filter<'a>( self, predicate: impl Fn(DataIdentifierBorrowed) -> bool + Sync + 'a, ) -> FilterDataProvider<D, Box<dyn Fn(DataIdentifierBorrowed) -> bool + Sync + 'a>> where F: 'a,81 pub fn with_filter<'a>( 82 self, 83 predicate: impl Fn(DataIdentifierBorrowed) -> bool + Sync + 'a, 84 ) -> FilterDataProvider<D, Box<dyn Fn(DataIdentifierBorrowed) -> bool + Sync + 'a>> 85 where 86 F: 'a, 87 { 88 let old_predicate = self.predicate; 89 FilterDataProvider { 90 inner: self.inner, 91 predicate: Box::new(move |id| -> bool { 92 if !(old_predicate)(id) { 93 return false; 94 } 95 predicate(id) 96 }), 97 filter_name: self.filter_name, 98 } 99 } 100 } 101