1use std::collections::VecDeque;
40use std::fmt::{Debug, Display, Formatter};
41use tick_id::TickId;
42
43#[derive(Debug, PartialEq, Eq, Clone)]
44pub struct ItemInfo<T> {
45 pub item: T,
46 pub tick_id: TickId,
47}
48
49impl<T: Display> Display for ItemInfo<T> {
50 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
51 write!(f, "{}: {}", self.tick_id, self.item)
52 }
53}
54
55#[derive(Debug)]
56pub struct Queue<T> {
57 items: VecDeque<ItemInfo<T>>,
58 expected_write_id: TickId, }
60
61impl<T> Default for Queue<T> {
62 fn default() -> Self {
63 Self {
64 items: VecDeque::default(),
65 expected_write_id: TickId::default(),
66 }
67 }
68}
69
70impl<T> Queue<T> {
71 pub fn iter(&self) -> impl Iterator<Item = &ItemInfo<T>> {
72 self.items.iter()
73 }
74}
75
76impl<T> IntoIterator for Queue<T> {
77 type Item = ItemInfo<T>;
78 type IntoIter = std::collections::vec_deque::IntoIter<ItemInfo<T>>;
79
80 fn into_iter(self) -> Self::IntoIter {
85 self.items.into_iter()
86 }
87}
88
89pub struct FromIndexIterator<'a, T> {
90 deque: &'a VecDeque<ItemInfo<T>>,
91 #[allow(unused)]
92 start_index: usize,
93 current_index: usize,
94}
95
96impl<'a, T> FromIndexIterator<'a, T> {
97 #[must_use]
98 pub const fn new(deque: &'a VecDeque<ItemInfo<T>>, start_index: usize) -> Self {
99 Self {
100 deque,
101 start_index,
102 current_index: start_index,
103 }
104 }
105}
106
107impl<T: Clone> Iterator for FromIndexIterator<'_, T> {
108 type Item = ItemInfo<T>;
109
110 fn next(&mut self) -> Option<Self::Item> {
111 let item = self.deque.get(self.current_index)?;
112 self.current_index += 1;
113 Some(item.clone())
114 }
115}
116
117pub const TICK_ID_MAX: u32 = u32::MAX;
118
119#[derive(Debug)]
120pub enum QueueError {
121 WrongTickId {
122 expected: TickId,
123 encountered: TickId,
124 },
125}
126
127impl<T: Clone> Queue<T> {
128 #[must_use]
129 pub const fn new(tick_id: TickId) -> Self {
130 Self {
131 items: VecDeque::new(),
132 expected_write_id: tick_id,
133 }
134 }
135
136 pub fn clear(&mut self, initial_tick_id: TickId) {
138 self.items.clear();
139 self.expected_write_id = initial_tick_id;
140 }
141
142 pub fn push(&mut self, tick_id: TickId, item: T) -> Result<(), QueueError> {
160 if self.expected_write_id != tick_id {
161 Err(QueueError::WrongTickId {
162 expected: self.expected_write_id,
163 encountered: tick_id,
164 })?;
165 }
166
167 self.push_internal(item);
168
169 Ok(())
170 }
171
172 fn push_internal(&mut self, item: T) {
173 let info = ItemInfo {
174 item,
175 tick_id: self.expected_write_id,
176 };
177 self.items.push_back(info);
178 self.expected_write_id += 1;
179 }
180
181 #[must_use]
182 pub fn debug_get(&self, index: usize) -> Option<&ItemInfo<T>> {
183 self.items.get(index)
184 }
185
186 #[must_use]
187 pub fn pop(&mut self) -> Option<ItemInfo<T>> {
188 self.items.pop_front()
189 }
190
191 pub fn discard_up_to(&mut self, tick_id: TickId) {
192 while let Some(info) = self.items.front() {
193 if info.tick_id >= tick_id {
194 break;
195 }
196
197 self.items.pop_front();
198 }
199
200 if self.is_empty() {
201 self.expected_write_id = tick_id + 1;
202 }
203 }
204
205 pub fn discard_count(&mut self, count: usize) {
206 if count >= self.items.len() {
207 self.items.clear();
208 } else {
209 self.items.drain(..count);
210 }
211 }
212
213 #[must_use]
239 pub fn take(&mut self, count: usize) -> Option<(TickId, Vec<T>)> {
240 let first_tick_id = self.front_tick_id()?;
241
242 let items_to_take: Vec<T> = self
243 .items
244 .drain(..count.min(self.items.len()))
245 .map(|item_info| item_info.item)
246 .collect();
247
248 Some((first_tick_id, items_to_take))
249 }
250
251 #[must_use]
252 pub fn front_tick_id(&self) -> Option<TickId> {
253 self.items.front().map(|item_info| item_info.tick_id)
254 }
255
256 #[must_use]
257 pub const fn expected_write_tick_id(&self) -> TickId {
258 self.expected_write_id
259 }
260
261 #[must_use]
262 pub fn back_tick_id(&self) -> Option<TickId> {
263 self.items.back().map(|item_info| item_info.tick_id)
264 }
265
266 #[must_use]
267 pub fn len(&self) -> usize {
268 self.items.len()
269 }
270
271 #[must_use]
272 pub fn is_empty(&self) -> bool {
273 self.items.is_empty()
274 }
275
276 #[must_use]
277 pub fn to_vec(&self) -> Vec<T> {
278 let (front_slice, back_slice) = self.items.as_slices();
279 front_slice
280 .iter()
281 .chain(back_slice.iter())
282 .map(|item_info| item_info.item.clone())
283 .collect()
284 }
285
286 #[must_use]
287 pub const fn iter_index(&self, start_index: usize) -> FromIndexIterator<T> {
288 FromIndexIterator::new(&self.items, start_index)
289 }
290}