1use core::marker::PhantomData;
2
3use super::{
4 source::{CurrentStorage, StorageAddress},
5 StorageClearable, StorageMapper, StorageMapperFromAddress,
6};
7use crate::{
8 abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName},
9 api::StorageMapperApi,
10 codec::{
11 self,
12 derive::{TopDecode, TopDecodeOrDefault, TopEncode, TopEncodeOrDefault},
13 multi_encode_iter_or_handle_err, DecodeDefault, EncodeDefault, EncodeErrorHandler,
14 TopDecode, TopEncode, TopEncodeMulti, TopEncodeMultiOutput,
15 },
16 storage::{storage_set, StorageKey},
17 types::{ManagedAddress, ManagedType, MultiValueEncoded},
18};
19use alloc::vec::Vec;
20
21const NULL_ENTRY: u32 = 0;
22const INFO_IDENTIFIER: &[u8] = b".info";
23const NODE_IDENTIFIER: &[u8] = b".node_links";
24const VALUE_IDENTIFIER: &[u8] = b".value";
25
26#[derive(TopEncode, TopDecode, PartialEq, Eq, Clone, Copy)]
27pub struct Node {
28 pub previous: u32,
29 pub next: u32,
30}
31
32#[derive(TopEncodeOrDefault, TopDecodeOrDefault, PartialEq, Eq, Clone, Copy)]
33pub struct QueueMapperInfo {
34 pub len: u32,
35 pub front: u32,
36 pub back: u32,
37 pub new: u32,
38}
39
40impl EncodeDefault for QueueMapperInfo {
41 fn is_default(&self) -> bool {
42 self.len == 0
43 }
44}
45
46impl DecodeDefault for QueueMapperInfo {
47 fn default() -> Self {
48 Self {
49 len: 0,
50 front: 0,
51 back: 0,
52 new: 0,
53 }
54 }
55}
56
57impl QueueMapperInfo {
58 pub fn generate_new_node_id(&mut self) -> u32 {
59 self.new += 1;
60 self.new
61 }
62}
63
64pub struct QueueMapper<SA, T, A = CurrentStorage>
69where
70 SA: StorageMapperApi,
71 A: StorageAddress<SA>,
72 T: TopEncode + TopDecode + 'static,
73{
74 _phantom_api: PhantomData<SA>,
75 address: A,
76 base_key: StorageKey<SA>,
77 _phantom_item: PhantomData<T>,
78}
79
80impl<SA, T> StorageMapper<SA> for QueueMapper<SA, T, CurrentStorage>
81where
82 SA: StorageMapperApi,
83 T: TopEncode + TopDecode,
84{
85 fn new(base_key: StorageKey<SA>) -> Self {
86 QueueMapper {
87 _phantom_api: PhantomData,
88 address: CurrentStorage,
89 base_key,
90 _phantom_item: PhantomData,
91 }
92 }
93}
94
95impl<SA, T> StorageClearable for QueueMapper<SA, T, CurrentStorage>
96where
97 SA: StorageMapperApi,
98 T: TopEncode + TopDecode,
99{
100 fn clear(&mut self) {
101 let info = self.get_info();
102 let mut node_id = info.front;
103 while node_id != NULL_ENTRY {
104 let node = self.get_node(node_id);
105 self.clear_node(node_id);
106 self.clear_value(node_id);
107 node_id = node.next;
108 }
109 self.set_info(QueueMapperInfo::default());
110 }
111}
112
113impl<SA, T> QueueMapper<SA, T, CurrentStorage>
114where
115 SA: StorageMapperApi,
116 T: TopEncode + TopDecode,
117{
118 fn set_info(&mut self, value: QueueMapperInfo) {
119 storage_set(self.build_name_key(INFO_IDENTIFIER).as_ref(), &value);
120 }
121
122 fn set_node(&mut self, node_id: u32, item: Node) {
123 storage_set(
124 self.build_node_id_named_key(NODE_IDENTIFIER, node_id)
125 .as_ref(),
126 &item,
127 );
128 }
129
130 fn clear_node(&mut self, node_id: u32) {
131 storage_set(
132 self.build_node_id_named_key(NODE_IDENTIFIER, node_id)
133 .as_ref(),
134 &codec::Empty,
135 );
136 }
137
138 fn set_value(&mut self, node_id: u32, value: &T) {
139 storage_set(
140 self.build_node_id_named_key(VALUE_IDENTIFIER, node_id)
141 .as_ref(),
142 value,
143 )
144 }
145
146 fn clear_value(&mut self, node_id: u32) {
147 storage_set(
148 self.build_node_id_named_key(VALUE_IDENTIFIER, node_id)
149 .as_ref(),
150 &codec::Empty,
151 )
152 }
153
154 pub(crate) fn push_back_node_id(&mut self, elt: &T) -> u32 {
159 let mut info = self.get_info();
160 let new_node_id = info.generate_new_node_id();
161 let mut previous = NULL_ENTRY;
162 if info.len == 0 {
163 info.front = new_node_id;
164 } else {
165 let back = info.back;
166 let mut back_node = self.get_node(back);
167 back_node.next = new_node_id;
168 previous = back;
169 self.set_node(back, back_node);
170 }
171 self.set_node(
172 new_node_id,
173 Node {
174 previous,
175 next: NULL_ENTRY,
176 },
177 );
178 info.back = new_node_id;
179 self.set_value(new_node_id, elt);
180 info.len += 1;
181 self.set_info(info);
182 new_node_id
183 }
184
185 pub fn push_back(&mut self, elt: T) {
189 let _ = self.push_back_node_id(&elt);
190 }
191
192 pub fn push_front(&mut self, elt: T) {
196 let mut info = self.get_info();
197 let new_node_id = info.generate_new_node_id();
198 let mut next = NULL_ENTRY;
199 if info.len == 0 {
200 info.back = new_node_id;
201 } else {
202 let front = info.front;
203 let mut front_node = self.get_node(front);
204 front_node.previous = new_node_id;
205 next = front;
206 self.set_node(front, front_node);
207 }
208 self.set_node(
209 new_node_id,
210 Node {
211 previous: NULL_ENTRY,
212 next,
213 },
214 );
215 info.front = new_node_id;
216 self.set_value(new_node_id, &elt);
217 info.len += 1;
218 self.set_info(info);
219 }
220
221 pub fn pop_back(&mut self) -> Option<T> {
226 self.remove_by_node_id(self.get_info().back)
227 }
228
229 pub fn pop_front(&mut self) -> Option<T> {
234 self.remove_by_node_id(self.get_info().front)
235 }
236
237 pub(crate) fn remove_by_node_id(&mut self, node_id: u32) -> Option<T> {
243 if node_id == NULL_ENTRY {
244 return None;
245 }
246 let node = self.get_node(node_id);
247
248 let mut info = self.get_info();
249 if node.previous == NULL_ENTRY {
250 info.front = node.next;
251 } else {
252 let mut previous = self.get_node(node.previous);
253 previous.next = node.next;
254 self.set_node(node.previous, previous);
255 }
256
257 if node.next == NULL_ENTRY {
258 info.back = node.previous;
259 } else {
260 let mut next = self.get_node(node.next);
261 next.previous = node.previous;
262 self.set_node(node.next, next);
263 }
264
265 self.clear_node(node_id);
266 let removed_value = self.get_value(node_id);
267 self.clear_value(node_id);
268 info.len -= 1;
269 self.set_info(info);
270 Some(removed_value)
271 }
272}
273
274impl<SA, T> StorageMapperFromAddress<SA> for QueueMapper<SA, T, ManagedAddress<SA>>
275where
276 SA: StorageMapperApi,
277 T: TopEncode + TopDecode,
278{
279 fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
280 QueueMapper {
281 _phantom_api: PhantomData::<SA>,
282 address,
283 base_key,
284 _phantom_item: PhantomData::<T>,
285 }
286 }
287}
288
289impl<SA, A, T> QueueMapper<SA, T, A>
290where
291 SA: StorageMapperApi,
292 A: StorageAddress<SA>,
293 T: TopEncode + TopDecode + 'static,
294{
295 fn build_node_id_named_key(&self, name: &[u8], node_id: u32) -> StorageKey<SA> {
296 let mut named_key = self.base_key.clone();
297 named_key.append_bytes(name);
298 named_key.append_item(&node_id);
299 named_key
300 }
301
302 fn build_name_key(&self, name: &[u8]) -> StorageKey<SA> {
303 let mut name_key = self.base_key.clone();
304 name_key.append_bytes(name);
305 name_key
306 }
307
308 pub fn iter(&self) -> Iter<'_, SA, A, T> {
309 Iter::new(self)
310 }
311
312 pub fn iter_from_node_id(&self, node_id: u32) -> Iter<'_, SA, A, T> {
313 Iter::new_from_node_id(self, node_id)
314 }
315
316 fn get_info(&self) -> QueueMapperInfo {
317 self.address
318 .address_storage_get(self.build_name_key(INFO_IDENTIFIER).as_ref())
319 }
320
321 pub fn get_node(&self, node_id: u32) -> Node {
322 self.address.address_storage_get(
323 self.build_node_id_named_key(NODE_IDENTIFIER, node_id)
324 .as_ref(),
325 )
326 }
327
328 fn get_value(&self, node_id: u32) -> T {
329 self.address.address_storage_get(
330 self.build_node_id_named_key(VALUE_IDENTIFIER, node_id)
331 .as_ref(),
332 )
333 }
334
335 pub fn get_value_option(&self, node_id: u32) -> Option<T> {
336 if node_id == NULL_ENTRY {
337 return None;
338 }
339 Some(self.get_value(node_id))
340 }
341
342 pub fn is_empty(&self) -> bool {
346 self.get_info().len == 0
347 }
348
349 pub fn len(&self) -> usize {
353 self.get_info().len as usize
354 }
355
356 pub fn front(&self) -> Option<T> {
359 self.get_value_option(self.get_info().front)
360 }
361
362 pub fn back(&self) -> Option<T> {
365 self.get_value_option(self.get_info().back)
366 }
367
368 pub fn check_internal_consistency(&self) -> bool {
374 let info = self.get_info();
375 let mut front = info.front;
376 let mut back = info.back;
377 if info.len == 0 {
378 if front != NULL_ENTRY {
380 return false;
381 }
382 if back != NULL_ENTRY {
383 return false;
384 }
385 true
386 } else {
387 if front == NULL_ENTRY {
389 return false;
390 }
391 if back == NULL_ENTRY {
392 return false;
393 }
394
395 if self.get_node(front).previous != NULL_ENTRY {
397 return false;
398 }
399 if self.get_node(back).next != NULL_ENTRY {
400 return false;
401 }
402
403 let mut forwards = Vec::new();
405 while front != NULL_ENTRY {
406 forwards.push(front);
407 front = self.get_node(front).next;
408 }
409 if forwards.len() != info.len as usize {
410 return false;
411 }
412
413 let mut backwards = Vec::new();
415 while back != NULL_ENTRY {
416 backwards.push(back);
417 back = self.get_node(back).previous;
418 }
419 if backwards.len() != info.len as usize {
420 return false;
421 }
422
423 let backwards_reversed: Vec<u32> = backwards.iter().rev().cloned().collect();
425 if forwards != backwards_reversed {
426 return false;
427 }
428
429 forwards.sort_unstable();
431 forwards.dedup();
432 if forwards.len() != info.len as usize {
433 return false;
434 }
435 true
436 }
437 }
438}
439
440impl<'a, SA, A, T> IntoIterator for &'a QueueMapper<SA, T, A>
441where
442 SA: StorageMapperApi,
443 A: StorageAddress<SA>,
444 T: TopEncode + TopDecode + 'static,
445{
446 type Item = T;
447
448 type IntoIter = Iter<'a, SA, A, T>;
449
450 fn into_iter(self) -> Self::IntoIter {
451 self.iter()
452 }
453}
454
455pub struct Iter<'a, SA, A, T>
460where
461 SA: StorageMapperApi,
462 A: StorageAddress<SA>,
463 T: TopEncode + TopDecode + 'static,
464{
465 node_id: u32,
466 queue: &'a QueueMapper<SA, T, A>,
467}
468
469impl<'a, SA, A, T> Iter<'a, SA, A, T>
470where
471 SA: StorageMapperApi,
472 A: StorageAddress<SA>,
473 T: TopEncode + TopDecode + 'static,
474{
475 fn new(queue: &'a QueueMapper<SA, T, A>) -> Iter<'a, SA, A, T> {
476 Iter {
477 node_id: queue.get_info().front,
478 queue,
479 }
480 }
481
482 pub fn new_from_node_id(queue: &'a QueueMapper<SA, T, A>, node_id: u32) -> Iter<'a, SA, A, T> {
483 Iter { node_id, queue }
484 }
485}
486
487impl<SA, A, T> Iterator for Iter<'_, SA, A, T>
488where
489 SA: StorageMapperApi,
490 A: StorageAddress<SA>,
491 T: TopEncode + TopDecode + 'static,
492{
493 type Item = T;
494
495 #[inline]
496 fn next(&mut self) -> Option<T> {
497 let current_node_id = self.node_id;
498 if current_node_id == NULL_ENTRY {
499 return None;
500 }
501 self.node_id = self.queue.get_node(current_node_id).next;
502 Some(self.queue.get_value(current_node_id))
503 }
504}
505
506impl<SA, T> TopEncodeMulti for QueueMapper<SA, T, CurrentStorage>
508where
509 SA: StorageMapperApi,
510 T: TopEncode + TopDecode,
511{
512 fn multi_encode_or_handle_err<O, H>(&self, output: &mut O, h: H) -> Result<(), H::HandledErr>
513 where
514 O: TopEncodeMultiOutput,
515 H: EncodeErrorHandler,
516 {
517 multi_encode_iter_or_handle_err(self.iter(), output, h)
518 }
519}
520
521impl<SA, T> TypeAbiFrom<QueueMapper<SA, T, CurrentStorage>> for MultiValueEncoded<SA, T>
522where
523 SA: StorageMapperApi,
524 T: TopEncode + TopDecode,
525{
526}
527
528impl<SA, T> TypeAbiFrom<Self> for QueueMapper<SA, T, CurrentStorage>
529where
530 SA: StorageMapperApi,
531 T: TopEncode + TopDecode,
532{
533}
534
535impl<SA, T> TypeAbi for QueueMapper<SA, T, CurrentStorage>
537where
538 SA: StorageMapperApi,
539 T: TopEncode + TopDecode + TypeAbi,
540{
541 type Unmanaged = Self;
542
543 fn type_name() -> TypeName {
544 crate::abi::type_name_variadic::<T>()
545 }
546
547 fn type_name_rust() -> TypeName {
548 crate::abi::type_name_multi_value_encoded::<T>()
549 }
550
551 fn provide_type_descriptions<TDC: TypeDescriptionContainer>(accumulator: &mut TDC) {
552 T::provide_type_descriptions(accumulator);
553 }
554
555 fn is_variadic() -> bool {
556 true
557 }
558}