use std::fmt::{Debug, Display};
#[derive(Debug)]
pub struct Queue<T> {
buffer: Vec<Option<T>>,
head: usize,
tail: usize,
size: usize,
}
impl<T> Queue<T> {
pub fn with_capacity(capacity: usize) -> Self {
let mut buffer = Vec::with_capacity(capacity);
buffer.extend((0..capacity).map(|_| None));
Queue {
buffer,
head: 0,
tail: 0,
size: 0,
}
}
pub fn new() -> Self {
Self::with_capacity(16)
}
pub fn enqueue(&mut self, value: T) -> Result<(), T> {
if self.is_full() {
return Err(value);
}
self.buffer[self.tail] = Some(value);
self.tail = (self.tail + 1) % self.capacity();
self.size += 1;
Ok(())
}
pub fn dequeue(&mut self) -> Option<T> {
if self.is_empty() {
return None;
}
let value = self.buffer[self.head].take();
self.head = (self.head + 1) % self.capacity();
self.size -= 1;
value
}
pub fn peek(&self) -> Option<&T> {
if self.is_empty() {
None
} else {
self.buffer[self.head].as_ref()
}
}
pub fn len(&self) -> usize {
self.size
}
pub fn is_empty(&self) -> bool {
self.size == 0
}
pub fn is_full(&self) -> bool {
self.size == self.capacity()
}
pub fn capacity(&self) -> usize {
self.buffer.capacity()
}
pub fn clear(&mut self) {
for i in 0..self.capacity() {
self.buffer[i] = None;
}
self.head = 0;
self.tail = 0;
self.size = 0;
}
}
impl<T: Clone> Clone for Queue<T> {
fn clone(&self) -> Self {
Queue {
buffer: self.buffer.clone(),
head: self.head,
tail: self.tail,
size: self.size,
}
}
}
impl<T> Default for Queue<T> {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_queue() {
let queue: Queue<i32> = Queue::new();
assert!(queue.is_empty());
assert_eq!(queue.len(), 0);
assert_eq!(queue.capacity(), 16);
}
#[test]
fn test_enqueue_dequeue() {
let mut queue = Queue::new();
assert!(queue.enqueue(1).is_ok());
assert!(queue.enqueue(2).is_ok());
assert!(queue.enqueue(3).is_ok());
assert_eq!(queue.len(), 3);
assert_eq!(queue.dequeue(), Some(1));
assert_eq!(queue.dequeue(), Some(2));
assert_eq!(queue.dequeue(), Some(3));
assert_eq!(queue.dequeue(), None);
}
#[test]
fn test_peek() {
let mut queue = Queue::new();
assert_eq!(queue.peek(), None);
queue.enqueue(1).unwrap();
assert_eq!(queue.peek(), Some(&1));
queue.enqueue(2).unwrap();
assert_eq!(queue.peek(), Some(&1));
}
#[test]
fn test_clear() {
let mut queue = Queue::new();
queue.enqueue(1).unwrap();
queue.enqueue(2).unwrap();
queue.clear();
assert!(queue.is_empty());
assert_eq!(queue.len(), 0);
}
#[test]
fn test_full_queue() {
let mut queue = Queue::with_capacity(3);
assert!(queue.enqueue(1).is_ok());
assert!(queue.enqueue(2).is_ok());
assert!(queue.enqueue(3).is_ok());
assert!(queue.enqueue(4).is_err());
assert_eq!(queue.dequeue(), Some(1));
assert!(queue.enqueue(4).is_ok());
assert_eq!(queue.len(), 3);
}
#[test]
fn test_circular_behavior() {
let mut queue = Queue::with_capacity(3);
assert!(queue.enqueue(1).is_ok());
assert!(queue.enqueue(2).is_ok());
assert!(queue.enqueue(3).is_ok());
assert_eq!(queue.dequeue(), Some(1));
assert!(queue.enqueue(4).is_ok());
assert_eq!(queue.dequeue(), Some(2));
assert_eq!(queue.dequeue(), Some(3));
assert_eq!(queue.dequeue(), Some(4));
}
}