ferroui_base/utilities/
single_or_queue.rs1use std::collections::VecDeque;
2
3pub struct SingleOrQueue<T> {
5 head: Option<T>,
6 tail: Option<VecDeque<T>>,
7 empty: bool,
8}
9
10impl<T> Default for SingleOrQueue<T> {
11 fn default() -> Self {
12 Self::new()
13 }
14}
15
16impl<T> SingleOrQueue<T> {
17 pub fn new() -> Self {
18 Self { head: None, tail: None, empty: true }
19 }
20
21 fn tail(&mut self) -> &mut VecDeque<T> {
22 self.tail.get_or_insert_with(VecDeque::new)
23 }
24
25 fn has_tail(&self) -> bool {
26 self.tail.is_some()
27 }
28
29 pub fn empty(&self) -> bool {
30 self.empty
31 }
32
33 pub fn enqueue(&mut self, value: T) {
34 if self.empty {
35 self.head = Some(value);
36 } else {
37 self.tail().push_back(value);
38 }
39
40 self.empty = false;
41 }
42
43 pub fn dequeue(&mut self) -> T {
45 if self.empty {
46 panic!("Cannot dequeue from an empty queue!");
47 }
48
49 let result = self.head.take();
50
51 if self.has_tail() && !self.tail().is_empty() {
52 self.head = self.tail().pop_front();
53 } else {
54 self.head = None;
55 self.empty = true;
56 }
57
58 match result {
59 Some(result) => result,
60 None => unreachable!("a queue that is not empty has a head"),
61 }
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn new_single_or_queue_is_empty() {
71 assert!(SingleOrQueue::<String>::new().empty());
72 }
73
74 #[test]
75 #[should_panic(expected = "Cannot dequeue from an empty queue!")]
76 fn dequeue_throws_when_empty() {
77 let mut queue = SingleOrQueue::<String>::new();
78
79 queue.dequeue();
80 }
81
82 #[test]
83 fn enqueue_adds_element() {
84 let mut queue = SingleOrQueue::<i32>::new();
85
86 queue.enqueue(1);
87
88 assert!(!queue.empty());
89
90 assert_eq!(1, queue.dequeue());
91 }
92
93 #[test]
94 fn multiple_elements_dequeued_in_correct_order() {
95 let mut queue = SingleOrQueue::<i32>::new();
96
97 queue.enqueue(1);
98 queue.enqueue(2);
99 queue.enqueue(3);
100 assert_eq!(1, queue.dequeue());
101 assert_eq!(2, queue.dequeue());
102 assert_eq!(3, queue.dequeue());
103 }
104}