use std::collections::VecDeque;
#[derive(Debug, Default, Clone)]
pub struct CircularQueue<T> {
buffer: VecDeque<T>,
capacity: usize,
}
impl<T> CircularQueue<T> {
pub fn new(capacity: usize) -> Self {
CircularQueue {
buffer: VecDeque::with_capacity(capacity + 1),
capacity,
}
}
pub fn push(&mut self, item: T) {
self.buffer.push_back(item);
if self.buffer.len() > self.capacity {
self.buffer.pop_front();
}
}
pub fn pop(&mut self) -> Option<T> {
self.buffer.pop_front()
}
pub fn is_empty(&self) -> bool {
self.buffer.is_empty()
}
pub fn is_full(&self) -> bool {
self.buffer.len() == self.capacity
}
pub fn len(&self) -> usize {
self.buffer.len()
}
pub fn capacity(&self) -> usize {
self.capacity
}
pub fn back(&self) -> Option<&T> {
self.buffer.back()
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.buffer.iter()
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_ring_buffer() {
let mut rb = CircularQueue::new(3);
assert_eq!(rb.len(), 0);
assert_eq!(rb.capacity(), 3);
assert!(rb.is_empty());
rb.push(1);
assert_eq!(rb.len(), 1);
assert_eq!(rb.pop(), Some(1));
assert!(rb.is_empty());
rb.push(2);
rb.push(3);
rb.push(4);
assert_eq!(rb.len(), 3);
assert_eq!(rb.pop(), Some(2));
assert_eq!(rb.pop(), Some(3));
assert_eq!(rb.pop(), Some(4));
assert!(rb.is_empty());
}
#[test]
fn test_wrap_around() {
let mut rb = CircularQueue::new(3);
rb.push(1);
rb.push(2);
rb.push(3);
assert_eq!(rb.len(), 3);
rb.push(4);
rb.push(5);
assert_eq!(rb.len(), 3);
assert_eq!(rb.pop(), Some(3));
assert_eq!(rb.pop(), Some(4));
assert_eq!(rb.pop(), Some(5));
assert!(rb.is_empty());
}
#[test]
fn empty_pop() {
let mut rb: CircularQueue<u32> = CircularQueue::new(3);
assert_eq!(rb.pop(), None);
}
}