use std::collections::VecDeque;
use std::sync::{Arc, Mutex};
use crate::message::Message;
#[derive(Clone, Default)]
pub struct InputQueue(Arc<Mutex<VecDeque<Message>>>);
impl InputQueue {
pub fn new() -> Self {
Self::default()
}
pub fn push(&self, message: Message) {
self.0
.lock()
.unwrap_or_else(|error| error.into_inner())
.push_back(message);
}
pub fn is_empty(&self) -> bool {
self.0
.lock()
.unwrap_or_else(|error| error.into_inner())
.is_empty()
}
pub fn drain(&self) -> Vec<Message> {
self.0
.lock()
.unwrap_or_else(|error| error.into_inner())
.drain(..)
.collect()
}
}
impl std::fmt::Debug for InputQueue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("InputQueue")
.field("queued", &self.0.lock().map(|q| q.len()).unwrap_or(0))
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn clones_share_one_queue() {
let queue = InputQueue::new();
let handle = queue.clone();
assert!(queue.is_empty());
handle.push(Message::user("first"));
handle.push(Message::user("second"));
assert!(!queue.is_empty());
let drained = queue.drain();
assert_eq!(drained.len(), 2);
assert_eq!(drained[0].text(), "first");
assert_eq!(drained[1].text(), "second");
assert!(handle.is_empty(), "draining one clone drains them all");
}
#[test]
fn a_queue_nobody_is_draining_keeps_its_messages() {
let queue = InputQueue::new();
queue.push(Message::user("held"));
assert_eq!(queue.drain().len(), 1);
}
}