Struct icu_provider::filter::RequestFilterDataProvider [−][src]
pub struct RequestFilterDataProvider<D, F> where
F: Fn(&DataRequest) -> bool, { pub inner: D, pub predicate: F, pub description: String, }
Expand description
A data provider that selectively filters out data requests.
Data requests that are rejected by the filter will return DataError::FilteredResource
, and
they will not be returned by IterableDataProviderCore::supported_options_for_key
.
Although this struct can be created directly, the traits in this module provide helper functions for common filtering patterns.
Fields
inner: D
The data provider to which we delegate requests.
predicate: F
The predicate function. A return value of true
indicates that the request should
proceed as normal; a return value of false
will reject the request.
description: String
A description for this filter, used in error messages.
Implementations
pub fn filter_by_langid<'a>(
self,
predicate: impl Fn(&LanguageIdentifier) -> bool + 'a
) -> RequestFilterDataProvider<D, Box<dyn Fn(&DataRequest) -> bool + 'a>> where
F: 'a,
pub fn filter_by_langid<'a>(
self,
predicate: impl Fn(&LanguageIdentifier) -> bool + 'a
) -> RequestFilterDataProvider<D, Box<dyn Fn(&DataRequest) -> bool + 'a>> where
F: 'a,
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.
Data requests with no langid will be allowed. To reject data requests without a langid,
chain this with Self::require_langid
.
Examples
use icu_provider::prelude::*; use icu_provider::hello_world::*; use icu_provider::filter::Filterable; use icu_provider::iter::IterableDataProviderCore; use icu_locid::LanguageIdentifier; use icu_locid_macros::{language, langid}; let provider = HelloWorldProvider::new_with_placeholder_data() .filterable() .filter_by_langid(|langid| langid.language != language!("en")); // German requests should succeed: let req_de = DataRequest { resource_path: ResourcePath { key: key::HELLO_WORLD_V1, options: langid!("de").into(), } }; let response: Result<DataResponse<HelloWorldV1Marker>, _> = provider.load_payload(&req_de); assert!(matches!(response, Ok(_))); // English requests should fail: let req_en = DataRequest { resource_path: ResourcePath { key: key::HELLO_WORLD_V1, options: langid!("en-US").into(), } }; let response: Result<DataResponse<HelloWorldV1Marker>, _> = provider.load_payload(&req_en); assert!(matches!(response, Err(DataError::FilteredResource(_, _)))); // English should not appear in the iterator result: let supported_langids = provider.supported_options_for_key(&key::HELLO_WORLD_V1) .expect("Should successfully make an iterator of supported locales") .filter_map(|options| options.langid) .collect::<Vec<LanguageIdentifier>>(); assert!(supported_langids.contains(&langid!("de"))); assert!(!supported_langids.contains(&langid!("en")));
pub fn filter_by_langid_with_description<'a>(
self,
predicate: impl Fn(&LanguageIdentifier) -> bool + 'a,
description: String
) -> RequestFilterDataProvider<D, Box<dyn Fn(&DataRequest) -> bool + 'a>> where
F: 'a,
pub fn filter_by_langid_with_description<'a>(
self,
predicate: impl Fn(&LanguageIdentifier) -> bool + 'a,
description: String
) -> RequestFilterDataProvider<D, Box<dyn Fn(&DataRequest) -> bool + 'a>> where
F: 'a,
Same as Self::filter_by_langid
but with an extra argument to set a custom
description for debugging.
pub fn filter_by_langid_allowlist_strict<'a>(
self,
allowlist: &'a [LanguageIdentifier]
) -> RequestFilterDataProvider<D, Box<dyn Fn(&DataRequest) -> bool + 'a>> where
F: 'a,
pub fn filter_by_langid_allowlist_strict<'a>(
self,
allowlist: &'a [LanguageIdentifier]
) -> RequestFilterDataProvider<D, Box<dyn Fn(&DataRequest) -> bool + 'a>> where
F: 'a,
Filter out data request except those having a language identifier that exactly matches one in the allowlist.
This will be replaced with a smarter algorithm for locale filtering; see https://github.com/unicode-org/icu4x/issues/834
Data requests with no langid will be allowed. To reject data requests without a langid,
chain this with Self::require_langid
.
Examples
use icu_provider::prelude::*; use icu_provider::hello_world::*; use icu_provider::filter::Filterable; use icu_locid_macros::langid; let allowlist = vec![langid!("de"), langid!("zh")]; let provider = HelloWorldProvider::new_with_placeholder_data() .filterable() .filter_by_langid_allowlist_strict(&allowlist); // German requests should succeed: let req_de = DataRequest { resource_path: ResourcePath { key: key::HELLO_WORLD_V1, options: langid!("de").into(), } }; let response: Result<DataResponse<HelloWorldV1Marker>, _> = provider.load_payload(&req_de); assert!(matches!(response, Ok(_))); // English requests should fail: let req_en = DataRequest { resource_path: ResourcePath { key: key::HELLO_WORLD_V1, options: langid!("en-US").into(), } }; let response: Result<DataResponse<HelloWorldV1Marker>, _> = provider.load_payload(&req_en); assert!(matches!(response, Err(DataError::FilteredResource(_, _)))); assert_eq!( "Resource was filtered: Locale filter (allowlist: [de, zh]): core/helloworld@1/en-US", response.unwrap_err().to_string() );
pub fn require_langid<'a>(
self
) -> RequestFilterDataProvider<D, Box<dyn Fn(&DataRequest) -> bool + 'a>> where
F: 'a,
pub fn require_langid<'a>(
self
) -> RequestFilterDataProvider<D, Box<dyn Fn(&DataRequest) -> bool + 'a>> where
F: 'a,
Require that data requests contain a langid.
Examples
use icu_provider::prelude::*; use icu_provider::hello_world::*; use icu_provider::filter::Filterable; use icu_locid_macros::langid; let provider = HelloWorldProvider::new_with_placeholder_data() .filterable() .require_langid(); // Requests with a langid should succeed: let req_with_langid = DataRequest { resource_path: ResourcePath { key: key::HELLO_WORLD_V1, options: langid!("de").into(), } }; let response: Result<DataResponse<HelloWorldV1Marker>, _> = provider.load_payload(&req_with_langid); assert!(matches!(response, Ok(_))); // Requests without a langid should fail: let req_no_langid = DataRequest { resource_path: ResourcePath { key: key::HELLO_WORLD_V1, options: Default::default(), } }; let response: Result<DataResponse<HelloWorldV1Marker>, _> = provider.load_payload(&req_no_langid); assert!(matches!(response, Err(DataError::FilteredResource(_, _))));
Trait Implementations
impl<'data, D, F, M> DataProvider<'data, M> for RequestFilterDataProvider<D, F> where
F: Fn(&DataRequest) -> bool,
M: DataMarker<'data>,
D: DataProvider<'data, M>,
impl<'data, D, F, M> DataProvider<'data, M> for RequestFilterDataProvider<D, F> where
F: Fn(&DataRequest) -> bool,
M: DataMarker<'data>,
D: DataProvider<'data, M>,
Query the provider for data, returning the result. Read more
impl<D, F> IterableDataProviderCore for RequestFilterDataProvider<D, F> where
F: Fn(&DataRequest) -> bool,
D: IterableDataProviderCore,
impl<D, F> IterableDataProviderCore for RequestFilterDataProvider<D, F> where
F: Fn(&DataRequest) -> bool,
D: IterableDataProviderCore,
fn supported_options_for_key(
&self,
resc_key: &ResourceKey
) -> Result<Box<dyn Iterator<Item = ResourceOptions>>, DataError>
fn supported_options_for_key(
&self,
resc_key: &ResourceKey
) -> Result<Box<dyn Iterator<Item = ResourceOptions>>, DataError>
Given a ResourceKey
, returns a boxed iterator over ResourceOptions
.
Auto Trait Implementations
impl<D, F> RefUnwindSafe for RequestFilterDataProvider<D, F> where
D: RefUnwindSafe,
F: RefUnwindSafe,
impl<D, F> Send for RequestFilterDataProvider<D, F> where
D: Send,
F: Send,
impl<D, F> Sync for RequestFilterDataProvider<D, F> where
D: Sync,
F: Sync,
impl<D, F> Unpin for RequestFilterDataProvider<D, F> where
D: Unpin,
F: Unpin,
impl<D, F> UnwindSafe for RequestFilterDataProvider<D, F> where
D: UnwindSafe,
F: UnwindSafe,
Blanket Implementations
Mutably borrows from an owned value. Read more
impl<'data, T> ErasedDataProvider<'data> for T where
T: DataProvider<'static, ErasedDataStructMarker>,
impl<'data, T> ErasedDataProvider<'data> for T where
T: DataProvider<'static, ErasedDataStructMarker>,
pub fn load_erased(
&Self,
&DataRequest
) -> Result<DataResponse<'static, ErasedDataStructMarker>, Error>
pub fn load_erased(
&Self,
&DataRequest
) -> Result<DataResponse<'static, ErasedDataStructMarker>, Error>
Query the provider for data, returning the result as an ErasedDataStruct
trait object. Read more
Clone this trait object reference, returning a boxed trait object.