use std::collections::VecDeque;
use crate::core::types::MsgId;
use super::message::Msg;
#[derive(Debug, Default)]
pub struct MsgQueue {
inner: VecDeque<Msg>,
}
impl<'a> IntoIterator for &'a MsgQueue {
type Item = &'a Msg;
type IntoIter = std::collections::vec_deque::Iter<'a, Msg>;
fn into_iter(self) -> Self::IntoIter {
self.inner.iter()
}
}
impl MsgQueue {
#[must_use]
pub fn new() -> Self {
Self {
inner: VecDeque::new(),
}
}
#[must_use]
pub fn with_capacity(n: usize) -> Self {
Self {
inner: VecDeque::with_capacity(n),
}
}
pub fn push_back(&mut self, msg: Msg) {
self.inner.push_back(msg);
}
pub fn push_front(&mut self, msg: Msg) {
self.inner.push_front(msg);
}
pub fn pop_front(&mut self) -> Option<Msg> {
self.inner.pop_front()
}
pub fn pop_back(&mut self) -> Option<Msg> {
self.inner.pop_back()
}
#[must_use]
pub fn len(&self) -> usize {
self.inner.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
#[must_use]
pub fn front(&self) -> Option<&Msg> {
self.inner.front()
}
pub fn front_mut(&mut self) -> Option<&mut Msg> {
self.inner.front_mut()
}
pub fn iter(&self) -> std::collections::vec_deque::Iter<'_, Msg> {
self.inner.iter()
}
#[must_use]
pub fn msg_get_id_lookup(&self, id: MsgId) -> Option<&Msg> {
self.inner.iter().find(|m| m.id() == id)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::msg::{Msg, MsgType};
#[test]
fn fifo_order() {
let mut q = MsgQueue::new();
for i in 1..=3 {
q.push_back(Msg::new(i, MsgType::ReqRedisGet, true));
}
assert_eq!(q.pop_front().unwrap().id(), 1);
assert_eq!(q.pop_front().unwrap().id(), 2);
assert_eq!(q.pop_front().unwrap().id(), 3);
assert!(q.is_empty());
}
#[test]
fn lookup_finds_by_id() {
let mut q = MsgQueue::new();
q.push_back(Msg::new(11, MsgType::ReqRedisGet, true));
q.push_back(Msg::new(22, MsgType::ReqRedisSet, true));
assert_eq!(q.msg_get_id_lookup(22).unwrap().id(), 22);
assert!(q.msg_get_id_lookup(33).is_none());
}
}