use super::{Batch, Disposition};
use crate::packets::Packet;
use crate::Mbuf;
use anyhow::Result;
#[allow(missing_debug_implementations)]
pub enum Either<T> {
Keep(T),
Drop(Mbuf),
}
#[allow(missing_debug_implementations)]
pub struct FilterMap<B: Batch, T: Packet, F>
where
F: FnMut(B::Item) -> Result<Either<T>>,
{
batch: B,
f: F,
}
impl<B: Batch, T: Packet, F> FilterMap<B, T, F>
where
F: FnMut(B::Item) -> Result<Either<T>>,
{
#[inline]
pub fn new(batch: B, f: F) -> Self {
FilterMap { batch, f }
}
}
impl<B: Batch, T: Packet, F> Batch for FilterMap<B, T, F>
where
F: FnMut(B::Item) -> Result<Either<T>>,
{
type Item = T;
#[inline]
fn replenish(&mut self) {
self.batch.replenish();
}
#[inline]
fn next(&mut self) -> Option<Disposition<Self::Item>> {
self.batch.next().map(|disp| {
disp.map(|orig| match (self.f)(orig) {
Ok(Either::Keep(new)) => Disposition::Act(new),
Ok(Either::Drop(mbuf)) => Disposition::Drop(mbuf),
Err(e) => Disposition::Abort(e),
})
})
}
}