mod impls;
use alloc::collections::BTreeSet;
#[cfg(feature = "export")]
use icu_provider::export::ExportableProvider;
use icu_provider::prelude::*;
#[allow(clippy::exhaustive_structs)] #[derive(Debug)]
pub struct FilterDataProvider<D, F>
where
F: Fn(DataIdentifierBorrowed) -> bool,
{
pub inner: D,
pub predicate: F,
pub filter_name: &'static str,
}
impl<D, F> FilterDataProvider<D, F>
where
F: Fn(DataIdentifierBorrowed) -> bool,
{
fn check(&self, marker: DataMarkerInfo, req: DataRequest) -> Result<(), DataError> {
if !(self.predicate)(req.id) {
return Err(DataErrorKind::IdentifierNotFound
.with_str_context(self.filter_name)
.with_req(marker, req));
}
Ok(())
}
}
impl<D, F, M> DynamicDataProvider<M> for FilterDataProvider<D, F>
where
F: Fn(DataIdentifierBorrowed) -> bool,
M: DynamicDataMarker,
D: DynamicDataProvider<M>,
{
fn load_data(
&self,
marker: DataMarkerInfo,
req: DataRequest,
) -> Result<DataResponse<M>, DataError> {
self.check(marker, req)?;
self.inner.load_data(marker, req)
}
}
impl<D, F, M> DynamicDryDataProvider<M> for FilterDataProvider<D, F>
where
F: Fn(DataIdentifierBorrowed) -> bool,
M: DynamicDataMarker,
D: DynamicDryDataProvider<M>,
{
fn dry_load_data(
&self,
marker: DataMarkerInfo,
req: DataRequest,
) -> Result<DataResponseMetadata, DataError> {
self.check(marker, req)?;
self.inner.dry_load_data(marker, req)
}
}
impl<D, F, M> DataProvider<M> for FilterDataProvider<D, F>
where
F: Fn(DataIdentifierBorrowed) -> bool,
M: DataMarker,
D: DataProvider<M>,
{
fn load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError> {
self.check(M::INFO, req)?;
self.inner.load(req)
}
}
impl<D, F, M> DryDataProvider<M> for FilterDataProvider<D, F>
where
F: Fn(DataIdentifierBorrowed) -> bool,
M: DataMarker,
D: DryDataProvider<M>,
{
fn dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError> {
self.check(M::INFO, req)?;
self.inner.dry_load(req)
}
}
impl<D, F> AnyProvider for FilterDataProvider<D, F>
where
F: Fn(DataIdentifierBorrowed) -> bool,
D: AnyProvider,
{
fn load_any(&self, marker: DataMarkerInfo, req: DataRequest) -> Result<AnyResponse, DataError> {
self.check(marker, req)?;
self.inner.load_any(marker, req)
}
}
impl<M, D, F> IterableDynamicDataProvider<M> for FilterDataProvider<D, F>
where
M: DynamicDataMarker,
F: Fn(DataIdentifierBorrowed) -> bool,
D: IterableDynamicDataProvider<M>,
{
fn iter_ids_for_marker(
&self,
marker: DataMarkerInfo,
) -> Result<BTreeSet<DataIdentifierCow>, DataError> {
self.inner.iter_ids_for_marker(marker).map(|set| {
set.into_iter()
.filter(|id| (self.predicate)(id.as_borrowed()))
.collect()
})
}
}
impl<M, D, F> IterableDataProvider<M> for FilterDataProvider<D, F>
where
M: DataMarker,
F: Fn(DataIdentifierBorrowed) -> bool,
D: IterableDataProvider<M>,
{
fn iter_ids(&self) -> Result<BTreeSet<DataIdentifierCow>, DataError> {
self.inner.iter_ids().map(|vec| {
vec.into_iter()
.filter(|id| (self.predicate)(id.as_borrowed()))
.collect()
})
}
}
#[cfg(feature = "export")]
impl<P0, F> ExportableProvider for FilterDataProvider<P0, F>
where
P0: ExportableProvider,
F: Fn(DataIdentifierBorrowed) -> bool + Sync,
{
fn supported_markers(&self) -> std::collections::HashSet<DataMarkerInfo> {
self.inner.supported_markers()
}
}