pub struct RequestFilterDataProvider<D, F>{
pub inner: D,
pub predicate: F,
pub filter_name: &'static str,
}
Expand description
A data provider that selectively filters out data requests.
Data requests that are rejected by the filter will return a DataError
with kind
FilteredResource
, and they will not be returned
by [datagen::IterableDynamicDataProvider::supported_locales_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.
filter_name: &'static str
A name for this filter, used in error messages.
Implementations§
source§impl<D, F> RequestFilterDataProvider<D, F>
impl<D, F> RequestFilterDataProvider<D, F>
sourcepub fn filter_by_langid<'a>(
self,
predicate: impl Fn(&LanguageIdentifier) -> bool + Sync + 'a,
) -> RequestFilterDataProvider<D, Box<dyn Fn(DataRequest<'_>) -> bool + Sync + 'a>>where
F: 'a,
pub fn filter_by_langid<'a>(
self,
predicate: impl Fn(&LanguageIdentifier) -> bool + Sync + 'a,
) -> RequestFilterDataProvider<D, Box<dyn Fn(DataRequest<'_>) -> bool + Sync + '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_locid::LanguageIdentifier;
use icu_locid::{langid, subtags::language};
use icu_provider::datagen::*;
use icu_provider::hello_world::*;
use icu_provider::prelude::*;
use icu_provider_adapters::filter::Filterable;
let provider = HelloWorldProvider
.filterable("Demo no-English filter")
.filter_by_langid(|langid| langid.language != language!("en"));
// German requests should succeed:
let req_de = DataRequest {
locale: &langid!("de").into(),
metadata: Default::default(),
};
let response: Result<DataResponse<HelloWorldV1Marker>, _> =
provider.load(req_de);
assert!(matches!(response, Ok(_)));
// English requests should fail:
let req_en = DataRequest {
locale: &langid!("en-US").into(),
metadata: Default::default(),
};
let response: Result<DataResponse<HelloWorldV1Marker>, _> =
provider.load(req_en);
assert!(matches!(
response,
Err(DataError {
kind: DataErrorKind::FilteredResource,
..
})
));
// English should not appear in the iterator result:
let supported_langids = provider
.supported_locales()
.expect("Should successfully make an iterator of supported locales")
.into_iter()
.map(|options| options.get_langid())
.collect::<Vec<LanguageIdentifier>>();
assert!(supported_langids.contains(&langid!("de")));
assert!(!supported_langids.contains(&langid!("en")));
sourcepub fn filter_by_langid_allowlist_strict<'a>(
self,
allowlist: &'a [LanguageIdentifier],
) -> RequestFilterDataProvider<D, Box<dyn Fn(DataRequest<'_>) -> bool + Sync + 'a>>where
F: 'a,
pub fn filter_by_langid_allowlist_strict<'a>(
self,
allowlist: &'a [LanguageIdentifier],
) -> RequestFilterDataProvider<D, Box<dyn Fn(DataRequest<'_>) -> bool + Sync + '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_locid::langid;
use icu_provider::hello_world::*;
use icu_provider::prelude::*;
use icu_provider_adapters::filter::Filterable;
let allowlist = [langid!("de"), langid!("zh")];
let provider = HelloWorldProvider
.filterable("Demo German+Chinese filter")
.filter_by_langid_allowlist_strict(&allowlist);
// German requests should succeed:
let req_de = DataRequest {
locale: &langid!("de").into(),
metadata: Default::default(),
};
let response: Result<DataResponse<HelloWorldV1Marker>, _> =
provider.load(req_de);
assert!(matches!(response, Ok(_)));
// English requests should fail:
let req_en = DataRequest {
locale: &langid!("en-US").into(),
metadata: Default::default(),
};
let response: Result<DataResponse<HelloWorldV1Marker>, _> =
provider.load(req_en);
assert!(matches!(
response,
Err(DataError {
kind: DataErrorKind::FilteredResource,
..
})
));
assert_eq!(
response.unwrap_err().str_context,
Some("Demo German+Chinese filter")
);
sourcepub fn require_langid<'a>(
self,
) -> RequestFilterDataProvider<D, Box<dyn Fn(DataRequest<'_>) -> bool + Sync + 'a>>where
F: 'a,
pub fn require_langid<'a>(
self,
) -> RequestFilterDataProvider<D, Box<dyn Fn(DataRequest<'_>) -> bool + Sync + 'a>>where
F: 'a,
Require that data requests contain a langid.
§Examples
use icu_locid::langid;
use icu_provider::hello_world::*;
use icu_provider::prelude::*;
use icu_provider_adapters::filter::Filterable;
let provider = HelloWorldProvider
.filterable("Demo require-langid filter")
.require_langid();
// Requests with a langid should succeed:
let req_with_langid = DataRequest {
locale: &langid!("de").into(),
metadata: Default::default(),
};
let response: Result<DataResponse<HelloWorldV1Marker>, _> =
provider.load(req_with_langid);
assert!(matches!(response, Ok(_)));
// Requests without a langid should fail:
let req_no_langid = DataRequest {
locale: Default::default(),
metadata: Default::default(),
};
let response: Result<DataResponse<HelloWorldV1Marker>, _> =
provider.load(req_no_langid);
assert!(matches!(
response,
Err(DataError {
kind: DataErrorKind::FilteredResource,
..
})
));
Trait Implementations§
source§impl<D, F> AnyProvider for RequestFilterDataProvider<D, F>
impl<D, F> AnyProvider for RequestFilterDataProvider<D, F>
source§fn load_any(
&self,
key: DataKey,
req: DataRequest<'_>,
) -> Result<AnyResponse, DataError>
fn load_any( &self, key: DataKey, req: DataRequest<'_>, ) -> Result<AnyResponse, DataError>
AnyPayload
according to the key and request.source§impl<D, F> BufferProvider for RequestFilterDataProvider<D, F>
impl<D, F> BufferProvider for RequestFilterDataProvider<D, F>
source§fn load_buffer(
&self,
key: DataKey,
req: DataRequest<'_>,
) -> Result<DataResponse<BufferMarker>, DataError>
fn load_buffer( &self, key: DataKey, req: DataRequest<'_>, ) -> Result<DataResponse<BufferMarker>, DataError>
source§impl<D, F, M> DataProvider<M> for RequestFilterDataProvider<D, F>
impl<D, F, M> DataProvider<M> for RequestFilterDataProvider<D, F>
source§fn load(&self, req: DataRequest<'_>) -> Result<DataResponse<M>, DataError>
fn load(&self, req: DataRequest<'_>) -> Result<DataResponse<M>, DataError>
source§impl<D: Debug, F> Debug for RequestFilterDataProvider<D, F>
impl<D: Debug, F> Debug for RequestFilterDataProvider<D, F>
source§impl<D, F, M> DynamicDataProvider<M> for RequestFilterDataProvider<D, F>
impl<D, F, M> DynamicDataProvider<M> for RequestFilterDataProvider<D, F>
source§fn load_data(
&self,
key: DataKey,
req: DataRequest<'_>,
) -> Result<DataResponse<M>, DataError>
fn load_data( &self, key: DataKey, req: DataRequest<'_>, ) -> Result<DataResponse<M>, DataError>
Auto Trait Implementations§
impl<D, F> Freeze for RequestFilterDataProvider<D, F>
impl<D, F> RefUnwindSafe for RequestFilterDataProvider<D, F>where
D: RefUnwindSafe,
F: RefUnwindSafe,
impl<D, F> Send for RequestFilterDataProvider<D, F>
impl<D, F> Sync for RequestFilterDataProvider<D, F>
impl<D, F> Unpin for RequestFilterDataProvider<D, F>
impl<D, F> UnwindSafe for RequestFilterDataProvider<D, F>where
D: UnwindSafe,
F: UnwindSafe,
Blanket Implementations§
source§impl<P> AsDowncastingAnyProvider for Pwhere
P: AnyProvider + ?Sized,
impl<P> AsDowncastingAnyProvider for Pwhere
P: AnyProvider + ?Sized,
source§fn as_downcasting(&self) -> DowncastingAnyProvider<'_, P>
fn as_downcasting(&self) -> DowncastingAnyProvider<'_, P>
DynamicDataProvider<M>
when called on AnyProvider
source§impl<P> AsDynamicDataProviderAnyMarkerWrap for P
impl<P> AsDynamicDataProviderAnyMarkerWrap for P
source§fn as_any_provider(&self) -> DynamicDataProviderAnyMarkerWrap<'_, P>
fn as_any_provider(&self) -> DynamicDataProviderAnyMarkerWrap<'_, P>
AnyProvider
when called on DynamicDataProvider<AnyMarker>