use super::{Batch, Disposition};
use crate::packets::Packet;
use anyhow::Result;
#[allow(missing_debug_implementations)]
pub struct Replace<B: Batch, T: Packet, F>
where
F: FnMut(&B::Item) -> Result<T>,
{
batch: B,
f: F,
slot: Option<B::Item>,
}
impl<B: Batch, T: Packet, F> Replace<B, T, F>
where
F: FnMut(&B::Item) -> Result<T>,
{
#[inline]
pub fn new(batch: B, f: F) -> Self {
Replace {
batch,
f,
slot: None,
}
}
}
impl<B: Batch, T: Packet, F> Batch for Replace<B, T, F>
where
F: FnMut(&B::Item) -> Result<T>,
{
type Item = T;
#[inline]
fn replenish(&mut self) {
self.batch.replenish();
}
#[inline]
fn next(&mut self) -> Option<Disposition<Self::Item>> {
if let Some(pkt) = self.slot.take() {
Some(Disposition::Drop(pkt.reset()))
} else {
self.batch.next().map(|disp| {
disp.map(|orig| {
match (self.f)(&orig) {
Ok(new) => {
self.slot.replace(orig);
Disposition::Act(new)
}
Err(e) => Disposition::Abort(e),
}
})
})
}
}
}