1use crate::{
22 storage::{
23 types::{OptionQuery, QueryKindTrait, StorageEntryMetadataBuilder},
24 KeyLenOf, StorageAppend, StorageDecodeLength, StoragePrefixedMap, StorageTryAppend,
25 },
26 traits::{Get, GetDefault, StorageInfo, StorageInstance},
27 StorageHasher, Twox128,
28};
29use alloc::{vec, vec::Vec};
30use codec::{Decode, Encode, EncodeLike, FullCodec, MaxEncodedLen};
31use frame_support::storage::StorageDecodeNonDedupLength;
32use sp_arithmetic::traits::SaturatedConversion;
33use sp_metadata_ir::{StorageEntryMetadataIR, StorageEntryTypeIR};
34
35pub struct StorageMap<
75 Prefix,
76 Hasher,
77 Key,
78 Value,
79 QueryKind = OptionQuery,
80 OnEmpty = GetDefault,
81 MaxValues = GetDefault,
82>(core::marker::PhantomData<(Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues)>);
83
84impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues> Get<u32>
85 for KeyLenOf<StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>>
86where
87 Prefix: StorageInstance,
88 Hasher: crate::hash::StorageHasher,
89 Key: FullCodec + MaxEncodedLen,
90{
91 fn get() -> u32 {
92 let z = Hasher::max_len::<Key>() + Twox128::max_len::<()>() * 2;
95 z as u32
96 }
97}
98
99impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
100 crate::storage::generator::StorageMap<Key, Value>
101 for StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
102where
103 Prefix: StorageInstance,
104 Hasher: crate::hash::StorageHasher,
105 Key: FullCodec,
106 Value: FullCodec,
107 QueryKind: QueryKindTrait<Value, OnEmpty>,
108 OnEmpty: Get<QueryKind::Query> + 'static,
109 MaxValues: Get<Option<u32>>,
110{
111 type Query = QueryKind::Query;
112 type Hasher = Hasher;
113 fn pallet_prefix() -> &'static [u8] {
114 Prefix::pallet_prefix().as_bytes()
115 }
116 fn storage_prefix() -> &'static [u8] {
117 Prefix::STORAGE_PREFIX.as_bytes()
118 }
119 fn prefix_hash() -> [u8; 32] {
120 Prefix::prefix_hash()
121 }
122 fn from_optional_value_to_query(v: Option<Value>) -> Self::Query {
123 QueryKind::from_optional_value_to_query(v)
124 }
125 fn from_query_to_optional_value(v: Self::Query) -> Option<Value> {
126 QueryKind::from_query_to_optional_value(v)
127 }
128}
129
130impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues> StoragePrefixedMap<Value>
131 for StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
132where
133 Prefix: StorageInstance,
134 Hasher: crate::hash::StorageHasher,
135 Key: FullCodec,
136 Value: FullCodec,
137 QueryKind: QueryKindTrait<Value, OnEmpty>,
138 OnEmpty: Get<QueryKind::Query> + 'static,
139 MaxValues: Get<Option<u32>>,
140{
141 fn pallet_prefix() -> &'static [u8] {
142 <Self as crate::storage::generator::StorageMap<Key, Value>>::pallet_prefix()
143 }
144 fn storage_prefix() -> &'static [u8] {
145 <Self as crate::storage::generator::StorageMap<Key, Value>>::storage_prefix()
146 }
147}
148
149impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
150 StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
151where
152 Prefix: StorageInstance,
153 Hasher: crate::hash::StorageHasher,
154 Key: FullCodec,
155 Value: FullCodec,
156 QueryKind: QueryKindTrait<Value, OnEmpty>,
157 OnEmpty: Get<QueryKind::Query> + 'static,
158 MaxValues: Get<Option<u32>>,
159{
160 pub fn hashed_key_for<KeyArg: EncodeLike<Key>>(key: KeyArg) -> Vec<u8> {
162 <Self as crate::storage::StorageMap<Key, Value>>::hashed_key_for(key)
163 }
164
165 pub fn contains_key<KeyArg: EncodeLike<Key>>(key: KeyArg) -> bool {
167 <Self as crate::storage::StorageMap<Key, Value>>::contains_key(key)
168 }
169
170 pub fn get<KeyArg: EncodeLike<Key>>(key: KeyArg) -> QueryKind::Query {
172 <Self as crate::storage::StorageMap<Key, Value>>::get(key)
173 }
174
175 pub fn try_get<KeyArg: EncodeLike<Key>>(key: KeyArg) -> Result<Value, ()> {
179 <Self as crate::storage::StorageMap<Key, Value>>::try_get(key)
180 }
181
182 pub fn swap<KeyArg1: EncodeLike<Key>, KeyArg2: EncodeLike<Key>>(key1: KeyArg1, key2: KeyArg2) {
184 <Self as crate::storage::StorageMap<Key, Value>>::swap(key1, key2)
185 }
186
187 pub fn set<KeyArg: EncodeLike<Key>>(key: KeyArg, q: QueryKind::Query) {
189 <Self as crate::storage::StorageMap<Key, Value>>::set(key, q)
190 }
191
192 pub fn insert<KeyArg: EncodeLike<Key>, ValArg: EncodeLike<Value>>(key: KeyArg, val: ValArg) {
194 <Self as crate::storage::StorageMap<Key, Value>>::insert(key, val)
195 }
196
197 pub fn remove<KeyArg: EncodeLike<Key>>(key: KeyArg) {
199 <Self as crate::storage::StorageMap<Key, Value>>::remove(key)
200 }
201
202 pub fn mutate<KeyArg: EncodeLike<Key>, R, F: FnOnce(&mut QueryKind::Query) -> R>(
204 key: KeyArg,
205 f: F,
206 ) -> R {
207 <Self as crate::storage::StorageMap<Key, Value>>::mutate(key, f)
208 }
209
210 pub fn try_mutate<KeyArg, R, E, F>(key: KeyArg, f: F) -> Result<R, E>
212 where
213 KeyArg: EncodeLike<Key>,
214 F: FnOnce(&mut QueryKind::Query) -> Result<R, E>,
215 {
216 <Self as crate::storage::StorageMap<Key, Value>>::try_mutate(key, f)
217 }
218
219 pub fn mutate_extant<KeyArg: EncodeLike<Key>, R: Default, F: FnOnce(&mut Value) -> R>(
221 key: KeyArg,
222 f: F,
223 ) -> R {
224 <Self as crate::storage::StorageMap<Key, Value>>::mutate_extant(key, f)
225 }
226
227 pub fn mutate_exists<KeyArg: EncodeLike<Key>, R, F: FnOnce(&mut Option<Value>) -> R>(
229 key: KeyArg,
230 f: F,
231 ) -> R {
232 <Self as crate::storage::StorageMap<Key, Value>>::mutate_exists(key, f)
233 }
234
235 pub fn try_mutate_exists<KeyArg, R, E, F>(key: KeyArg, f: F) -> Result<R, E>
239 where
240 KeyArg: EncodeLike<Key>,
241 F: FnOnce(&mut Option<Value>) -> Result<R, E>,
242 {
243 <Self as crate::storage::StorageMap<Key, Value>>::try_mutate_exists(key, f)
244 }
245
246 pub fn take<KeyArg: EncodeLike<Key>>(key: KeyArg) -> QueryKind::Query {
248 <Self as crate::storage::StorageMap<Key, Value>>::take(key)
249 }
250
251 pub fn append<Item, EncodeLikeItem, EncodeLikeKey>(key: EncodeLikeKey, item: EncodeLikeItem)
261 where
262 EncodeLikeKey: EncodeLike<Key>,
263 Item: Encode,
264 EncodeLikeItem: EncodeLike<Item>,
265 Value: StorageAppend<Item>,
266 {
267 <Self as crate::storage::StorageMap<Key, Value>>::append(key, item)
268 }
269
270 pub fn decode_len<KeyArg: EncodeLike<Key>>(key: KeyArg) -> Option<usize>
283 where
284 Value: StorageDecodeLength,
285 {
286 <Self as crate::storage::StorageMap<Key, Value>>::decode_len(key)
287 }
288
289 pub fn decode_non_dedup_len<KeyArg: EncodeLike<Key>>(key: KeyArg) -> Option<usize>
305 where
306 Value: StorageDecodeNonDedupLength,
307 {
308 <Self as crate::storage::StorageMap<Key, Value>>::decode_non_dedup_len(key)
309 }
310
311 pub fn migrate_key<OldHasher: crate::hash::StorageHasher, KeyArg: EncodeLike<Key>>(
315 key: KeyArg,
316 ) -> Option<Value> {
317 <Self as crate::storage::StorageMap<Key, Value>>::migrate_key::<OldHasher, _>(key)
318 }
319
320 #[deprecated = "Use `clear` instead"]
332 pub fn remove_all(limit: Option<u32>) -> sp_io::KillStorageResult {
333 #[allow(deprecated)]
334 <Self as crate::storage::StoragePrefixedMap<Value>>::remove_all(limit)
335 }
336
337 pub fn clear(limit: u32, maybe_cursor: Option<&[u8]>) -> sp_io::MultiRemovalResults {
361 <Self as crate::storage::StoragePrefixedMap<Value>>::clear(limit, maybe_cursor)
362 }
363
364 pub fn iter_values() -> crate::storage::PrefixIterator<Value> {
368 <Self as crate::storage::StoragePrefixedMap<Value>>::iter_values()
369 }
370
371 pub fn translate_values<OldValue: Decode, F: FnMut(OldValue) -> Option<Value>>(f: F) {
386 <Self as crate::storage::StoragePrefixedMap<Value>>::translate_values(f)
387 }
388
389 pub fn try_append<KArg, Item, EncodeLikeItem>(key: KArg, item: EncodeLikeItem) -> Result<(), ()>
393 where
394 KArg: EncodeLike<Key> + Clone,
395 Item: Encode,
396 EncodeLikeItem: EncodeLike<Item>,
397 Value: StorageTryAppend<Item>,
398 {
399 <Self as crate::storage::TryAppendMap<Key, Value, Item>>::try_append(key, item)
400 }
401}
402
403impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
404 StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
405where
406 Prefix: StorageInstance,
407 Hasher: crate::hash::StorageHasher + crate::ReversibleStorageHasher,
408 Key: FullCodec,
409 Value: FullCodec,
410 QueryKind: QueryKindTrait<Value, OnEmpty>,
411 OnEmpty: Get<QueryKind::Query> + 'static,
412 MaxValues: Get<Option<u32>>,
413{
414 pub fn iter() -> crate::storage::PrefixIterator<(Key, Value)> {
418 <Self as crate::storage::IterableStorageMap<Key, Value>>::iter()
419 }
420
421 pub fn iter_from(starting_raw_key: Vec<u8>) -> crate::storage::PrefixIterator<(Key, Value)> {
426 <Self as crate::storage::IterableStorageMap<Key, Value>>::iter_from(starting_raw_key)
427 }
428
429 pub fn iter_from_key(
434 starting_key: impl EncodeLike<Key>,
435 ) -> crate::storage::PrefixIterator<(Key, Value)> {
436 Self::iter_from(Self::hashed_key_for(starting_key))
437 }
438
439 pub fn iter_keys() -> crate::storage::KeyPrefixIterator<Key> {
443 <Self as crate::storage::IterableStorageMap<Key, Value>>::iter_keys()
444 }
445
446 pub fn iter_keys_from(starting_raw_key: Vec<u8>) -> crate::storage::KeyPrefixIterator<Key> {
451 <Self as crate::storage::IterableStorageMap<Key, Value>>::iter_keys_from(starting_raw_key)
452 }
453
454 pub fn iter_keys_from_key(
459 starting_key: impl EncodeLike<Key>,
460 ) -> crate::storage::KeyPrefixIterator<Key> {
461 Self::iter_keys_from(Self::hashed_key_for(starting_key))
462 }
463
464 pub fn drain() -> crate::storage::PrefixIterator<(Key, Value)> {
468 <Self as crate::storage::IterableStorageMap<Key, Value>>::drain()
469 }
470
471 pub fn translate<O: Decode, F: FnMut(Key, O) -> Option<Value>>(f: F) {
478 <Self as crate::storage::IterableStorageMap<Key, Value>>::translate(f)
479 }
480}
481
482impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues> StorageEntryMetadataBuilder
483 for StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
484where
485 Prefix: StorageInstance,
486 Hasher: crate::hash::StorageHasher,
487 Key: FullCodec + scale_info::StaticTypeInfo,
488 Value: FullCodec + scale_info::StaticTypeInfo,
489 QueryKind: QueryKindTrait<Value, OnEmpty>,
490 OnEmpty: Get<QueryKind::Query> + 'static,
491 MaxValues: Get<Option<u32>>,
492{
493 fn build_metadata(
494 deprecation_status: sp_metadata_ir::ItemDeprecationInfoIR,
495 docs: Vec<&'static str>,
496 entries: &mut Vec<StorageEntryMetadataIR>,
497 ) {
498 let docs = if cfg!(feature = "no-metadata-docs") { vec![] } else { docs };
499
500 let entry = StorageEntryMetadataIR {
501 name: Prefix::STORAGE_PREFIX,
502 modifier: QueryKind::METADATA,
503 ty: StorageEntryTypeIR::Map {
504 hashers: vec![Hasher::METADATA],
505 key: scale_info::meta_type::<Key>(),
506 value: scale_info::meta_type::<Value>(),
507 },
508 default: OnEmpty::get().encode(),
509 docs,
510 deprecation_info: deprecation_status,
511 };
512
513 entries.push(entry);
514 }
515}
516
517impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues> crate::traits::StorageInfoTrait
518 for StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
519where
520 Prefix: StorageInstance,
521 Hasher: crate::hash::StorageHasher,
522 Key: FullCodec + MaxEncodedLen,
523 Value: FullCodec + MaxEncodedLen,
524 QueryKind: QueryKindTrait<Value, OnEmpty>,
525 OnEmpty: Get<QueryKind::Query> + 'static,
526 MaxValues: Get<Option<u32>>,
527{
528 fn storage_info() -> Vec<StorageInfo> {
529 vec![StorageInfo {
530 pallet_name: Self::pallet_prefix().to_vec(),
531 storage_name: Self::storage_prefix().to_vec(),
532 prefix: Self::final_prefix().to_vec(),
533 max_values: MaxValues::get(),
534 max_size: Some(
535 Hasher::max_len::<Key>()
536 .saturating_add(Value::max_encoded_len())
537 .saturated_into(),
538 ),
539 }]
540 }
541}
542
543impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
545 crate::traits::PartialStorageInfoTrait
546 for StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
547where
548 Prefix: StorageInstance,
549 Hasher: crate::hash::StorageHasher,
550 Key: FullCodec,
551 Value: FullCodec,
552 QueryKind: QueryKindTrait<Value, OnEmpty>,
553 OnEmpty: Get<QueryKind::Query> + 'static,
554 MaxValues: Get<Option<u32>>,
555{
556 fn partial_storage_info() -> Vec<StorageInfo> {
557 vec![StorageInfo {
558 pallet_name: Self::pallet_prefix().to_vec(),
559 storage_name: Self::storage_prefix().to_vec(),
560 prefix: Self::final_prefix().to_vec(),
561 max_values: MaxValues::get(),
562 max_size: None,
563 }]
564 }
565}
566
567#[cfg(test)]
568mod test {
569 use super::*;
570 use crate::{
571 hash::*,
572 storage::{types::ValueQuery, IterableStorageMap},
573 };
574 use sp_io::{hashing::twox_128, TestExternalities};
575 use sp_metadata_ir::{StorageEntryModifierIR, StorageEntryTypeIR, StorageHasherIR};
576
577 struct Prefix;
578 impl StorageInstance for Prefix {
579 fn pallet_prefix() -> &'static str {
580 "test"
581 }
582 const STORAGE_PREFIX: &'static str = "foo";
583 }
584
585 struct ADefault;
586 impl crate::traits::Get<u32> for ADefault {
587 fn get() -> u32 {
588 97
589 }
590 }
591
592 #[test]
593 fn keylenof_works() {
594 type A = StorageMap<Prefix, Blake2_128Concat, u32, u32>;
596 let size = 16 * 2 + 16 + 4; assert_eq!(KeyLenOf::<A>::get(), size);
599
600 type B = StorageMap<Prefix, Blake2_256, u32, u32>;
602 let size = 16 * 2 + 32; assert_eq!(KeyLenOf::<B>::get(), size);
605
606 type C = StorageMap<Prefix, Twox64Concat, u32, u32>;
608 let size = 16 * 2 + 8 + 4; assert_eq!(KeyLenOf::<C>::get(), size);
611 }
612
613 #[test]
614 fn test() {
615 type A = StorageMap<Prefix, Blake2_128Concat, u16, u32, OptionQuery>;
616 type AValueQueryWithAnOnEmpty =
617 StorageMap<Prefix, Blake2_128Concat, u16, u32, ValueQuery, ADefault>;
618 type B = StorageMap<Prefix, Blake2_256, u16, u32, ValueQuery>;
619 type C = StorageMap<Prefix, Blake2_128Concat, u16, u8, ValueQuery>;
620 type WithLen = StorageMap<Prefix, Blake2_128Concat, u16, Vec<u32>>;
621
622 TestExternalities::default().execute_with(|| {
623 let mut k: Vec<u8> = vec![];
624 k.extend(&twox_128(b"test"));
625 k.extend(&twox_128(b"foo"));
626 k.extend(&3u16.blake2_128_concat());
627 assert_eq!(A::hashed_key_for(3).to_vec(), k);
628
629 assert_eq!(A::contains_key(3), false);
630 assert_eq!(A::get(3), None);
631 assert_eq!(AValueQueryWithAnOnEmpty::get(3), 97);
632
633 A::insert(3, 10);
634 assert_eq!(A::contains_key(3), true);
635 assert_eq!(A::get(3), Some(10));
636 assert_eq!(A::try_get(3), Ok(10));
637 assert_eq!(AValueQueryWithAnOnEmpty::get(3), 10);
638
639 A::swap(3, 2);
640 assert_eq!(A::contains_key(3), false);
641 assert_eq!(A::contains_key(2), true);
642 assert_eq!(A::get(3), None);
643 assert_eq!(A::try_get(3), Err(()));
644 assert_eq!(AValueQueryWithAnOnEmpty::get(3), 97);
645 assert_eq!(A::get(2), Some(10));
646 assert_eq!(AValueQueryWithAnOnEmpty::get(2), 10);
647
648 A::remove(2);
649 assert_eq!(A::contains_key(2), false);
650 assert_eq!(A::get(2), None);
651
652 AValueQueryWithAnOnEmpty::mutate(2, |v| *v = *v * 2);
653 AValueQueryWithAnOnEmpty::mutate(2, |v| *v = *v * 2);
654 assert_eq!(AValueQueryWithAnOnEmpty::contains_key(2), true);
655 assert_eq!(AValueQueryWithAnOnEmpty::get(2), 97 * 4);
656
657 A::remove(2);
658 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate(2, |v| {
659 *v = *v * 2;
660 Ok(())
661 });
662 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate(2, |v| {
663 *v = *v * 2;
664 Ok(())
665 });
666 assert_eq!(A::contains_key(2), true);
667 assert_eq!(A::get(2), Some(97 * 4));
668
669 A::remove(2);
670 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate(2, |v| {
671 *v = *v * 2;
672 Err(())
673 });
674 assert_eq!(A::contains_key(2), false);
675
676 A::remove(2);
677 AValueQueryWithAnOnEmpty::mutate_exists(2, |v| {
678 assert!(v.is_none());
679 *v = Some(10);
680 });
681 assert_eq!(A::contains_key(2), true);
682 assert_eq!(A::get(2), Some(10));
683 AValueQueryWithAnOnEmpty::mutate_exists(2, |v| {
684 *v = Some(v.unwrap() * 10);
685 });
686 assert_eq!(A::contains_key(2), true);
687 assert_eq!(A::get(2), Some(100));
688
689 A::remove(2);
690 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists(2, |v| {
691 assert!(v.is_none());
692 *v = Some(10);
693 Ok(())
694 });
695 assert_eq!(A::contains_key(2), true);
696 assert_eq!(A::get(2), Some(10));
697 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists(2, |v| {
698 *v = Some(v.unwrap() * 10);
699 Ok(())
700 });
701 assert_eq!(A::contains_key(2), true);
702 assert_eq!(A::get(2), Some(100));
703 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists(2, |v| {
704 *v = Some(v.unwrap() * 10);
705 Err(())
706 });
707 assert_eq!(A::contains_key(2), true);
708 assert_eq!(A::get(2), Some(100));
709
710 A::insert(2, 10);
711 assert_eq!(A::take(2), Some(10));
712 assert_eq!(A::contains_key(2), false);
713 assert_eq!(AValueQueryWithAnOnEmpty::take(2), 97);
714 assert_eq!(A::contains_key(2), false);
715
716 B::set(30, 100);
718
719 assert_eq!(B::contains_key(30), true);
720 assert_eq!(B::get(30), 100);
721 assert_eq!(B::try_get(30), Ok(100));
722
723 B::set(30, 101);
725
726 assert_eq!(B::contains_key(30), true);
727 assert_eq!(B::get(30), 101);
728 assert_eq!(B::try_get(30), Ok(101));
729
730 A::set(30, Some(100));
732
733 assert_eq!(A::contains_key(30), true);
734 assert_eq!(A::get(30), Some(100));
735 assert_eq!(A::try_get(30), Ok(100));
736
737 A::set(30, Some(101));
739
740 assert_eq!(A::contains_key(30), true);
741 assert_eq!(A::get(30), Some(101));
742 assert_eq!(A::try_get(30), Ok(101));
743
744 A::set(30, None);
746
747 assert_eq!(A::contains_key(30), false);
748 assert_eq!(A::get(30), None);
749 assert_eq!(A::try_get(30), Err(()));
750
751 A::set(31, None);
753
754 assert_eq!(A::contains_key(31), false);
755 assert_eq!(A::get(31), None);
756 assert_eq!(A::try_get(31), Err(()));
757
758 B::insert(2, 10);
759 assert_eq!(A::migrate_key::<Blake2_256, _>(2), Some(10));
760 assert_eq!(A::contains_key(2), true);
761 assert_eq!(A::get(2), Some(10));
762
763 A::insert(3, 10);
764 A::insert(4, 10);
765 let _ = A::clear(u32::max_value(), None);
766 assert_eq!(A::contains_key(3), false);
767 assert_eq!(A::contains_key(4), false);
768
769 A::insert(3, 10);
770 A::insert(4, 10);
771 assert_eq!(A::iter_values().collect::<Vec<_>>(), vec![10, 10]);
772
773 C::insert(3, 10);
774 C::insert(4, 10);
775 A::translate_values::<u8, _>(|v| Some((v * 2).into()));
776 assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 20), (3, 20)]);
777
778 A::insert(3, 10);
779 A::insert(4, 10);
780 assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 10), (3, 10)]);
781 assert_eq!(A::drain().collect::<Vec<_>>(), vec![(4, 10), (3, 10)]);
782 assert_eq!(A::iter().collect::<Vec<_>>(), vec![]);
783
784 C::insert(3, 10);
785 C::insert(4, 10);
786 A::translate::<u8, _>(|k, v| Some((k * v as u16).into()));
787 assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 40), (3, 30)]);
788
789 let translate_next = |k: u16, v: u8| Some((v as u16 / k).into());
790 let k = A::translate_next::<u8, _>(None, translate_next);
791 let k = A::translate_next::<u8, _>(k, translate_next);
792 assert_eq!(None, A::translate_next::<u8, _>(k, translate_next));
793 assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 10), (3, 10)]);
794
795 let _ = A::translate_next::<u8, _>(None, |_, _| None);
796 assert_eq!(A::iter().collect::<Vec<_>>(), vec![(3, 10)]);
797
798 let mut entries = vec![];
799 A::build_metadata(
800 sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
801 vec![],
802 &mut entries,
803 );
804 AValueQueryWithAnOnEmpty::build_metadata(
805 sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
806 vec![],
807 &mut entries,
808 );
809 assert_eq!(
810 entries,
811 vec![
812 StorageEntryMetadataIR {
813 name: "foo",
814 modifier: StorageEntryModifierIR::Optional,
815 ty: StorageEntryTypeIR::Map {
816 hashers: vec![StorageHasherIR::Blake2_128Concat],
817 key: scale_info::meta_type::<u16>(),
818 value: scale_info::meta_type::<u32>(),
819 },
820 default: Option::<u32>::None.encode(),
821 docs: vec![],
822 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated
823 },
824 StorageEntryMetadataIR {
825 name: "foo",
826 modifier: StorageEntryModifierIR::Default,
827 ty: StorageEntryTypeIR::Map {
828 hashers: vec![StorageHasherIR::Blake2_128Concat],
829 key: scale_info::meta_type::<u16>(),
830 value: scale_info::meta_type::<u32>(),
831 },
832 default: 97u32.encode(),
833 docs: vec![],
834 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated
835 }
836 ]
837 );
838
839 let _ = WithLen::clear(u32::max_value(), None);
840 assert_eq!(WithLen::decode_len(3), None);
841 WithLen::append(0, 10);
842 assert_eq!(WithLen::decode_len(0), Some(1));
843 })
844 }
845}