pub mod contains;
pub mod error;
pub mod take;
pub use self::{contains::Contains, take::Take};
use self::error::FilterError;
use crate::{
entry::Entry,
maybe_send::{MaybeSend, MaybeSendSync},
};
use std::{convert::Infallible, ops::RangeBounds, slice, vec};
use super::{Action, ActionContext, ActionResult};
pub trait Filter: MaybeSendSync {
type Err: Into<FilterError>;
fn filter(
&mut self,
entries: FilterableEntries<'_>,
) -> impl Future<Output = Result<(), Self::Err>> + MaybeSend;
}
#[derive(Debug)]
pub struct FilterableEntries<'a>(&'a mut Vec<Entry>);
impl<'a> FilterableEntries<'a> {
pub fn new(entries: &'a mut Vec<Entry>) -> Self {
Self(entries)
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn iter(&self) -> slice::Iter<'_, Entry> {
self.0.iter()
}
pub fn retain<F>(&mut self, f: F)
where
F: FnMut(&Entry) -> bool,
{
self.0.retain(f);
}
pub fn truncate(&mut self, len: usize) {
self.0.truncate(len);
}
pub fn drain<R>(&mut self, range: R) -> vec::Drain<'_, Entry>
where
R: RangeBounds<usize>,
{
self.0.drain(range)
}
}
#[derive(Clone, Debug)]
pub struct FilterAction<F>(pub F);
impl Filter for () {
type Err = Infallible;
async fn filter(&mut self, _entries: FilterableEntries<'_>) -> Result<(), Self::Err> {
Ok(())
}
}
impl<F: Filter> Filter for Option<F> {
type Err = F::Err;
async fn filter(&mut self, entries: FilterableEntries<'_>) -> Result<(), Self::Err> {
let Some(f) = self else {
return Ok(());
};
f.filter(entries).await
}
}
impl Filter for Infallible {
type Err = Infallible;
async fn filter(&mut self, _entries: FilterableEntries<'_>) -> Result<(), Self::Err> {
match *self {}
}
}
#[cfg(feature = "nightly")]
impl Filter for ! {
type Err = !;
async fn filter(&mut self, _entries: FilterableEntries<'_>) -> Result<(), Self::Err> {
match *self {}
}
}
impl<F> Filter for &mut F
where
F: Filter,
{
type Err = F::Err;
fn filter(
&mut self,
entries: FilterableEntries<'_>,
) -> impl Future<Output = Result<(), Self::Err>> + MaybeSend {
(*self).filter(entries)
}
}
impl<F> Action for FilterAction<F>
where
F: Filter,
{
type Err = FilterError;
async fn apply<S, E>(
&mut self,
mut entries: Vec<Entry>,
_ctx: ActionContext<'_, S, E>,
) -> ActionResult<Self::Err> {
match self.0.filter(FilterableEntries(&mut entries)).await {
Ok(()) => ActionResult::Ok(entries),
Err(e) => ActionResult::Err(e.into()),
}
}
}