use core::fmt;
use crate::queues::elastic::Elastic;
use crate::queues::Queue;
pub struct UnboundedElastic<T> {
inner: Elastic<T>,
}
impl<T> UnboundedElastic<T> {
pub(crate) fn new(initialise_memory: fn() -> T) -> Self {
Self {
inner: Elastic::new(1, usize::MAX, initialise_memory),
}
}
}
impl<T> Queue for UnboundedElastic<T> {
type Item = T;
fn len(&self) -> usize {
self.inner.len()
}
fn is_full(&self) -> bool {
false
}
fn max_capacity(&self) -> Option<usize> {
None
}
fn enqueue(&mut self, item: T) -> Option<T> {
self.inner.enqueue(item)
}
async fn expose_slots<F, R>(&mut self, f: F) -> R
where
F: AsyncFnOnce(&mut [T]) -> (usize, R),
{
self.inner.expose_slots(f).await
}
fn dequeue(&mut self) -> Option<T> {
self.inner.dequeue()
}
async fn expose_items<F, R>(&mut self, f: F) -> R
where
F: AsyncFnOnce(&[T]) -> (usize, R),
{
self.inner.expose_items(f).await
}
}
impl<T: fmt::Debug> fmt::Debug for UnboundedElastic<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("UnboundedElastic")
.field("len", &self.len())
.field("data", &DataDebugger(self))
.finish()
}
}
struct DataDebugger<'q, T>(&'q UnboundedElastic<T>);
impl<T: fmt::Debug> fmt::Debug for DataDebugger<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut list = f.debug_list();
for item in self.0.inner.buffer.iter().take(self.0.len()) {
list.entry(item);
}
list.finish()
}
}
#[cfg(test)]
mod tests {
extern crate alloc;
use super::*;
use crate::queues::QueueExt;
use alloc::format;
#[test]
fn enqueues_and_dequeues_with_correct_amount() {
let mut queue: UnboundedElastic<u8> = UnboundedElastic::new(Default::default);
assert_eq!(queue.enqueue(2), None);
assert_eq!(queue.enqueue(3), None);
assert_eq!(queue.enqueue(5), None);
assert_eq!(queue.enqueue(7), None);
assert_eq!(queue.len(), 4);
assert_eq!(queue.enqueue(11), None);
assert_eq!(queue.len(), 5);
assert_eq!(queue.enqueue(13), None);
assert_eq!(queue.dequeue(), Some(2));
assert_eq!(queue.len(), 5);
assert_eq!(queue.enqueue(13), None);
}
#[test]
fn returns_none_on_dequeue_when_queue_is_empty() {
let mut queue: UnboundedElastic<u8> = UnboundedElastic::new(Default::default);
queue.enqueue(2);
queue.dequeue();
assert!(queue.dequeue().is_none());
}
#[test]
fn bulk_enqueues_and_dequeues_with_correct_amount() {
pollster::block_on(async {
let mut queue: UnboundedElastic<u8> = UnboundedElastic::new(Default::default);
let mut buf = [0; 8];
let enqueue_amount = queue.bulk_enqueue(b"ufotofu").await;
let dequeue_amount = queue.bulk_dequeue(&mut buf).await;
assert_eq!(enqueue_amount, dequeue_amount);
})
}
#[test]
fn test_debug_impl() {
let mut queue: UnboundedElastic<u8> = UnboundedElastic::new(Default::default);
assert_eq!(queue.enqueue(2), None);
assert_eq!(queue.enqueue(3), None);
assert_eq!(queue.enqueue(5), None);
assert_eq!(
format!("{queue:?}"),
"UnboundedElastic { len: 3, data: [2, 3, 5] }"
);
assert_eq!(queue.dequeue(), Some(2));
assert_eq!(
format!("{queue:?}"),
"UnboundedElastic { len: 2, data: [3, 5] }"
);
assert_eq!(queue.dequeue(), Some(3));
assert_eq!(
format!("{queue:?}"),
"UnboundedElastic { len: 1, data: [5] }"
);
assert_eq!(queue.enqueue(7), None);
assert_eq!(
format!("{queue:?}"),
"UnboundedElastic { len: 2, data: [5, 7] }"
);
assert_eq!(queue.enqueue(11), None);
assert_eq!(queue.enqueue(13), None);
assert_eq!(queue.enqueue(17), None);
assert_eq!(
format!("{queue:?}"),
"UnboundedElastic { len: 5, data: [5, 7, 11, 13, 17] }"
);
}
}