1use std::collections::{BinaryHeap, VecDeque};
2
3#[derive(Debug, PartialEq, Eq, Clone, Copy)]
6pub struct PushError;
7
8impl std::fmt::Display for PushError {
9 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
10 write!(f, "queue reached its capacity")
11 }
12}
13
14impl std::error::Error for PushError {}
15
16pub trait Queue {
18 type Item;
20
21 fn push(&mut self, value: Self::Item) -> Result<(), PushError>;
27
28 fn pop(&mut self) -> Option<Self::Item>;
30
31 fn len(&self) -> usize;
33
34 fn is_empty(&self) -> bool {
36 self.len() == 0
37 }
38}
39
40pub struct Fifo<T> {
47 inner: VecDeque<T>,
48 capacity: usize,
49}
50
51impl<T> Default for Fifo<T> {
52 fn default() -> Self {
53 Self {
54 inner: VecDeque::default(),
55 capacity: usize::MAX,
56 }
57 }
58}
59
60impl<T> Fifo<T> {
61 #[must_use]
63 pub fn bounded(capacity: usize) -> Self {
64 Self {
65 inner: VecDeque::with_capacity(capacity),
66 capacity,
67 }
68 }
69}
70
71impl<T> Queue for Fifo<T> {
72 type Item = T;
73
74 fn push(&mut self, value: T) -> Result<(), PushError> {
75 if self.inner.len() < self.capacity {
76 self.inner.push_back(value);
77 Ok(())
78 } else {
79 Err(PushError)
80 }
81 }
82
83 fn pop(&mut self) -> Option<T> {
84 self.inner.pop_front()
85 }
86
87 fn len(&self) -> usize {
88 self.inner.len()
89 }
90}
91
92pub struct PriorityQueue<T> {
94 inner: BinaryHeap<T>,
95 capacity: usize,
96}
97
98impl<T: Ord> Default for PriorityQueue<T> {
99 fn default() -> Self {
100 Self {
101 inner: BinaryHeap::default(),
102 capacity: usize::MAX,
103 }
104 }
105}
106
107impl<T: Ord> PriorityQueue<T> {
108 #[must_use]
110 pub fn bounded(capacity: usize) -> Self {
111 Self {
112 inner: BinaryHeap::with_capacity(capacity),
113 capacity,
114 }
115 }
116}
117
118impl<T: Ord> Queue for PriorityQueue<T> {
119 type Item = T;
120
121 fn push(&mut self, value: T) -> Result<(), PushError> {
122 if self.inner.len() < self.capacity {
123 self.inner.push(value);
124 Ok(())
125 } else {
126 Err(PushError)
127 }
128 }
129
130 fn pop(&mut self) -> Option<T> {
131 self.inner.pop()
132 }
133
134 fn len(&self) -> usize {
135 self.inner.len()
136 }
137}
138
139#[cfg(test)]
140mod test {
141 use super::*;
142
143 #[test]
144 fn test_unbounded_queue() {
145 let mut queue = Fifo::<i32>::default();
146 assert_eq!(queue.len(), 0);
147 assert!(queue.is_empty());
148 assert!(queue.push(0).is_ok());
149 assert_eq!(queue.len(), 1);
150 assert!(!queue.is_empty());
151 assert!(queue.push(1).is_ok());
152 assert_eq!(queue.len(), 2);
153 assert_eq!(queue.pop(), Some(0));
154 assert_eq!(queue.len(), 1);
155 assert_eq!(queue.pop(), Some(1));
156 assert_eq!(queue.len(), 0);
157 assert_eq!(queue.pop(), None);
158 }
159
160 #[test]
161 fn test_bounded_queue() {
162 let mut queue = Fifo::<i32>::bounded(2);
163 assert_eq!(queue.len(), 0);
164 assert!(queue.is_empty());
165 assert!(queue.push(0).is_ok());
166 assert_eq!(queue.len(), 1);
167 assert!(!queue.is_empty());
168 assert!(queue.push(1).is_ok());
169 assert_eq!(queue.len(), 2);
170 let err = queue.push(2).err();
171 assert!(err.is_some());
172 let err = err.unwrap();
173 assert_eq!(&format!("{}", err), "queue reached its capacity");
174 assert_eq!(queue.pop(), Some(0));
175 assert_eq!(queue.len(), 1);
176 assert!(queue.push(2).is_ok());
177 assert_eq!(queue.len(), 2);
178 assert_eq!(queue.pop(), Some(1));
179 assert_eq!(queue.len(), 1);
180 assert_eq!(queue.pop(), Some(2));
181 assert_eq!(queue.len(), 0);
182 assert_eq!(queue.pop(), None);
183 }
184
185 #[test]
186 fn test_priority_queue() -> Result<(), PushError> {
187 let queue = PriorityQueue::<i32>::default();
188 assert_eq!(queue.capacity, usize::MAX);
189 let mut queue = PriorityQueue::<i32>::bounded(2);
190 assert_eq!(queue.capacity, 2);
191
192 assert_eq!(queue.len(), 0);
193 queue.push(1)?;
194 assert_eq!(queue.len(), 1);
195 queue.push(2)?;
196 assert_eq!(queue.len(), 2);
197
198 assert_eq!(queue.push(2).err(), Some(PushError));
199
200 assert_eq!(queue.len(), 2);
201 assert_eq!(queue.pop(), Some(2));
202 assert_eq!(queue.len(), 1);
203 assert_eq!(queue.pop(), Some(1));
204 assert_eq!(queue.len(), 0);
205
206 Ok(())
207 }
208}