use std::marker::PhantomData;
use crate::{ProcessContext, ProcessOutcome, ProcessorError};
pub trait ItemFilter<I>: Send + Sync {
fn keep(&self, item: &I) -> bool;
}
impl<I, F> ItemFilter<I> for F
where
F: Fn(&I) -> bool + Send + Sync,
{
fn keep(&self, item: &I) -> bool {
self(item)
}
}
pub struct FilterProcessor<I, F> {
predicate: F,
_marker: PhantomData<fn(&I)>,
}
impl<I, F> FilterProcessor<I, F>
where
F: ItemFilter<I>,
{
pub const fn new(predicate: F) -> Self {
Self {
predicate,
_marker: PhantomData,
}
}
}
impl<I, F> crate::ItemProcessor<I, I> for FilterProcessor<I, F>
where
I: Clone + Send + Sync,
F: ItemFilter<I>,
{
async fn process(
&self,
item: &I,
context: ProcessContext<'_>,
) -> Result<ProcessOutcome<I>, ProcessorError> {
if context.stop_token().is_stop_requested() {
return Ok(ProcessOutcome::Stopped);
}
if self.predicate.keep(item) {
Ok(ProcessOutcome::Item(item.clone()))
} else {
Ok(ProcessOutcome::Filtered)
}
}
}