#[derive(Debug, Clone)]
pub struct RingBuf<T: Clone> {
buf: Vec<T>,
cap: usize,
head: usize,
len: usize,
}
impl<T: Clone> RingBuf<T> {
pub fn new(cap: usize, initial: T) -> Self {
assert!(cap > 0, "RingBuf capacity must be > 0");
Self {
buf: vec![initial; cap],
cap,
head: 0,
len: 0,
}
}
pub fn push(&mut self, value: T) -> Option<T> {
let overwritten = if self.is_full() {
Some(self.buf[self.head].clone())
} else {
None
};
self.buf[self.head] = value;
self.head = (self.head + 1) % self.cap;
self.len = self.len.saturating_add(1).min(self.cap);
overwritten
}
pub fn len(&self) -> usize {
self.len
}
#[allow(dead_code)]
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn is_full(&self) -> bool {
self.len == self.cap
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
(0..self.len).map(move |i| &self.buf[(self.head + self.cap - self.len + i) % self.cap])
}
#[allow(dead_code)]
pub fn latest(&self) -> Option<&T> {
if self.len == 0 {
None
} else {
let idx = (self.head + self.cap - 1) % self.cap;
self.buf.get(idx)
}
}
}