use std::collections::VecDeque;
#[derive(Clone, Debug)]
pub(crate) struct Recent<T> {
kept: usize,
shed: usize,
items: VecDeque<T>,
}
impl<T> Recent<T> {
pub(crate) fn keeping(kept: usize) -> Recent<T> {
Recent {
kept,
shed: 0,
items: VecDeque::new(),
}
}
pub(crate) fn push(&mut self, item: T) -> usize {
self.pushed(item).0
}
pub(crate) fn pushed(&mut self, item: T) -> (usize, Option<T>) {
self.items.push_back(item);
let shed = (self.items.len() > self.kept)
.then(|| self.items.pop_front())
.flatten();
self.shed += usize::from(shed.is_some());
(self.made() - 1, shed)
}
pub(crate) fn get(&self, at: usize) -> Option<&T> {
self.items.get(at.checked_sub(self.shed)?)
}
pub(crate) fn get_mut(&mut self, at: usize) -> Option<&mut T> {
self.items.get_mut(at.checked_sub(self.shed)?)
}
pub(crate) fn made(&self) -> usize {
self.shed + self.items.len()
}
pub(crate) fn shed(&self) -> usize {
self.shed
}
pub(crate) fn iter(&self) -> impl Iterator<Item = &T> {
self.items.iter()
}
}