use std::collections::VecDeque;
use bitfold_protocol::command::ProtocolCommand;
#[derive(Debug)]
pub struct CommandQueue {
commands: VecDeque<ProtocolCommand>,
max_queue_size: usize,
}
impl CommandQueue {
pub fn new(capacity: usize) -> Self {
Self { commands: VecDeque::with_capacity(capacity), max_queue_size: capacity }
}
pub fn enqueue(&mut self, command: ProtocolCommand) -> bool {
self.commands.push_back(command);
self.commands.len() >= self.max_queue_size
}
pub fn len(&self) -> usize {
self.commands.len()
}
pub fn is_empty(&self) -> bool {
self.commands.is_empty()
}
pub fn drain(&mut self) -> impl Iterator<Item = ProtocolCommand> + '_ {
self.commands.drain(..)
}
pub fn iter(&self) -> impl Iterator<Item = &ProtocolCommand> {
self.commands.iter()
}
pub fn clear(&mut self) {
self.commands.clear();
}
}
impl Default for CommandQueue {
fn default() -> Self {
Self::new(256)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_queue_basic_operations() {
let mut queue = CommandQueue::new(3);
assert!(queue.is_empty());
assert_eq!(queue.len(), 0);
queue.enqueue(ProtocolCommand::Ping { timestamp: 100 });
assert_eq!(queue.len(), 1);
assert!(!queue.is_empty());
}
#[test]
fn test_queue_max_size_trigger() {
let mut queue = CommandQueue::new(2);
assert!(!queue.enqueue(ProtocolCommand::Ping { timestamp: 100 }));
assert!(queue.enqueue(ProtocolCommand::Ping { timestamp: 200 }));
assert_eq!(queue.len(), 2);
}
#[test]
fn test_queue_drain() {
let mut queue = CommandQueue::new(10);
queue.enqueue(ProtocolCommand::Ping { timestamp: 100 });
queue.enqueue(ProtocolCommand::Disconnect { reason: 0 });
let commands: Vec<_> = queue.drain().collect();
assert_eq!(commands.len(), 2);
assert!(queue.is_empty());
}
#[test]
fn test_queue_command_aggregation() {
let mut queue = CommandQueue::new(10);
queue.enqueue(ProtocolCommand::SendReliable {
channel_id: 0,
sequence: 1,
ordered: true,
data: vec![1, 2, 3].into(),
});
queue.enqueue(ProtocolCommand::Acknowledge {
sequence: 5,
received_mask: 0xFF,
sent_time: Some(1000),
});
queue.enqueue(ProtocolCommand::Ping { timestamp: 2000 });
assert_eq!(queue.len(), 3);
let commands: Vec<_> = queue.drain().collect();
assert_eq!(commands.len(), 3);
assert!(queue.is_empty());
}
#[test]
fn test_queue_iter() {
let mut queue = CommandQueue::new(10);
queue.enqueue(ProtocolCommand::Ping { timestamp: 100 });
queue.enqueue(ProtocolCommand::Pong { timestamp: 200 });
let count = queue.iter().count();
assert_eq!(count, 2);
assert_eq!(queue.len(), 2); }
}