158 lines
3.2 KiB
Rust
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);
|
|
}
|
|
}
|