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, NestedDecode, NestedEncode,
12 TopDecode, TopEncode, TopEncodeMulti, TopEncodeMultiOutput,
13 derive::{
14 NestedDecode, NestedEncode, TopDecode, TopDecodeOrDefault, TopEncode,
15 TopEncodeOrDefault,
16 },
17 },
18 storage::{StorageKey, storage_set},
19 types::{ManagedAddress, ManagedType, MultiValueEncoded, heap::BoxedBytes},
20};
21use alloc::vec::Vec;
22
23const NULL_ENTRY: u32 = 0;
24const INFO_IDENTIFIER: &[u8] = b".info";
25const NODE_IDENTIFIER: &[u8] = b".node";
26
27#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, PartialEq, Eq, Clone, Copy)]
28pub struct LinkedListNode<T: NestedEncode + NestedDecode + TopEncode + TopDecode + Clone> {
29 pub(crate) value: T,
30 pub(crate) node_id: u32,
31 pub(crate) next_id: u32,
32 pub(crate) prev_id: u32,
33}
34
35impl<T: NestedEncode + NestedDecode + TopEncode + TopDecode + Clone> LinkedListNode<T> {
36 pub fn get_value_cloned(&self) -> T {
37 self.value.clone()
38 }
39
40 pub fn get_value_as_ref(&self) -> &T {
41 &self.value
42 }
43
44 pub fn into_value(self) -> T {
45 self.value
46 }
47
48 pub fn get_node_id(&self) -> u32 {
49 self.node_id
50 }
51
52 pub fn get_next_node_id(&self) -> u32 {
53 self.next_id
54 }
55
56 pub fn get_prev_node_id(&self) -> u32 {
57 self.prev_id
58 }
59}
60
61#[derive(TopEncodeOrDefault, TopDecodeOrDefault, PartialEq, Eq, Clone, Copy)]
62pub struct LinkedListInfo {
63 pub len: u32,
64 pub front: u32,
65 pub back: u32,
66 pub new: u32,
67}
68
69impl EncodeDefault for LinkedListInfo {
70 fn is_default(&self) -> bool {
71 self.len == 0
72 }
73}
74
75impl DecodeDefault for LinkedListInfo {
76 fn default() -> Self {
77 Self {
78 len: 0,
79 front: 0,
80 back: 0,
81 new: 0,
82 }
83 }
84}
85
86impl LinkedListInfo {
87 pub fn generate_new_node_id(&mut self) -> u32 {
88 self.new += 1;
89 self.new
90 }
91}
92
93pub struct LinkedListMapper<SA, T, A = CurrentStorage>
173where
174 SA: StorageMapperApi,
175 A: StorageAddress<SA>,
176 T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static,
177{
178 _phantom_api: PhantomData<SA>,
179 address: A,
180 base_key: StorageKey<SA>,
181 _phantom_item: PhantomData<T>,
182}
183
184impl<SA, T> StorageMapper<SA> for LinkedListMapper<SA, T, CurrentStorage>
185where
186 SA: StorageMapperApi,
187 T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone,
188{
189 fn new(base_key: StorageKey<SA>) -> Self {
190 LinkedListMapper {
191 _phantom_api: PhantomData,
192 address: CurrentStorage,
193 base_key,
194 _phantom_item: PhantomData,
195 }
196 }
197}
198
199impl<SA, T> StorageMapperFromAddress<SA> for LinkedListMapper<SA, T, ManagedAddress<SA>>
200where
201 SA: StorageMapperApi,
202 T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone,
203{
204 fn new_from_address(address: ManagedAddress<SA>, base_key: StorageKey<SA>) -> Self {
205 LinkedListMapper {
206 _phantom_api: PhantomData,
207 address,
208 base_key,
209 _phantom_item: PhantomData,
210 }
211 }
212}
213
214impl<SA, T> StorageClearable for LinkedListMapper<SA, T>
215where
216 SA: StorageMapperApi,
217 T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone,
218{
219 fn clear(&mut self) {
220 let info = self.get_info();
221 let mut node_id = info.front;
222
223 while node_id != NULL_ENTRY {
224 let node = self.get_node(node_id);
225 self.clear_node(node_id);
226 node_id = node.next_id;
227 }
228
229 self.set_info(LinkedListInfo::default());
230 }
231}
232
233impl<SA, T, A> LinkedListMapper<SA, T, A>
234where
235 SA: StorageMapperApi,
236 A: StorageAddress<SA>,
237 T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone,
238{
239 fn build_node_id_named_key(&self, name: &[u8], node_id: u32) -> StorageKey<SA> {
240 let mut named_key = self.base_key.clone();
241 named_key.append_bytes(name);
242 named_key.append_item(&node_id);
243 named_key
244 }
245
246 fn build_name_key(&self, name: &[u8]) -> StorageKey<SA> {
247 let mut name_key = self.base_key.clone();
248 name_key.append_bytes(name);
249 name_key
250 }
251
252 fn get_info(&self) -> LinkedListInfo {
253 self.address
254 .address_storage_get(self.build_name_key(INFO_IDENTIFIER).as_ref())
255 }
256
257 fn get_node(&self, node_id: u32) -> LinkedListNode<T> {
258 self.address.address_storage_get(
259 self.build_node_id_named_key(NODE_IDENTIFIER, node_id)
260 .as_ref(),
261 )
262 }
263
264 fn is_empty_node(&self, node_id: u32) -> bool {
265 self.address.address_storage_get_len(
266 self.build_node_id_named_key(NODE_IDENTIFIER, node_id)
267 .as_ref(),
268 ) == 0
269 }
270
271 pub fn is_empty(&self) -> bool {
272 self.get_info().len == 0
273 }
274
275 pub fn len(&self) -> usize {
276 self.get_info().len as usize
277 }
278
279 pub fn front(&self) -> Option<LinkedListNode<T>> {
280 let info = self.get_info();
281
282 self.get_node_by_id(info.front)
283 }
284
285 pub fn back(&self) -> Option<LinkedListNode<T>> {
286 let info = self.get_info();
287
288 self.get_node_by_id(info.back)
289 }
290
291 pub fn get_node_by_id(&self, node_id: u32) -> Option<LinkedListNode<T>> {
292 if self.is_empty_node(node_id) {
293 return None;
294 }
295
296 Some(self.get_node(node_id))
297 }
298
299 pub fn iter(&self) -> Iter<'_, SA, T, A> {
300 Iter::new(self)
301 }
302
303 pub fn iter_from_node_id(&self, node_id: u32) -> Iter<'_, SA, T, A> {
304 Iter::new_from_node_id(self, node_id)
305 }
306
307 pub fn check_internal_consistency(&self) -> bool {
308 let info = self.get_info();
309 let mut front = info.front;
310 let mut back = info.back;
311
312 if info.len == 0 {
313 if front != NULL_ENTRY {
314 return false;
315 }
316 if back != NULL_ENTRY {
317 return false;
318 }
319 true
320 } else {
321 if front == NULL_ENTRY {
322 return false;
323 }
324 if back == NULL_ENTRY {
325 return false;
326 }
327
328 if self.get_node(front).prev_id != NULL_ENTRY {
329 return false;
330 }
331 if self.get_node(back).next_id != NULL_ENTRY {
332 return false;
333 }
334
335 let mut forwards = Vec::new();
336 while front != NULL_ENTRY {
337 forwards.push(front);
338 front = self.get_node(front).next_id;
339 }
340 if forwards.len() != info.len as usize {
341 return false;
342 }
343
344 let mut backwards = Vec::new();
345 while back != NULL_ENTRY {
346 backwards.push(back);
347 back = self.get_node(back).prev_id;
348 }
349 if backwards.len() != info.len as usize {
350 return false;
351 }
352
353 let backwards_reversed: Vec<u32> = backwards.iter().rev().cloned().collect();
354 if forwards != backwards_reversed {
355 return false;
356 }
357
358 forwards.sort_unstable();
359 forwards.dedup();
360 if forwards.len() != info.len as usize {
361 return false;
362 }
363 true
364 }
365 }
366}
367
368impl<SA, T> LinkedListMapper<SA, T, CurrentStorage>
369where
370 SA: StorageMapperApi,
371 T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone,
372{
373 fn set_info(&mut self, value: LinkedListInfo) {
374 storage_set(self.build_name_key(INFO_IDENTIFIER).as_ref(), &value);
375 }
376
377 fn set_node(&mut self, node_id: u32, item: &LinkedListNode<T>) {
378 storage_set(
379 self.build_node_id_named_key(NODE_IDENTIFIER, node_id)
380 .as_ref(),
381 item,
382 );
383 }
384
385 fn clear_node(&mut self, node_id: u32) {
386 storage_set(
387 self.build_node_id_named_key(NODE_IDENTIFIER, node_id)
388 .as_ref(),
389 &BoxedBytes::empty(),
390 );
391 }
392
393 pub fn pop_back(&mut self) -> Option<LinkedListNode<T>> {
394 let info = self.get_info();
395
396 self.remove_node_by_id(info.back)
397 }
398
399 pub fn pop_front(&mut self) -> Option<LinkedListNode<T>> {
400 let info = self.get_info();
401
402 self.remove_node_by_id(info.front)
403 }
404
405 pub fn push_after(
406 &mut self,
407 node: &mut LinkedListNode<T>,
408 element: T,
409 ) -> Option<LinkedListNode<T>> {
410 if self.is_empty_node(node.node_id) {
411 return None;
412 }
413
414 let mut info = self.get_info();
415 let new_node_id = info.generate_new_node_id();
416
417 let new_node_next_id = node.next_id;
418 node.next_id = new_node_id;
419 self.set_node(node.node_id, node);
420
421 if new_node_next_id == NULL_ENTRY {
422 info.back = new_node_id;
423 } else {
424 let mut next_node = self.get_node(new_node_next_id);
425 next_node.prev_id = new_node_id;
426 self.set_node(new_node_next_id, &next_node);
427 }
428
429 let new_node = LinkedListNode {
430 value: element,
431 node_id: new_node_id,
432 next_id: new_node_next_id,
433 prev_id: node.node_id,
434 };
435 self.set_node(new_node_id, &new_node);
436
437 info.len += 1;
438 self.set_info(info);
439 Some(new_node)
440 }
441
442 pub fn push_before(
443 &mut self,
444 node: &mut LinkedListNode<T>,
445 element: T,
446 ) -> Option<LinkedListNode<T>> {
447 if self.is_empty_node(node.node_id) {
448 return None;
449 }
450
451 let mut info = self.get_info();
452 let new_node_id = info.generate_new_node_id();
453
454 let new_node_prev_id = node.prev_id;
455 node.prev_id = new_node_id;
456 self.set_node(node.node_id, node);
457
458 if new_node_prev_id == NULL_ENTRY {
459 info.front = new_node_id;
460 } else {
461 let mut previous_node = self.get_node(new_node_prev_id);
462 previous_node.next_id = new_node_id;
463 self.set_node(new_node_prev_id, &previous_node);
464 }
465
466 let new_node = LinkedListNode {
467 value: element,
468 node_id: new_node_id,
469 next_id: node.node_id,
470 prev_id: new_node_prev_id,
471 };
472 self.set_node(new_node_id, &new_node);
473
474 info.len += 1;
475 self.set_info(info);
476 Some(new_node)
477 }
478
479 pub fn push_after_node_id(&mut self, node_id: u32, element: T) -> Option<LinkedListNode<T>> {
480 if !self.is_empty_node(node_id) {
481 let mut node = self.get_node(node_id);
482 self.push_after(&mut node, element)
483 } else {
484 None
485 }
486 }
487
488 pub fn push_before_node_id(&mut self, node_id: u32, element: T) -> Option<LinkedListNode<T>> {
489 if !self.is_empty_node(node_id) {
490 let mut node = self.get_node(node_id);
491 self.push_before(&mut node, element)
492 } else {
493 None
494 }
495 }
496
497 pub fn push_back(&mut self, element: T) -> LinkedListNode<T> {
498 let mut info = self.get_info();
499 let new_node_id = info.generate_new_node_id();
500 let mut previous = NULL_ENTRY;
501
502 if info.len == 0 {
503 info.front = new_node_id;
504 } else {
505 let back = info.back;
506 let mut back_node = self.get_node(back);
507 back_node.next_id = new_node_id;
508 previous = back;
509 self.set_node(back, &back_node);
510 }
511
512 let node = LinkedListNode {
513 value: element,
514 node_id: new_node_id,
515 prev_id: previous,
516 next_id: NULL_ENTRY,
517 };
518 self.set_node(new_node_id, &node);
519
520 info.back = new_node_id;
521 info.len += 1;
522 self.set_info(info);
523 node
524 }
525
526 pub fn push_front(&mut self, element: T) -> LinkedListNode<T> {
527 let mut info = self.get_info();
528 let new_node_id = info.generate_new_node_id();
529 let mut next = NULL_ENTRY;
530
531 if info.len == 0 {
532 info.back = new_node_id;
533 } else {
534 let front = info.front;
535 let mut front_node = self.get_node(front);
536 front_node.prev_id = new_node_id;
537 next = front;
538 self.set_node(front, &front_node);
539 }
540
541 let node = LinkedListNode {
542 value: element,
543 node_id: new_node_id,
544 prev_id: NULL_ENTRY,
545 next_id: next,
546 };
547 self.set_node(new_node_id, &node);
548
549 info.front = new_node_id;
550 info.len += 1;
551 self.set_info(info);
552 node
553 }
554
555 pub fn set_node_value(&mut self, mut node: LinkedListNode<T>, new_value: T) {
556 if self.is_empty_node(node.node_id) {
557 return;
558 }
559
560 node.value = new_value;
561 self.set_node(node.node_id, &node);
562 }
563
564 pub fn set_node_value_by_id(&mut self, node_id: u32, new_value: T) {
565 if let Some(node) = self.get_node_by_id(node_id) {
566 self.set_node_value(node, new_value)
567 }
568 }
569
570 pub fn remove_node(&mut self, node: &LinkedListNode<T>) {
571 let node_id = node.node_id;
572
573 if self.is_empty_node(node_id) {
574 return;
575 }
576
577 let mut info = self.get_info();
578 if node.prev_id == NULL_ENTRY {
579 info.front = node.next_id;
580 } else {
581 let mut previous = self.get_node(node.prev_id);
582 previous.next_id = node.next_id;
583 self.set_node(node.prev_id, &previous);
584 }
585
586 if node.next_id == NULL_ENTRY {
587 info.back = node.prev_id;
588 } else {
589 let mut next = self.get_node(node.next_id);
590 next.prev_id = node.prev_id;
591 self.set_node(node.next_id, &next);
592 }
593
594 self.clear_node(node_id);
595 info.len -= 1;
596 self.set_info(info);
597 }
598
599 pub fn remove_node_by_id(&mut self, node_id: u32) -> Option<LinkedListNode<T>> {
600 if self.is_empty_node(node_id) {
601 return None;
602 }
603
604 let node = self.get_node_by_id(node_id).unwrap();
605 self.remove_node(&node);
606 Some(node)
607 }
608}
609
610impl<'a, SA, T, A> IntoIterator for &'a LinkedListMapper<SA, T, A>
611where
612 SA: StorageMapperApi,
613 A: StorageAddress<SA>,
614 T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static,
615{
616 type Item = LinkedListNode<T>;
617
618 type IntoIter = Iter<'a, SA, T, A>;
619
620 fn into_iter(self) -> Self::IntoIter {
621 self.iter()
622 }
623}
624
625pub struct Iter<'a, SA, T, A>
626where
627 SA: StorageMapperApi,
628 A: StorageAddress<SA>,
629 T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static,
630{
631 node_opt: Option<LinkedListNode<T>>,
632 linked_list: &'a LinkedListMapper<SA, T, A>,
633}
634
635impl<'a, SA, T, A> Iter<'a, SA, T, A>
636where
637 SA: StorageMapperApi,
638 A: StorageAddress<SA>,
639 T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone,
640{
641 fn new(linked_list: &'a LinkedListMapper<SA, T, A>) -> Iter<'a, SA, T, A> {
642 Iter {
643 node_opt: linked_list.front(),
644 linked_list,
645 }
646 }
647
648 fn new_from_node_id(
649 linked_list: &'a LinkedListMapper<SA, T, A>,
650 node_id: u32,
651 ) -> Iter<'a, SA, T, A> {
652 Iter {
653 node_opt: linked_list.get_node_by_id(node_id),
654 linked_list,
655 }
656 }
657}
658
659impl<SA, T, A> Iterator for Iter<'_, SA, T, A>
660where
661 SA: StorageMapperApi,
662 A: StorageAddress<SA>,
663 T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static,
664{
665 type Item = LinkedListNode<T>;
666
667 #[inline]
668 fn next(&mut self) -> Option<LinkedListNode<T>> {
669 self.node_opt.as_ref()?;
670 let node = self.node_opt.clone().unwrap();
671 self.node_opt = self.linked_list.get_node_by_id(node.next_id);
672 Some(node)
673 }
674}
675
676impl<SA, T> TopEncodeMulti for LinkedListMapper<SA, T>
677where
678 SA: StorageMapperApi,
679 T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone,
680{
681 fn multi_encode_or_handle_err<O, H>(&self, output: &mut O, h: H) -> Result<(), H::HandledErr>
682 where
683 O: TopEncodeMultiOutput,
684 H: EncodeErrorHandler,
685 {
686 for elem in self.iter() {
687 elem.into_value().multi_encode_or_handle_err(output, h)?;
688 }
689 Ok(())
690 }
691}
692
693impl<SA, T, U> TypeAbiFrom<LinkedListMapper<SA, T>> for MultiValueEncoded<SA, U>
694where
695 SA: StorageMapperApi,
696 T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone,
697 U: TypeAbiFrom<T>,
698{
699}
700
701impl<SA, T> TypeAbiFrom<Self> for LinkedListMapper<SA, T>
702where
703 SA: StorageMapperApi,
704 T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone,
705{
706}
707
708impl<SA, T> TypeAbi for LinkedListMapper<SA, T>
709where
710 SA: StorageMapperApi,
711 T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + TypeAbi,
712{
713 type Unmanaged = Self;
714
715 fn type_name() -> TypeName {
716 crate::abi::type_name_variadic::<T>()
717 }
718
719 fn type_name_rust() -> TypeName {
720 crate::abi::type_name_multi_value_encoded::<T>()
721 }
722
723 fn provide_type_descriptions<TDC: TypeDescriptionContainer>(accumulator: &mut TDC) {
724 T::provide_type_descriptions(accumulator);
725 }
726
727 fn is_variadic() -> bool {
728 true
729 }
730}