1use core::marker::PhantomData;
2
3use super::{
4 StorageClearable, StorageMapper, StorageMapperFromAddress,
5 source::{CurrentStorage, StorageAddress},
6};
7use crate::{
8 abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName},
9 api::StorageMapperApi,
10 codec::{
11 self, DecodeDefault, EncodeDefault, EncodeErrorHandler, TopDecode, TopEncode,
12 TopEncodeMulti, TopEncodeMultiOutput,
13 derive::{TopDecode, TopDecodeOrDefault, TopEncode, TopEncodeOrDefault},
14 multi_encode_iter_or_handle_err,
15 },
16 storage::{StorageKey, storage_set},
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>
148where
149 SA: StorageMapperApi,
150 A: StorageAddress<SA>,
151 T: TopEncode + TopDecode + 'static,
152{
153 _phantom_api: PhantomData<SA>,
154 address: A,
155 base_key: StorageKey<SA>,
156 _phantom_item: PhantomData<T>,
157}
158
159impl<SA, T> StorageMapper<SA> for QueueMapper<SA, T, CurrentStorage>
160where
161 SA: StorageMapperApi,
162 T: TopEncode + TopDecode,
163{
164 fn new(base_key: StorageKey<SA>) -> Self {
165 QueueMapper {
166 _phantom_api: PhantomData,
167 address: CurrentStorage,
168 base_key,
169 _phantom_item: PhantomData,
170 }
171 }
172}
173
174impl<SA, T> StorageClearable for QueueMapper<SA, T, CurrentStorage>
175where
176 SA: StorageMapperApi,
177 T: TopEncode + TopDecode,
178{
179 fn clear(&mut self) {
180 let info = self.get_info();
181 let mut node_id = info.front;
182 while node_id != NULL_ENTRY {
183 let node = self.get_node(node_id);
184 self.clear_node(node_id);
185 self.clear_value(node_id);
186 node_id = node.next;
187 }
188 self.set_info(QueueMapperInfo::default());
189 }
190}
191
192impl<SA, T> QueueMapper<SA, T, CurrentStorage>
193where
194 SA: StorageMapperApi,
195 T: TopEncode + TopDecode,
196{
197 fn set_info(&mut self, value: QueueMapperInfo) {
198 storage_set(self.build_name_key(INFO_IDENTIFIER).as_ref(), &value);
199 }
200
201 fn set_node(&mut self, node_id: u32, item: Node) {
202 storage_set(
203 self.build_node_id_named_key(NODE_IDENTIFIER, node_id)
204 .as_ref(),
205 &item,
206 );
207 }
208
209 fn clear_node(&mut self, node_id: u32) {
210 storage_set(
211 self.build_node_id_named_key(NODE_IDENTIFIER, node_id)
212 .as_ref(),
213 &codec::Empty,
214 );
215 }
216
217 fn set_value(&mut self, node_id: u32, value: &T) {
218 storage_set(
219 self.build_node_id_named_key(VALUE_IDENTIFIER, node_id)
220 .as_ref(),
221 value,
222 )
223 }
224
225 fn clear_value(&mut self, node_id: u32) {
226 storage_set(
227 self.build_node_id_named_key(VALUE_IDENTIFIER, node_id)
228 .as_ref(),
229 &codec::Empty,
230 )
231 }
232
233 pub(crate) fn push_back_node_id(&mut self, elt: &T) -> u32 {
238 let mut info = self.get_info();
239 let new_node_id = info.generate_new_node_id();
240 let mut previous = NULL_ENTRY;
241 if info.len == 0 {
242 info.front = new_node_id;
243 } else {
244 let back = info.back;
245 let mut back_node = self.get_node(back);
246 back_node.next = new_node_id;
247 previous = back;
248 self.set_node(back, back_node);
249 }
250 self.set_node(
251 new_node_id,
252 Node {
253 previous,
254 next: NULL_ENTRY,
255 },
256 );
257 info.back = new_node_id;
258 self.set_value(new_node_id, elt);
259 info.len += 1;
260 self.set_info(info);
261 new_node_id
262 }
263
264 pub fn push_back(&mut self, elt: T) {
268 let _ = self.push_back_node_id(&elt);
269 }
270
271 pub fn push_front(&mut self, elt: T) {
275 let mut info = self.get_info();
276 let new_node_id = info.generate_new_node_id();
277 let mut next = NULL_ENTRY;
278 if info.len == 0 {
279 info.back = new_node_id;
280 } else {
281 let front = info.front;
282 let mut front_node = self.get_node(front);
283 front_node.previous = new_node_id;
284 next = front;
285 self.set_node(front, front_node);
286 }
287 self.set_node(
288 new_node_id,
289 Node {
290 previous: NULL_ENTRY,
291 next,
292 },
293 );
294 info.front = new_node_id;
295 self.set_value(new_node_id, &elt);
296 info.len += 1;
297 self.set_info(info);
298 }
299
300 pub fn pop_back(&mut self) -> Option<T> {
305 self.remove_by_node_id(self.get_info().back)
306 }
307
308 pub fn pop_front(&mut self) -> Option<T> {
313 self.remove_by_node_id(self.get_info().front)
314 }
315
316 pub(crate) fn remove_by_node_id(&mut self, node_id: u32) -> Option<T> {
322 if node_id == NULL_ENTRY {
323 return None;
324 }
325 let node = self.get_node(node_id);
326
327 let mut info = self.get_info();
328 if node.previous == NULL_ENTRY {
329 info.front = node.next;
330 } else {
331 let mut previous = self.get_node(node.previous);
332 previous.next = node.next;
333 self.set_node(node.previous, previous);
334 }
335
336 if node.next == NULL_ENTRY {
337 info.back = node.previous;
338 } else {
339 let mut next = self.get_node(node.next);
340 next.previous = node.previous;
341 self.set_node(node.next, next);
342 }
343
344 self.clear_node(node_id);
345 let removed_value = self.get_value(node_id);
346 self.clear_value(node_id);
347 info.len -= 1;
348 self.set_info(info);
349 Some(removed_value)
350 }
351}
352
353impl<SA, T> StorageMapperFromAddress<SA> for QueueMapper<SA, T, ManagedAddress<SA>>
354where
355 SA: StorageMapperApi,
356 T: TopEncode + TopDecode,
357{
358 fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
359 QueueMapper {
360 _phantom_api: PhantomData::<SA>,
361 address,
362 base_key,
363 _phantom_item: PhantomData::<T>,
364 }
365 }
366}
367
368impl<SA, A, T> QueueMapper<SA, T, A>
369where
370 SA: StorageMapperApi,
371 A: StorageAddress<SA>,
372 T: TopEncode + TopDecode + 'static,
373{
374 fn build_node_id_named_key(&self, name: &[u8], node_id: u32) -> StorageKey<SA> {
375 let mut named_key = self.base_key.clone();
376 named_key.append_bytes(name);
377 named_key.append_item(&node_id);
378 named_key
379 }
380
381 fn build_name_key(&self, name: &[u8]) -> StorageKey<SA> {
382 let mut name_key = self.base_key.clone();
383 name_key.append_bytes(name);
384 name_key
385 }
386
387 pub fn iter(&self) -> Iter<'_, SA, A, T> {
388 Iter::new(self)
389 }
390
391 pub fn iter_from_node_id(&self, node_id: u32) -> Iter<'_, SA, A, T> {
392 Iter::new_from_node_id(self, node_id)
393 }
394
395 fn get_info(&self) -> QueueMapperInfo {
396 self.address
397 .address_storage_get(self.build_name_key(INFO_IDENTIFIER).as_ref())
398 }
399
400 pub fn get_node(&self, node_id: u32) -> Node {
401 self.address.address_storage_get(
402 self.build_node_id_named_key(NODE_IDENTIFIER, node_id)
403 .as_ref(),
404 )
405 }
406
407 fn get_value(&self, node_id: u32) -> T {
408 self.address.address_storage_get(
409 self.build_node_id_named_key(VALUE_IDENTIFIER, node_id)
410 .as_ref(),
411 )
412 }
413
414 pub fn get_value_option(&self, node_id: u32) -> Option<T> {
415 if node_id == NULL_ENTRY {
416 return None;
417 }
418 Some(self.get_value(node_id))
419 }
420
421 pub fn is_empty(&self) -> bool {
425 self.get_info().len == 0
426 }
427
428 pub fn len(&self) -> usize {
432 self.get_info().len as usize
433 }
434
435 pub fn front(&self) -> Option<T> {
438 self.get_value_option(self.get_info().front)
439 }
440
441 pub fn back(&self) -> Option<T> {
444 self.get_value_option(self.get_info().back)
445 }
446
447 pub fn check_internal_consistency(&self) -> bool {
453 let info = self.get_info();
454 let mut front = info.front;
455 let mut back = info.back;
456 if info.len == 0 {
457 if front != NULL_ENTRY {
459 return false;
460 }
461 if back != NULL_ENTRY {
462 return false;
463 }
464 true
465 } else {
466 if front == NULL_ENTRY {
468 return false;
469 }
470 if back == NULL_ENTRY {
471 return false;
472 }
473
474 if self.get_node(front).previous != NULL_ENTRY {
476 return false;
477 }
478 if self.get_node(back).next != NULL_ENTRY {
479 return false;
480 }
481
482 let mut forwards = Vec::new();
484 while front != NULL_ENTRY {
485 forwards.push(front);
486 front = self.get_node(front).next;
487 }
488 if forwards.len() != info.len as usize {
489 return false;
490 }
491
492 let mut backwards = Vec::new();
494 while back != NULL_ENTRY {
495 backwards.push(back);
496 back = self.get_node(back).previous;
497 }
498 if backwards.len() != info.len as usize {
499 return false;
500 }
501
502 let backwards_reversed: Vec<u32> = backwards.iter().rev().cloned().collect();
504 if forwards != backwards_reversed {
505 return false;
506 }
507
508 forwards.sort_unstable();
510 forwards.dedup();
511 if forwards.len() != info.len as usize {
512 return false;
513 }
514 true
515 }
516 }
517}
518
519impl<'a, SA, A, T> IntoIterator for &'a QueueMapper<SA, T, A>
520where
521 SA: StorageMapperApi,
522 A: StorageAddress<SA>,
523 T: TopEncode + TopDecode + 'static,
524{
525 type Item = T;
526
527 type IntoIter = Iter<'a, SA, A, T>;
528
529 fn into_iter(self) -> Self::IntoIter {
530 self.iter()
531 }
532}
533
534pub struct Iter<'a, SA, A, T>
539where
540 SA: StorageMapperApi,
541 A: StorageAddress<SA>,
542 T: TopEncode + TopDecode + 'static,
543{
544 node_id: u32,
545 queue: &'a QueueMapper<SA, T, A>,
546}
547
548impl<'a, SA, A, T> Iter<'a, SA, A, T>
549where
550 SA: StorageMapperApi,
551 A: StorageAddress<SA>,
552 T: TopEncode + TopDecode + 'static,
553{
554 fn new(queue: &'a QueueMapper<SA, T, A>) -> Iter<'a, SA, A, T> {
555 Iter {
556 node_id: queue.get_info().front,
557 queue,
558 }
559 }
560
561 pub fn new_from_node_id(queue: &'a QueueMapper<SA, T, A>, node_id: u32) -> Iter<'a, SA, A, T> {
562 Iter { node_id, queue }
563 }
564}
565
566impl<SA, A, T> Iterator for Iter<'_, SA, A, T>
567where
568 SA: StorageMapperApi,
569 A: StorageAddress<SA>,
570 T: TopEncode + TopDecode + 'static,
571{
572 type Item = T;
573
574 #[inline]
575 fn next(&mut self) -> Option<T> {
576 let current_node_id = self.node_id;
577 if current_node_id == NULL_ENTRY {
578 return None;
579 }
580 self.node_id = self.queue.get_node(current_node_id).next;
581 Some(self.queue.get_value(current_node_id))
582 }
583}
584
585impl<SA, T> TopEncodeMulti for QueueMapper<SA, T, CurrentStorage>
587where
588 SA: StorageMapperApi,
589 T: TopEncode + TopDecode,
590{
591 fn multi_encode_or_handle_err<O, H>(&self, output: &mut O, h: H) -> Result<(), H::HandledErr>
592 where
593 O: TopEncodeMultiOutput,
594 H: EncodeErrorHandler,
595 {
596 multi_encode_iter_or_handle_err(self.iter(), output, h)
597 }
598}
599
600impl<SA, T> TypeAbiFrom<QueueMapper<SA, T, CurrentStorage>> for MultiValueEncoded<SA, T>
601where
602 SA: StorageMapperApi,
603 T: TopEncode + TopDecode,
604{
605}
606
607impl<SA, T> TypeAbiFrom<Self> for QueueMapper<SA, T, CurrentStorage>
608where
609 SA: StorageMapperApi,
610 T: TopEncode + TopDecode,
611{
612}
613
614impl<SA, T> TypeAbi for QueueMapper<SA, T, CurrentStorage>
616where
617 SA: StorageMapperApi,
618 T: TopEncode + TopDecode + TypeAbi,
619{
620 type Unmanaged = Self;
621
622 fn type_name() -> TypeName {
623 crate::abi::type_name_variadic::<T>()
624 }
625
626 fn type_name_rust() -> TypeName {
627 crate::abi::type_name_multi_value_encoded::<T>()
628 }
629
630 fn provide_type_descriptions<TDC: TypeDescriptionContainer>(accumulator: &mut TDC) {
631 T::provide_type_descriptions(accumulator);
632 }
633
634 fn is_variadic() -> bool {
635 true
636 }
637}