use std::collections::VecDeque;
pub struct RingBuffer<T> {
pub data: VecDeque<T>,
}
impl<T> RingBuffer<T> {
pub fn new(size: usize) -> Self {
Self {
data: VecDeque::with_capacity(size),
}
}
pub fn from_iter(iter: impl Iterator<Item = T>, size: usize) -> Self {
let mut ring_buffer = Self::new(size);
for value in iter {
ring_buffer.push_back(value);
}
ring_buffer
}
pub fn push_back(&mut self, value: T) -> Option<T> {
if self.data.capacity() == 0 {
return Some(value);
}
let result = if self.data.len() == self.data.capacity() {
self.data.pop_front()
} else {
None
};
self.data.push_back(value);
result
}
}
#[cfg(test)]
mod tests {
use crate::ringbuffer::RingBuffer;
use std::collections::VecDeque;
#[test]
fn test_size_limit_zero() {
let mut buf = RingBuffer::new(0);
assert_eq!(Some(0), buf.push_back(0));
assert_eq!(Some(1), buf.push_back(1));
assert_eq!(Some(2), buf.push_back(2));
}
#[test]
fn test_evict_oldest() {
let mut buf = RingBuffer::new(2);
assert_eq!(None, buf.push_back(0));
assert_eq!(None, buf.push_back(1));
assert_eq!(Some(0), buf.push_back(2));
}
#[test]
fn test_from_iter() {
let iter = [0, 1, 2].iter();
let actual = RingBuffer::from_iter(iter, 2).data;
let expected: VecDeque<&i32> = [1, 2].iter().collect();
assert_eq!(expected, actual);
}
}