use crossbeam_queue::ArrayQueue;
pub struct CBuf<T> {
inner: ArrayQueue<T>,
}
impl<T> CBuf<T> {
pub fn new(capacity: usize) -> Self {
Self {
inner: ArrayQueue::new(capacity),
}
}
pub fn capacity(&self) -> usize {
self.inner.capacity()
}
pub fn push(&self, item: T) -> Result<(), T> {
self.inner.push(item)
}
pub fn pop(&self) -> Option<T> {
self.inner.pop()
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn is_full(&self) -> bool {
self.inner.is_full()
}
}
impl<T> std::fmt::Debug for CBuf<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("CBuf")
.field("capacity", &self.inner.capacity())
.field("len", &self.inner.len())
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn push_pop_fifo_ordering() {
let q: CBuf<u32> = CBuf::new(8);
for i in 0..8u32 {
q.push(i).unwrap();
}
assert!(q.is_full());
for i in 0..8u32 {
assert_eq!(q.pop(), Some(i));
}
assert!(q.is_empty());
}
#[test]
fn push_returns_item_on_full() {
let q: CBuf<u32> = CBuf::new(2);
q.push(1).unwrap();
q.push(2).unwrap();
assert_eq!(q.push(3), Err(3));
}
#[test]
fn pop_returns_none_on_empty() {
let q: CBuf<u32> = CBuf::new(2);
assert_eq!(q.pop(), None);
}
#[test]
fn capacity_reports_initial_size() {
let q: CBuf<u32> = CBuf::new(13);
assert_eq!(q.capacity(), 13);
}
}