#[derive(Debug)]
pub struct CircularBuffer<T> {
pub buffer: Vec<T>,
write_index: usize,
}
impl<T> CircularBuffer<T>
where
T: Clone,
{
pub fn new(capacity: usize) -> Self {
Self {
buffer: Vec::with_capacity(capacity),
write_index: 0,
}
}
pub fn capacity(&self) -> usize {
self.buffer.capacity()
}
pub fn len(&self) -> usize {
self.buffer.len()
}
pub fn is_empty(&self) -> bool {
self.buffer.is_empty()
}
pub fn push(&mut self, element: T) {
let capacity = self.capacity();
let len = self.len();
if len < capacity {
self.buffer.push(element);
} else {
self.buffer[self.write_index % capacity] = element;
}
self.write_index += 1;
}
pub fn ordered_clone(&self) -> Self {
let capacity = self.capacity();
let len = self.len();
let mut cb = Self::new(capacity);
if len < capacity {
cb.buffer.clone_from(&self.buffer);
} else {
let index_position = self.write_index % capacity;
cb.buffer.extend_from_slice(&self.buffer[index_position..]);
cb.buffer.extend_from_slice(&self.buffer[..index_position]);
}
cb
}
pub fn reset(&mut self) {
self.buffer.clear();
self.write_index = 0;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn circular_buffer() {
let mut cb: CircularBuffer<i32> = CircularBuffer::new(3);
assert_eq!(cb.capacity(), 3);
assert_eq!(cb.len(), 0);
assert!(cb.is_empty());
cb.push(1);
assert_eq!(cb.buffer, vec![1]);
assert_eq!(cb.len(), 1);
assert!(!cb.is_empty());
cb.push(2);
cb.push(3);
assert_eq!(cb.buffer, vec![1, 2, 3]);
assert_eq!(cb.len(), 3);
cb.push(4);
assert_eq!(cb.buffer, vec![4, 2, 3]);
assert_eq!(cb.len(), 3);
}
#[test]
fn circular_buffer_clone() {
let mut cb: CircularBuffer<i32> = CircularBuffer::new(3);
cb.push(1);
cb.push(2);
cb.push(3);
cb.push(4);
let cb2 = cb.ordered_clone();
assert_eq!(cb2.buffer, vec![2, 3, 4]);
}
}