scratch/2021-07-11/array-queue/src/lib.rs

158 lines
3.2 KiB
Rust

use crate::error::ArrayQueueError;
mod alloc;
mod error;
#[derive(Clone, Copy, Debug)]
pub struct ArrayQueue<T, const N: usize> {
inner: [T; N],
head: usize,
tail: usize,
}
impl<T: Default + Copy, const N: usize> Default for ArrayQueue<T, N> {
fn default() -> Self {
Self {
inner: [T::default(); N],
head: Default::default(),
tail: Default::default(),
}
}
}
impl<T: Copy, const N: usize> ArrayQueue<T, N> {
pub fn new(default: T) -> Self {
Self {
inner: [default; N],
head: Default::default(),
tail: Default::default(),
}
}
pub fn push(&mut self, value: T) -> Result<(), ArrayQueueError> {
if self.tail >= N {
return Err(ArrayQueueError::CapacityReached);
}
self.inner[self.tail] = value;
self.tail += 1;
Ok(())
}
pub fn pop(&mut self) -> Option<&T> {
let prev_head = self.head;
self.head += 1;
if prev_head < self.tail {
self.inner.get(prev_head)
} else {
None
}
}
#[inline]
pub fn len(&self) -> usize {
self.tail - self.head
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn capacity(&self) -> usize {
N
}
pub fn clear(&mut self) {
self.head = 0;
self.tail = 0;
}
}
trait Queue<T> {}
#[cfg(test)]
mod tests {
use super::ArrayQueue;
#[test]
fn init_with_default() {
let _queue: ArrayQueue<u8, 5> = Default::default();
}
#[test]
fn init_with_new() {
let _queue: ArrayQueue<u8, 5> = ArrayQueue::new(5);
}
#[test]
fn default_create_default_values() {
let queue: ArrayQueue<u8, 2> = Default::default();
assert_eq!(queue.inner[0], 0);
assert_eq!(queue.inner[1], 0);
assert_eq!(queue.inner.len(), 2);
}
#[test]
fn new_create_default_values() {
let queue: ArrayQueue<u8, 2> = ArrayQueue::new(5);
assert_eq!(queue.inner[0], 5);
assert_eq!(queue.inner[1], 5);
assert_eq!(queue.inner.len(), 2);
}
#[test]
fn new_queue_is_empty() {
let queue: ArrayQueue<u8, 5> = Default::default();
assert!(queue.is_empty());
}
#[test]
#[should_panic]
fn push_too_much() {
let mut queue: ArrayQueue<u8, 10> = Default::default();
for _ in 0..100 {
queue.push(1).unwrap();
}
}
#[test]
fn basic_len() {
let mut queue: ArrayQueue<u8, 10> = Default::default();
assert_eq!(queue.len(), 0);
queue.push(1).unwrap();
assert_eq!(queue.len(), 1);
let _ = queue.pop();
assert_eq!(queue.len(), 0);
}
#[test]
fn basic_push() {
let mut queue: ArrayQueue<u8, 10> = Default::default();
queue.push(255).unwrap();
assert_eq!(queue.inner[0], 255);
}
#[test]
fn basic_pop() {
let mut queue: ArrayQueue<u8, 10> = Default::default();
queue.push(255).unwrap();
let left = queue.pop();
assert_eq!(left, Some(&255));
assert_eq!(queue.inner[0], 255);
}
}