use std::collections::VecDeque;
#[derive(Debug)]
pub struct TxQueue<T> {
inner: VecDeque<T>,
buffered_size: usize,
}
impl<T: TxQueueItem> TxQueue<T> {
pub fn new() -> Self {
Self { inner: VecDeque::new(), buffered_size: 0 }
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn buffered_size(&self) -> usize {
self.buffered_size
}
pub fn peek(&self) -> Option<&T> {
self.inner.front()
}
pub fn enqueue(&mut self, item: T) {
let size = item.buffered_size();
self.inner.push_back(item);
self.buffered_size += size;
}
pub fn dequeue(&mut self) -> Option<T> {
let item = self.inner.pop_front()?;
let size = item.buffered_size();
self.buffered_size -= size;
return Some(item);
}
pub fn trim(&mut self, target_buffer_size: usize) {
while self.buffered_size > target_buffer_size {
_ = self.dequeue()
}
}
}
pub trait TxQueueItem {
fn buffered_size(&self) -> usize;
}
impl TxQueueItem for Vec<u8> {
fn buffered_size(&self) -> usize {
self.len()
}
}
#[cfg(test)]
mod tests {
use super::TxQueue;
#[test]
fn test_buffered_size() {
let mut queue = TxQueue::new();
queue.enqueue(vec![0xFF, 0xFA]);
assert_eq!(queue.buffered_size(), 2);
queue.enqueue(vec![0x0F, 0xFC, 0xAF]);
assert_eq!(queue.buffered_size(), 5);
assert_eq!(queue.dequeue(), Some(vec![0xFF, 0xFA]));
assert_eq!(queue.buffered_size, 3);
assert_eq!(queue.dequeue(), Some(vec![0x0F, 0xFC, 0xAF]));
assert_eq!(queue.buffered_size, 0);
assert_eq!(queue.dequeue(), None);
}
#[test]
fn test_trim() {
let mut queue = TxQueue::new();
queue.enqueue(vec![0xFF, 0xFA]);
queue.enqueue(vec![0x0F, 0xFC, 0xAF]);
queue.enqueue(vec![0xAA]);
queue.trim(1);
assert_eq!(queue.buffered_size(), 1);
}
}