1use crate::{
21 storage::{
22 types::{
23 EncodeLikeTuple, HasKeyPrefix, HasReversibleKeyPrefix, OptionQuery, QueryKindTrait,
24 StorageEntryMetadataBuilder, StorageNMap, StorageValue, TupleToEncodedIter, ValueQuery,
25 },
26 KeyGenerator, PrefixIterator, StorageAppend, StorageDecodeLength,
27 },
28 traits::{Get, GetDefault, StorageInfo, StorageInstance},
29 Never,
30};
31use alloc::{vec, vec::Vec};
32use codec::{Decode, Encode, EncodeLike, FullCodec, MaxEncodedLen, Ref};
33use sp_metadata_ir::StorageEntryMetadataIR;
34use sp_runtime::traits::Saturating;
35
36pub struct CountedStorageNMap<
92 Prefix,
93 Key,
94 Value,
95 QueryKind = OptionQuery,
96 OnEmpty = GetDefault,
97 MaxValues = GetDefault,
98>(core::marker::PhantomData<(Prefix, Key, Value, QueryKind, OnEmpty, MaxValues)>);
99
100pub trait CountedStorageNMapInstance: StorageInstance {
102 type CounterPrefix: StorageInstance;
104}
105
106trait MapWrapper {
108 type Map;
109}
110
111impl<P: CountedStorageNMapInstance, K, V, Q, O, M> MapWrapper
112 for CountedStorageNMap<P, K, V, Q, O, M>
113{
114 type Map = StorageNMap<P, K, V, Q, O, M>;
115}
116
117type Counter = super::counted_map::Counter;
118
119type CounterFor<P> =
120 StorageValue<<P as CountedStorageNMapInstance>::CounterPrefix, Counter, ValueQuery>;
121
122pub struct OnRemovalCounterUpdate<Prefix>(core::marker::PhantomData<Prefix>);
125
126impl<Prefix: CountedStorageNMapInstance> crate::storage::PrefixIteratorOnRemoval
127 for OnRemovalCounterUpdate<Prefix>
128{
129 fn on_removal(_key: &[u8], _value: &[u8]) {
130 CounterFor::<Prefix>::mutate(|value| value.saturating_dec());
131 }
132}
133
134impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
135 CountedStorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
136where
137 Prefix: CountedStorageNMapInstance,
138 Key: super::key::KeyGenerator,
139 Value: FullCodec,
140 QueryKind: QueryKindTrait<Value, OnEmpty>,
141 OnEmpty: Get<QueryKind::Query> + 'static,
142 MaxValues: Get<Option<u32>>,
143{
144 pub fn counter_storage_final_key() -> [u8; 32] {
146 CounterFor::<Prefix>::hashed_key()
147 }
148
149 pub fn map_storage_final_prefix() -> Vec<u8> {
151 use crate::storage::generator::StorageNMap;
152 <Self as MapWrapper>::Map::prefix_hash().to_vec()
153 }
154
155 pub fn hashed_key_for<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
157 key: KArg,
158 ) -> Vec<u8> {
159 <Self as MapWrapper>::Map::hashed_key_for(key)
160 }
161
162 pub fn contains_key<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(key: KArg) -> bool {
164 <Self as MapWrapper>::Map::contains_key(key)
165 }
166
167 pub fn get<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
169 key: KArg,
170 ) -> QueryKind::Query {
171 <Self as MapWrapper>::Map::get(key)
172 }
173
174 pub fn try_get<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
178 key: KArg,
179 ) -> Result<Value, ()> {
180 <Self as MapWrapper>::Map::try_get(key)
181 }
182
183 pub fn set<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
186 key: KArg,
187 query: QueryKind::Query,
188 ) {
189 let option = QueryKind::from_query_to_optional_value(query);
190 if option.is_none() {
191 CounterFor::<Prefix>::mutate(|value| value.saturating_dec());
192 }
193 <Self as MapWrapper>::Map::set(key, QueryKind::from_optional_value_to_query(option))
194 }
195
196 pub fn take<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
198 key: KArg,
199 ) -> QueryKind::Query {
200 let removed_value =
201 <Self as MapWrapper>::Map::mutate_exists(key, |value| core::mem::replace(value, None));
202 if removed_value.is_some() {
203 CounterFor::<Prefix>::mutate(|value| value.saturating_dec());
204 }
205 QueryKind::from_optional_value_to_query(removed_value)
206 }
207
208 pub fn swap<KOther, KArg1, KArg2>(key1: KArg1, key2: KArg2)
210 where
211 KOther: KeyGenerator,
212 KArg1: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
213 KArg2: EncodeLikeTuple<KOther::KArg> + TupleToEncodedIter,
214 {
215 <Self as MapWrapper>::Map::swap::<KOther, _, _>(key1, key2)
216 }
217
218 pub fn insert<KArg, VArg>(key: KArg, val: VArg)
220 where
221 KArg: EncodeLikeTuple<Key::KArg> + EncodeLike<Key::KArg> + TupleToEncodedIter,
222 VArg: EncodeLike<Value>,
223 {
224 if !<Self as MapWrapper>::Map::contains_key(Ref::from(&key)) {
225 CounterFor::<Prefix>::mutate(|value| value.saturating_inc());
226 }
227 <Self as MapWrapper>::Map::insert(key, val)
228 }
229
230 pub fn remove<KArg: EncodeLikeTuple<Key::KArg> + EncodeLike<Key::KArg> + TupleToEncodedIter>(
232 key: KArg,
233 ) {
234 if <Self as MapWrapper>::Map::contains_key(Ref::from(&key)) {
235 CounterFor::<Prefix>::mutate(|value| value.saturating_dec());
236 }
237 <Self as MapWrapper>::Map::remove(key)
238 }
239
240 pub fn clear_prefix<KP>(
264 partial_key: KP,
265 limit: u32,
266 maybe_cursor: Option<&[u8]>,
267 ) -> sp_io::MultiRemovalResults
268 where
269 Key: HasKeyPrefix<KP>,
270 {
271 let result = <Self as MapWrapper>::Map::clear_prefix(partial_key, limit, maybe_cursor);
272 match result.maybe_cursor {
273 None => CounterFor::<Prefix>::kill(),
274 Some(_) => CounterFor::<Prefix>::mutate(|x| x.saturating_reduce(result.unique)),
275 }
276 result
277 }
278
279 pub fn iter_prefix_values<KP>(partial_key: KP) -> PrefixIterator<Value>
281 where
282 Key: HasKeyPrefix<KP>,
283 {
284 <Self as MapWrapper>::Map::iter_prefix_values(partial_key)
285 }
286
287 pub fn mutate<KArg, R, F>(key: KArg, f: F) -> R
289 where
290 KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
291 F: FnOnce(&mut QueryKind::Query) -> R,
292 {
293 Self::try_mutate(key, |v| Ok::<R, Never>(f(v)))
294 .expect("`Never` can not be constructed; qed")
295 }
296
297 pub fn try_mutate<KArg, R, E, F>(key: KArg, f: F) -> Result<R, E>
299 where
300 KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
301 F: FnOnce(&mut QueryKind::Query) -> Result<R, E>,
302 {
303 Self::try_mutate_exists(key, |option_value_ref| {
304 let option_value = core::mem::replace(option_value_ref, None);
305 let mut query = QueryKind::from_optional_value_to_query(option_value);
306 let res = f(&mut query);
307 let option_value = QueryKind::from_query_to_optional_value(query);
308 let _ = core::mem::replace(option_value_ref, option_value);
309 res
310 })
311 }
312
313 pub fn mutate_exists<KArg, R, F>(key: KArg, f: F) -> R
315 where
316 KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
317 F: FnOnce(&mut Option<Value>) -> R,
318 {
319 Self::try_mutate_exists(key, |v| Ok::<R, Never>(f(v)))
320 .expect("`Never` can not be constructed; qed")
321 }
322
323 pub fn try_mutate_exists<KArg, R, E, F>(key: KArg, f: F) -> Result<R, E>
327 where
328 KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
329 F: FnOnce(&mut Option<Value>) -> Result<R, E>,
330 {
331 <Self as MapWrapper>::Map::try_mutate_exists(key, |option_value| {
332 let existed = option_value.is_some();
333 let res = f(option_value);
334 let exist = option_value.is_some();
335
336 if res.is_ok() {
337 if existed && !exist {
338 CounterFor::<Prefix>::mutate(|value| value.saturating_dec());
340 } else if !existed && exist {
341 CounterFor::<Prefix>::mutate(|value| value.saturating_inc());
343 }
344 }
345 res
346 })
347 }
348
349 pub fn append<Item, EncodeLikeItem, KArg>(key: KArg, item: EncodeLikeItem)
359 where
360 KArg: EncodeLikeTuple<Key::KArg> + EncodeLike<Key::KArg> + TupleToEncodedIter,
361 Item: Encode,
362 EncodeLikeItem: EncodeLike<Item>,
363 Value: StorageAppend<Item>,
364 {
365 if !<Self as MapWrapper>::Map::contains_key(Ref::from(&key)) {
366 CounterFor::<Prefix>::mutate(|value| value.saturating_inc());
367 }
368 <Self as MapWrapper>::Map::append(key, item)
369 }
370
371 pub fn decode_len<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
384 key: KArg,
385 ) -> Option<usize>
386 where
387 Value: StorageDecodeLength,
388 {
389 <Self as MapWrapper>::Map::decode_len(key)
390 }
391
392 pub fn migrate_keys<KArg>(key: KArg, hash_fns: Key::HArg) -> Option<Value>
396 where
397 KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
398 {
399 <Self as MapWrapper>::Map::migrate_keys::<_>(key, hash_fns)
400 }
401
402 pub fn clear(limit: u32, maybe_cursor: Option<&[u8]>) -> sp_io::MultiRemovalResults {
426 let result = <Self as MapWrapper>::Map::clear(limit, maybe_cursor);
427 match result.maybe_cursor {
428 None => CounterFor::<Prefix>::kill(),
429 Some(_) => CounterFor::<Prefix>::mutate(|x| x.saturating_reduce(result.unique)),
430 }
431 result
432 }
433
434 pub fn iter_values() -> crate::storage::PrefixIterator<Value> {
438 <Self as MapWrapper>::Map::iter_values()
439 }
440
441 pub fn translate_values<OldValue: Decode, F: FnMut(OldValue) -> Option<Value>>(mut f: F) {
455 <Self as MapWrapper>::Map::translate_values(|old_value| {
456 let res = f(old_value);
457 if res.is_none() {
458 CounterFor::<Prefix>::mutate(|value| value.saturating_dec());
459 }
460 res
461 })
462 }
463
464 pub fn initialize_counter() -> u32 {
471 let count = Self::iter_values().count() as u32;
472 CounterFor::<Prefix>::set(count);
473 count
474 }
475
476 pub fn count() -> Counter {
478 CounterFor::<Prefix>::get()
479 }
480}
481
482impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
483 CountedStorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
484where
485 Prefix: CountedStorageNMapInstance,
486 Key: super::key::ReversibleKeyGenerator,
487 Value: FullCodec,
488 QueryKind: QueryKindTrait<Value, OnEmpty>,
489 OnEmpty: Get<QueryKind::Query> + 'static,
490 MaxValues: Get<Option<u32>>,
491{
492 pub fn iter_prefix<KP>(
497 kp: KP,
498 ) -> crate::storage::PrefixIterator<(<Key as HasKeyPrefix<KP>>::Suffix, Value)>
499 where
500 Key: HasReversibleKeyPrefix<KP>,
501 {
502 <Self as MapWrapper>::Map::iter_prefix(kp)
503 }
504
505 pub fn iter_prefix_from<KP>(
511 kp: KP,
512 starting_raw_key: Vec<u8>,
513 ) -> crate::storage::PrefixIterator<
514 (<Key as HasKeyPrefix<KP>>::Suffix, Value),
515 OnRemovalCounterUpdate<Prefix>,
516 >
517 where
518 Key: HasReversibleKeyPrefix<KP>,
519 {
520 <Self as MapWrapper>::Map::iter_prefix_from(kp, starting_raw_key).convert_on_removal()
521 }
522
523 pub fn iter_key_prefix<KP>(
528 kp: KP,
529 ) -> crate::storage::KeyPrefixIterator<<Key as HasKeyPrefix<KP>>::Suffix>
530 where
531 Key: HasReversibleKeyPrefix<KP>,
532 {
533 <Self as MapWrapper>::Map::iter_key_prefix(kp)
534 }
535
536 pub fn iter_key_prefix_from<KP>(
542 kp: KP,
543 starting_raw_key: Vec<u8>,
544 ) -> crate::storage::KeyPrefixIterator<<Key as HasKeyPrefix<KP>>::Suffix>
545 where
546 Key: HasReversibleKeyPrefix<KP>,
547 {
548 <Self as MapWrapper>::Map::iter_key_prefix_from(kp, starting_raw_key)
549 }
550
551 pub fn drain_prefix<KP>(
557 kp: KP,
558 ) -> crate::storage::PrefixIterator<
559 (<Key as HasKeyPrefix<KP>>::Suffix, Value),
560 OnRemovalCounterUpdate<Prefix>,
561 >
562 where
563 Key: HasReversibleKeyPrefix<KP>,
564 {
565 <Self as MapWrapper>::Map::drain_prefix(kp).convert_on_removal()
566 }
567
568 pub fn iter(
572 ) -> crate::storage::PrefixIterator<(Key::Key, Value), OnRemovalCounterUpdate<Prefix>> {
573 <Self as MapWrapper>::Map::iter().convert_on_removal()
574 }
575
576 pub fn iter_from(
580 starting_raw_key: Vec<u8>,
581 ) -> crate::storage::PrefixIterator<(Key::Key, Value), OnRemovalCounterUpdate<Prefix>> {
582 <Self as MapWrapper>::Map::iter_from(starting_raw_key).convert_on_removal()
583 }
584
585 pub fn iter_keys() -> crate::storage::KeyPrefixIterator<Key::Key> {
589 <Self as MapWrapper>::Map::iter_keys()
590 }
591
592 pub fn iter_keys_from(
596 starting_raw_key: Vec<u8>,
597 ) -> crate::storage::KeyPrefixIterator<Key::Key> {
598 <Self as MapWrapper>::Map::iter_keys_from(starting_raw_key)
599 }
600
601 pub fn drain(
605 ) -> crate::storage::PrefixIterator<(Key::Key, Value), OnRemovalCounterUpdate<Prefix>> {
606 <Self as MapWrapper>::Map::drain().convert_on_removal()
607 }
608
609 pub fn translate<O: Decode, F: FnMut(Key::Key, O) -> Option<Value>>(mut f: F) {
615 <Self as MapWrapper>::Map::translate(|key, old_value| {
616 let res = f(key, old_value);
617 if res.is_none() {
618 CounterFor::<Prefix>::mutate(|value| value.saturating_dec());
619 }
620 res
621 })
622 }
623}
624
625impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues> StorageEntryMetadataBuilder
626 for CountedStorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
627where
628 Prefix: CountedStorageNMapInstance,
629 Key: super::key::KeyGenerator,
630 Value: FullCodec + scale_info::StaticTypeInfo,
631 QueryKind: QueryKindTrait<Value, OnEmpty>,
632 OnEmpty: Get<QueryKind::Query> + 'static,
633 MaxValues: Get<Option<u32>>,
634{
635 fn build_metadata(
636 deprecation_status: sp_metadata_ir::ItemDeprecationInfoIR,
637 docs: Vec<&'static str>,
638 entries: &mut Vec<StorageEntryMetadataIR>,
639 ) {
640 <Self as MapWrapper>::Map::build_metadata(deprecation_status.clone(), docs, entries);
641 CounterFor::<Prefix>::build_metadata(
642 deprecation_status,
643 vec![&"Counter for the related counted storage map"],
644 entries,
645 );
646 }
647}
648
649impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues> crate::traits::StorageInfoTrait
650 for CountedStorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
651where
652 Prefix: CountedStorageNMapInstance,
653 Key: super::key::KeyGenerator + super::key::KeyGeneratorMaxEncodedLen,
654 Value: FullCodec + MaxEncodedLen,
655 QueryKind: QueryKindTrait<Value, OnEmpty>,
656 OnEmpty: Get<QueryKind::Query> + 'static,
657 MaxValues: Get<Option<u32>>,
658{
659 fn storage_info() -> Vec<StorageInfo> {
660 [<Self as MapWrapper>::Map::storage_info(), CounterFor::<Prefix>::storage_info()].concat()
661 }
662}
663
664impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues> crate::traits::PartialStorageInfoTrait
666 for CountedStorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
667where
668 Prefix: CountedStorageNMapInstance,
669 Key: super::key::KeyGenerator,
670 Value: FullCodec,
671 QueryKind: QueryKindTrait<Value, OnEmpty>,
672 OnEmpty: Get<QueryKind::Query> + 'static,
673 MaxValues: Get<Option<u32>>,
674{
675 fn partial_storage_info() -> Vec<StorageInfo> {
676 [
677 <Self as MapWrapper>::Map::partial_storage_info(),
678 CounterFor::<Prefix>::partial_storage_info(),
679 ]
680 .concat()
681 }
682}
683
684#[cfg(test)]
685mod test {
686 use super::*;
687 use crate::{
688 hash::{StorageHasher as _, *},
689 storage::types::{Key as NMapKey, ValueQuery},
690 };
691 use alloc::boxed::Box;
692 use sp_io::{hashing::twox_128, TestExternalities};
693 use sp_metadata_ir::{StorageEntryModifierIR, StorageEntryTypeIR, StorageHasherIR};
694
695 struct Prefix;
696 impl StorageInstance for Prefix {
697 fn pallet_prefix() -> &'static str {
698 "test"
699 }
700 const STORAGE_PREFIX: &'static str = "Foo";
701 }
702 impl CountedStorageNMapInstance for Prefix {
703 type CounterPrefix = Prefix;
704 }
705
706 struct ADefault;
707 impl crate::traits::Get<u32> for ADefault {
708 fn get() -> u32 {
709 98
710 }
711 }
712
713 #[test]
714 fn test_1_key() {
715 type A = CountedStorageNMap<Prefix, NMapKey<Blake2_128Concat, u16>, u32, OptionQuery>;
716 type AValueQueryWithAnOnEmpty =
717 CountedStorageNMap<Prefix, NMapKey<Blake2_128Concat, u16>, u32, ValueQuery, ADefault>;
718 type B = CountedStorageNMap<Prefix, NMapKey<Blake2_256, u16>, u32, ValueQuery>;
719 type C = CountedStorageNMap<Prefix, NMapKey<Blake2_128Concat, u16>, u8, ValueQuery>;
720 type WithLen = CountedStorageNMap<Prefix, NMapKey<Blake2_128Concat, u16>, Vec<u32>>;
721
722 TestExternalities::default().execute_with(|| {
723 let mut k: Vec<u8> = vec![];
724 k.extend(&twox_128(b"test"));
725 k.extend(&twox_128(b"Foo"));
726 k.extend(&3u16.blake2_128_concat());
727 assert_eq!(A::hashed_key_for((&3,)).to_vec(), k);
728
729 assert_eq!(A::contains_key((3,)), false);
730 assert_eq!(A::get((3,)), None);
731 assert_eq!(AValueQueryWithAnOnEmpty::get((3,)), 98);
732 assert_eq!(A::count(), 0);
733
734 A::insert((3,), 10);
735 assert_eq!(A::contains_key((3,)), true);
736 assert_eq!(A::get((3,)), Some(10));
737 assert_eq!(AValueQueryWithAnOnEmpty::get((3,)), 10);
738 assert_eq!(A::count(), 1);
739
740 A::swap::<NMapKey<Blake2_128Concat, u16>, _, _>((3,), (2,));
741 assert_eq!(A::contains_key((3,)), false);
742 assert_eq!(A::contains_key((2,)), true);
743 assert_eq!(A::get((3,)), None);
744 assert_eq!(AValueQueryWithAnOnEmpty::get((3,)), 98);
745 assert_eq!(A::get((2,)), Some(10));
746 assert_eq!(AValueQueryWithAnOnEmpty::get((2,)), 10);
747 assert_eq!(A::count(), 1);
748
749 A::remove((2,));
750 assert_eq!(A::contains_key((2,)), false);
751 assert_eq!(A::get((2,)), None);
752 assert_eq!(A::count(), 0);
753
754 AValueQueryWithAnOnEmpty::mutate((2,), |v| *v = *v * 2);
755 AValueQueryWithAnOnEmpty::mutate((2,), |v| *v = *v * 2);
756 assert_eq!(A::contains_key((2,)), true);
757 assert_eq!(A::get((2,)), Some(98 * 4));
758 assert_eq!(A::count(), 1);
759
760 A::remove((2,));
761 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate((2,), |v| {
762 *v = *v * 2;
763 Ok(())
764 });
765 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate((2,), |v| {
766 *v = *v * 2;
767 Ok(())
768 });
769 assert_eq!(A::contains_key((2,)), true);
770 assert_eq!(A::get((2,)), Some(98 * 4));
771 assert_eq!(A::count(), 1);
772
773 A::remove((2,));
774 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate((2,), |v| {
775 *v = *v * 2;
776 Err(())
777 });
778 assert_eq!(A::contains_key((2,)), false);
779 assert_eq!(A::count(), 0);
780
781 A::remove((2,));
782 AValueQueryWithAnOnEmpty::mutate_exists((2,), |v| {
783 assert!(v.is_none());
784 *v = Some(10);
785 });
786 assert_eq!(A::contains_key((2,)), true);
787 assert_eq!(A::get((2,)), Some(10));
788 AValueQueryWithAnOnEmpty::mutate_exists((2,), |v| {
789 *v = Some(v.unwrap() * 10);
790 });
791 assert_eq!(A::contains_key((2,)), true);
792 assert_eq!(A::get((2,)), Some(100));
793 assert_eq!(A::count(), 1);
794
795 A::remove((2,));
796 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists((2,), |v| {
797 assert!(v.is_none());
798 *v = Some(10);
799 Ok(())
800 });
801 assert_eq!(A::contains_key((2,)), true);
802 assert_eq!(A::get((2,)), Some(10));
803 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists((2,), |v| {
804 *v = Some(v.unwrap() * 10);
805 Ok(())
806 });
807 assert_eq!(A::contains_key((2,)), true);
808 assert_eq!(A::get((2,)), Some(100));
809 assert_eq!(A::try_get((2,)), Ok(100));
810 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists((2,), |v| {
811 *v = Some(v.unwrap() * 10);
812 Err(())
813 });
814 assert_eq!(A::contains_key((2,)), true);
815 assert_eq!(A::get((2,)), Some(100));
816 assert_eq!(A::count(), 1);
817
818 A::insert((2,), 10);
819 assert_eq!(A::take((2,)), Some(10));
820 assert_eq!(A::contains_key((2,)), false);
821 assert_eq!(AValueQueryWithAnOnEmpty::take((2,)), 98);
822 assert_eq!(A::contains_key((2,)), false);
823 assert_eq!(A::try_get((2,)), Err(()));
824 assert_eq!(A::count(), 0);
825
826 B::insert((2,), 10);
827 assert_eq!(
828 A::migrate_keys((2,), (Box::new(|key| Blake2_256::hash(key).to_vec()),),),
829 Some(10)
830 );
831 assert_eq!(A::contains_key((2,)), true);
832 assert_eq!(A::get((2,)), Some(10));
833 assert_eq!(A::count(), 1);
834
835 A::insert((3,), 10);
836 A::insert((4,), 10);
837 assert_eq!(A::count(), 3);
838 let _ = A::clear(u32::max_value(), None);
839 assert!(!A::contains_key((2,)) && !A::contains_key((3,)) && !A::contains_key((4,)));
840 assert_eq!(A::count(), 0);
841
842 A::insert((3,), 10);
843 A::insert((4,), 10);
844 assert_eq!(A::iter_values().collect::<Vec<_>>(), vec![10, 10]);
845 assert_eq!(A::count(), 2);
846
847 C::insert((3,), 10);
848 C::insert((4,), 10);
849 A::translate_values::<u8, _>(|v| Some((v * 2).into()));
850 assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 20), (3, 20)]);
851 assert_eq!(A::count(), 2);
852
853 A::insert((3,), 10);
854 A::insert((4,), 10);
855 assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 10), (3, 10)]);
856 assert_eq!(A::drain().collect::<Vec<_>>(), vec![(4, 10), (3, 10)]);
857 assert_eq!(A::iter().collect::<Vec<_>>(), vec![]);
858 assert_eq!(A::count(), 0);
859
860 C::insert((3,), 10);
861 C::insert((4,), 10);
862 A::translate::<u8, _>(|k1, v| Some((k1 as u16 * v as u16).into()));
863 assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 40), (3, 30)]);
864 assert_eq!(A::count(), 2);
865
866 let mut entries = vec![];
867 A::build_metadata(
868 sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
869 vec![],
870 &mut entries,
871 );
872 AValueQueryWithAnOnEmpty::build_metadata(
873 sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
874 vec![],
875 &mut entries,
876 );
877 assert_eq!(
878 entries,
879 vec![
880 StorageEntryMetadataIR {
881 name: "Foo",
882 modifier: StorageEntryModifierIR::Optional,
883 ty: StorageEntryTypeIR::Map {
884 hashers: vec![StorageHasherIR::Blake2_128Concat],
885 key: scale_info::meta_type::<u16>(),
886 value: scale_info::meta_type::<u32>(),
887 },
888 default: Option::<u32>::None.encode(),
889 docs: vec![],
890 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
891 },
892 StorageEntryMetadataIR {
893 name: "Foo",
894 modifier: StorageEntryModifierIR::Default,
895 ty: StorageEntryTypeIR::Plain(scale_info::meta_type::<u32>()),
896 default: vec![0, 0, 0, 0],
897 docs: if cfg!(feature = "no-metadata-docs") {
898 vec![]
899 } else {
900 vec!["Counter for the related counted storage map"]
901 },
902 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
903 },
904 StorageEntryMetadataIR {
905 name: "Foo",
906 modifier: StorageEntryModifierIR::Default,
907 ty: StorageEntryTypeIR::Map {
908 hashers: vec![StorageHasherIR::Blake2_128Concat],
909 key: scale_info::meta_type::<u16>(),
910 value: scale_info::meta_type::<u32>(),
911 },
912 default: 98u32.encode(),
913 docs: vec![],
914 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
915 },
916 StorageEntryMetadataIR {
917 name: "Foo",
918 modifier: StorageEntryModifierIR::Default,
919 ty: StorageEntryTypeIR::Plain(scale_info::meta_type::<u32>()),
920 default: vec![0, 0, 0, 0],
921 docs: if cfg!(feature = "no-metadata-docs") {
922 vec![]
923 } else {
924 vec!["Counter for the related counted storage map"]
925 },
926 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
927 },
928 ]
929 );
930
931 let _ = WithLen::clear(u32::max_value(), None);
932 assert_eq!(WithLen::decode_len((3,)), None);
933 WithLen::append((0,), 10);
934 assert_eq!(WithLen::decode_len((0,)), Some(1));
935 });
936 }
937
938 #[test]
939 fn test_2_keys() {
940 type A = CountedStorageNMap<
941 Prefix,
942 (NMapKey<Blake2_128Concat, u16>, NMapKey<Twox64Concat, u8>),
943 u32,
944 OptionQuery,
945 >;
946 type AValueQueryWithAnOnEmpty = CountedStorageNMap<
947 Prefix,
948 (NMapKey<Blake2_128Concat, u16>, NMapKey<Twox64Concat, u8>),
949 u32,
950 ValueQuery,
951 ADefault,
952 >;
953 type B = CountedStorageNMap<
954 Prefix,
955 (NMapKey<Blake2_256, u16>, NMapKey<Twox128, u8>),
956 u32,
957 ValueQuery,
958 >;
959 type C = CountedStorageNMap<
960 Prefix,
961 (NMapKey<Blake2_128Concat, u16>, NMapKey<Twox64Concat, u8>),
962 u8,
963 ValueQuery,
964 >;
965 type WithLen = CountedStorageNMap<
966 Prefix,
967 (NMapKey<Blake2_128Concat, u16>, NMapKey<Twox64Concat, u8>),
968 Vec<u32>,
969 >;
970
971 TestExternalities::default().execute_with(|| {
972 let mut k: Vec<u8> = vec![];
973 k.extend(&twox_128(b"test"));
974 k.extend(&twox_128(b"Foo"));
975 k.extend(&3u16.blake2_128_concat());
976 k.extend(&30u8.twox_64_concat());
977 assert_eq!(A::hashed_key_for((3, 30)).to_vec(), k);
978
979 assert_eq!(A::contains_key((3, 30)), false);
980 assert_eq!(A::get((3, 30)), None);
981 assert_eq!(AValueQueryWithAnOnEmpty::get((3, 30)), 98);
982 assert_eq!(A::count(), 0);
983
984 A::insert((3, 30), 10);
985 assert_eq!(A::contains_key((3, 30)), true);
986 assert_eq!(A::get((3, 30)), Some(10));
987 assert_eq!(AValueQueryWithAnOnEmpty::get((3, 30)), 10);
988 assert_eq!(A::count(), 1);
989
990 A::swap::<(NMapKey<Blake2_128Concat, u16>, NMapKey<Twox64Concat, u8>), _, _>(
991 (3, 30),
992 (2, 20),
993 );
994 assert_eq!(A::contains_key((3, 30)), false);
995 assert_eq!(A::contains_key((2, 20)), true);
996 assert_eq!(A::get((3, 30)), None);
997 assert_eq!(AValueQueryWithAnOnEmpty::get((3, 30)), 98);
998 assert_eq!(A::get((2, 20)), Some(10));
999 assert_eq!(AValueQueryWithAnOnEmpty::get((2, 20)), 10);
1000 assert_eq!(A::count(), 1);
1001
1002 A::remove((2, 20));
1003 assert_eq!(A::contains_key((2, 20)), false);
1004 assert_eq!(A::get((2, 20)), None);
1005 assert_eq!(A::count(), 0);
1006
1007 AValueQueryWithAnOnEmpty::mutate((2, 20), |v| *v = *v * 2);
1008 AValueQueryWithAnOnEmpty::mutate((2, 20), |v| *v = *v * 2);
1009 assert_eq!(A::contains_key((2, 20)), true);
1010 assert_eq!(A::get((2, 20)), Some(98 * 4));
1011 assert_eq!(A::count(), 1);
1012
1013 A::remove((2, 20));
1014 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate((2, 20), |v| {
1015 *v = *v * 2;
1016 Err(())
1017 });
1018 assert_eq!(A::contains_key((2, 20)), false);
1019 assert_eq!(A::count(), 0);
1020
1021 A::remove((2, 20));
1022 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate((2, 20), |v| {
1023 *v = *v * 2;
1024 Err(())
1025 });
1026 assert_eq!(A::contains_key((2, 20)), false);
1027 assert_eq!(A::count(), 0);
1028
1029 A::remove((2, 20));
1030 AValueQueryWithAnOnEmpty::mutate_exists((2, 20), |v| {
1031 assert!(v.is_none());
1032 *v = Some(10);
1033 });
1034 assert_eq!(A::contains_key((2, 20)), true);
1035 assert_eq!(A::get((2, 20)), Some(10));
1036 assert_eq!(A::count(), 1);
1037 AValueQueryWithAnOnEmpty::mutate_exists((2, 20), |v| {
1038 *v = Some(v.unwrap() * 10);
1039 });
1040 assert_eq!(A::contains_key((2, 20)), true);
1041 assert_eq!(A::get((2, 20)), Some(100));
1042 assert_eq!(A::count(), 1);
1043
1044 A::remove((2, 20));
1045 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists((2, 20), |v| {
1046 assert!(v.is_none());
1047 *v = Some(10);
1048 Ok(())
1049 });
1050 assert_eq!(A::contains_key((2, 20)), true);
1051 assert_eq!(A::get((2, 20)), Some(10));
1052 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists((2, 20), |v| {
1053 *v = Some(v.unwrap() * 10);
1054 Ok(())
1055 });
1056 assert_eq!(A::contains_key((2, 20)), true);
1057 assert_eq!(A::get((2, 20)), Some(100));
1058 assert_eq!(A::try_get((2, 20)), Ok(100));
1059 assert_eq!(A::count(), 1);
1060 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists((2, 20), |v| {
1061 *v = Some(v.unwrap() * 10);
1062 Err(())
1063 });
1064 assert_eq!(A::contains_key((2, 20)), true);
1065 assert_eq!(A::get((2, 20)), Some(100));
1066 assert_eq!(A::count(), 1);
1067
1068 A::insert((2, 20), 10);
1069 assert_eq!(A::take((2, 20)), Some(10));
1070 assert_eq!(A::contains_key((2, 20)), false);
1071 assert_eq!(AValueQueryWithAnOnEmpty::take((2, 20)), 98);
1072 assert_eq!(A::contains_key((2, 20)), false);
1073 assert_eq!(A::try_get((2, 20)), Err(()));
1074 assert_eq!(A::count(), 0);
1075
1076 B::insert((2, 20), 10);
1077 assert_eq!(
1078 A::migrate_keys(
1079 (2, 20),
1080 (
1081 Box::new(|key| Blake2_256::hash(key).to_vec()),
1082 Box::new(|key| Twox128::hash(key).to_vec()),
1083 ),
1084 ),
1085 Some(10)
1086 );
1087 assert_eq!(A::contains_key((2, 20)), true);
1088 assert_eq!(A::get((2, 20)), Some(10));
1089 assert_eq!(A::count(), 1);
1090
1091 A::insert((3, 30), 10);
1092 A::insert((4, 40), 10);
1093 assert_eq!(A::count(), 3);
1094 let _ = A::clear(u32::max_value(), None);
1095 assert!(
1097 !A::contains_key((2, 20)) && !A::contains_key((3, 30)) && !A::contains_key((4, 40))
1098 );
1099 assert_eq!(A::count(), 0);
1100
1101 assert_eq!(A::count(), 0);
1102
1103 A::insert((3, 30), 10);
1104 A::insert((4, 40), 10);
1105 assert_eq!(A::iter_values().collect::<Vec<_>>(), vec![10, 10]);
1106 assert_eq!(A::count(), 2);
1107
1108 C::insert((3, 30), 10);
1109 C::insert((4, 40), 10);
1110 A::translate_values::<u8, _>(|v| Some((v * 2).into()));
1111 assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40), 20), ((3, 30), 20)]);
1112 assert_eq!(A::count(), 2);
1113
1114 A::insert((3, 30), 10);
1115 A::insert((4, 40), 10);
1116 assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40), 10), ((3, 30), 10)]);
1117 assert_eq!(A::drain().collect::<Vec<_>>(), vec![((4, 40), 10), ((3, 30), 10)]);
1118 assert_eq!(A::iter().collect::<Vec<_>>(), vec![]);
1119 assert_eq!(A::count(), 0);
1120
1121 C::insert((3, 30), 10);
1122 C::insert((4, 40), 10);
1123 A::translate::<u8, _>(|(k1, k2), v| Some((k1 * k2 as u16 * v as u16).into()));
1124 assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40), 1600), ((3, 30), 900)]);
1125 assert_eq!(A::count(), 2);
1126
1127 let mut entries = vec![];
1128 A::build_metadata(
1129 sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1130 vec![],
1131 &mut entries,
1132 );
1133 AValueQueryWithAnOnEmpty::build_metadata(
1134 sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1135 vec![],
1136 &mut entries,
1137 );
1138 assert_eq!(
1139 entries,
1140 vec![
1141 StorageEntryMetadataIR {
1142 name: "Foo",
1143 modifier: StorageEntryModifierIR::Optional,
1144 ty: StorageEntryTypeIR::Map {
1145 hashers: vec![
1146 StorageHasherIR::Blake2_128Concat,
1147 StorageHasherIR::Twox64Concat
1148 ],
1149 key: scale_info::meta_type::<(u16, u8)>(),
1150 value: scale_info::meta_type::<u32>(),
1151 },
1152 default: Option::<u32>::None.encode(),
1153 docs: vec![],
1154 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1155 },
1156 StorageEntryMetadataIR {
1157 name: "Foo",
1158 modifier: StorageEntryModifierIR::Default,
1159 ty: StorageEntryTypeIR::Plain(scale_info::meta_type::<u32>()),
1160 default: vec![0, 0, 0, 0],
1161 docs: if cfg!(feature = "no-metadata-docs") {
1162 vec![]
1163 } else {
1164 vec!["Counter for the related counted storage map"]
1165 },
1166 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1167 },
1168 StorageEntryMetadataIR {
1169 name: "Foo",
1170 modifier: StorageEntryModifierIR::Default,
1171 ty: StorageEntryTypeIR::Map {
1172 hashers: vec![
1173 StorageHasherIR::Blake2_128Concat,
1174 StorageHasherIR::Twox64Concat
1175 ],
1176 key: scale_info::meta_type::<(u16, u8)>(),
1177 value: scale_info::meta_type::<u32>(),
1178 },
1179 default: 98u32.encode(),
1180 docs: vec![],
1181 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1182 },
1183 StorageEntryMetadataIR {
1184 name: "Foo",
1185 modifier: StorageEntryModifierIR::Default,
1186 ty: StorageEntryTypeIR::Plain(scale_info::meta_type::<u32>()),
1187 default: vec![0, 0, 0, 0],
1188 docs: if cfg!(feature = "no-metadata-docs") {
1189 vec![]
1190 } else {
1191 vec!["Counter for the related counted storage map"]
1192 },
1193 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1194 },
1195 ]
1196 );
1197
1198 let _ = WithLen::clear(u32::max_value(), None);
1199 assert_eq!(WithLen::decode_len((3, 30)), None);
1200 WithLen::append((0, 100), 10);
1201 assert_eq!(WithLen::decode_len((0, 100)), Some(1));
1202
1203 A::insert((3, 30), 11);
1204 A::insert((3, 31), 12);
1205 A::insert((4, 40), 13);
1206 A::insert((4, 41), 14);
1207 assert_eq!(A::iter_prefix_values((3,)).collect::<Vec<_>>(), vec![12, 11]);
1208 assert_eq!(A::iter_prefix_values((4,)).collect::<Vec<_>>(), vec![13, 14]);
1209 assert_eq!(A::count(), 5);
1210 });
1211 }
1212
1213 #[test]
1214 fn test_3_keys() {
1215 type A = CountedStorageNMap<
1216 Prefix,
1217 (
1218 NMapKey<Blake2_128Concat, u16>,
1219 NMapKey<Blake2_128Concat, u16>,
1220 NMapKey<Twox64Concat, u16>,
1221 ),
1222 u32,
1223 OptionQuery,
1224 >;
1225 type AValueQueryWithAnOnEmpty = CountedStorageNMap<
1226 Prefix,
1227 (
1228 NMapKey<Blake2_128Concat, u16>,
1229 NMapKey<Blake2_128Concat, u16>,
1230 NMapKey<Twox64Concat, u16>,
1231 ),
1232 u32,
1233 ValueQuery,
1234 ADefault,
1235 >;
1236 type B = CountedStorageNMap<
1237 Prefix,
1238 (NMapKey<Blake2_256, u16>, NMapKey<Blake2_256, u16>, NMapKey<Twox128, u16>),
1239 u32,
1240 ValueQuery,
1241 >;
1242 type C = CountedStorageNMap<
1243 Prefix,
1244 (
1245 NMapKey<Blake2_128Concat, u16>,
1246 NMapKey<Blake2_128Concat, u16>,
1247 NMapKey<Twox64Concat, u16>,
1248 ),
1249 u8,
1250 ValueQuery,
1251 >;
1252 type WithLen = CountedStorageNMap<
1253 Prefix,
1254 (
1255 NMapKey<Blake2_128Concat, u16>,
1256 NMapKey<Blake2_128Concat, u16>,
1257 NMapKey<Twox64Concat, u16>,
1258 ),
1259 Vec<u32>,
1260 >;
1261
1262 TestExternalities::default().execute_with(|| {
1263 let mut k: Vec<u8> = vec![];
1264 k.extend(&twox_128(b"test"));
1265 k.extend(&twox_128(b"Foo"));
1266 k.extend(&1u16.blake2_128_concat());
1267 k.extend(&10u16.blake2_128_concat());
1268 k.extend(&100u16.twox_64_concat());
1269 assert_eq!(A::hashed_key_for((1, 10, 100)).to_vec(), k);
1270
1271 assert_eq!(A::contains_key((1, 10, 100)), false);
1272 assert_eq!(A::get((1, 10, 100)), None);
1273 assert_eq!(AValueQueryWithAnOnEmpty::get((1, 10, 100)), 98);
1274 assert_eq!(A::count(), 0);
1275
1276 A::insert((1, 10, 100), 30);
1277 assert_eq!(A::contains_key((1, 10, 100)), true);
1278 assert_eq!(A::get((1, 10, 100)), Some(30));
1279 assert_eq!(AValueQueryWithAnOnEmpty::get((1, 10, 100)), 30);
1280 assert_eq!(A::count(), 1);
1281
1282 A::swap::<
1283 (
1284 NMapKey<Blake2_128Concat, u16>,
1285 NMapKey<Blake2_128Concat, u16>,
1286 NMapKey<Twox64Concat, u16>,
1287 ),
1288 _,
1289 _,
1290 >((1, 10, 100), (2, 20, 200));
1291 assert_eq!(A::contains_key((1, 10, 100)), false);
1292 assert_eq!(A::contains_key((2, 20, 200)), true);
1293 assert_eq!(A::get((1, 10, 100)), None);
1294 assert_eq!(AValueQueryWithAnOnEmpty::get((1, 10, 100)), 98);
1295 assert_eq!(A::get((2, 20, 200)), Some(30));
1296 assert_eq!(AValueQueryWithAnOnEmpty::get((2, 20, 200)), 30);
1297 assert_eq!(A::count(), 1);
1298
1299 A::remove((2, 20, 200));
1300 assert_eq!(A::contains_key((2, 20, 200)), false);
1301 assert_eq!(A::get((2, 20, 200)), None);
1302 assert_eq!(A::count(), 0);
1303
1304 AValueQueryWithAnOnEmpty::mutate((2, 20, 200), |v| *v = *v * 2);
1305 AValueQueryWithAnOnEmpty::mutate((2, 20, 200), |v| *v = *v * 2);
1306 assert_eq!(A::contains_key((2, 20, 200)), true);
1307 assert_eq!(A::get((2, 20, 200)), Some(98 * 4));
1308 assert_eq!(A::count(), 1);
1309
1310 A::remove((2, 20, 200));
1311 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate((2, 20, 200), |v| {
1312 *v = *v * 2;
1313 Err(())
1314 });
1315 assert_eq!(A::contains_key((2, 20, 200)), false);
1316 assert_eq!(A::count(), 0);
1317
1318 A::remove((2, 20, 200));
1319 AValueQueryWithAnOnEmpty::mutate_exists((2, 20, 200), |v| {
1320 assert!(v.is_none());
1321 *v = Some(10);
1322 });
1323 assert_eq!(A::contains_key((2, 20, 200)), true);
1324 assert_eq!(A::get((2, 20, 200)), Some(10));
1325 assert_eq!(A::count(), 1);
1326 AValueQueryWithAnOnEmpty::mutate_exists((2, 20, 200), |v| {
1327 *v = Some(v.unwrap() * 10);
1328 });
1329 assert_eq!(A::contains_key((2, 20, 200)), true);
1330 assert_eq!(A::get((2, 20, 200)), Some(100));
1331 assert_eq!(A::count(), 1);
1332
1333 A::remove((2, 20, 200));
1334 let _: Result<(), ()> =
1335 AValueQueryWithAnOnEmpty::try_mutate_exists((2, 20, 200), |v| {
1336 assert!(v.is_none());
1337 *v = Some(10);
1338 Ok(())
1339 });
1340 assert_eq!(A::contains_key((2, 20, 200)), true);
1341 assert_eq!(A::get((2, 20, 200)), Some(10));
1342 let _: Result<(), ()> =
1343 AValueQueryWithAnOnEmpty::try_mutate_exists((2, 20, 200), |v| {
1344 *v = Some(v.unwrap() * 10);
1345 Ok(())
1346 });
1347 assert_eq!(A::contains_key((2, 20, 200)), true);
1348 assert_eq!(A::get((2, 20, 200)), Some(100));
1349 assert_eq!(A::try_get((2, 20, 200)), Ok(100));
1350 assert_eq!(A::count(), 1);
1351 let _: Result<(), ()> =
1352 AValueQueryWithAnOnEmpty::try_mutate_exists((2, 20, 200), |v| {
1353 *v = Some(v.unwrap() * 10);
1354 Err(())
1355 });
1356 assert_eq!(A::contains_key((2, 20, 200)), true);
1357 assert_eq!(A::get((2, 20, 200)), Some(100));
1358 assert_eq!(A::count(), 1);
1359
1360 A::insert((2, 20, 200), 10);
1361 assert_eq!(A::take((2, 20, 200)), Some(10));
1362 assert_eq!(A::contains_key((2, 20, 200)), false);
1363 assert_eq!(AValueQueryWithAnOnEmpty::take((2, 20, 200)), 98);
1364 assert_eq!(A::contains_key((2, 20, 200)), false);
1365 assert_eq!(A::try_get((2, 20, 200)), Err(()));
1366 assert_eq!(A::count(), 0);
1367
1368 B::insert((2, 20, 200), 10);
1369 assert_eq!(
1370 A::migrate_keys(
1371 (2, 20, 200),
1372 (
1373 Box::new(|key| Blake2_256::hash(key).to_vec()),
1374 Box::new(|key| Blake2_256::hash(key).to_vec()),
1375 Box::new(|key| Twox128::hash(key).to_vec()),
1376 ),
1377 ),
1378 Some(10)
1379 );
1380 assert_eq!(A::contains_key((2, 20, 200)), true);
1381 assert_eq!(A::get((2, 20, 200)), Some(10));
1382 assert_eq!(A::count(), 1);
1383
1384 A::insert((3, 30, 300), 10);
1385 A::insert((4, 40, 400), 10);
1386 assert_eq!(A::count(), 3);
1387 let _ = A::clear(u32::max_value(), None);
1388 assert!(
1390 !A::contains_key((2, 20, 200)) &&
1391 !A::contains_key((3, 30, 300)) &&
1392 !A::contains_key((4, 40, 400))
1393 );
1394 assert_eq!(A::count(), 0);
1395
1396 A::insert((3, 30, 300), 10);
1397 A::insert((4, 40, 400), 10);
1398 assert_eq!(A::iter_values().collect::<Vec<_>>(), vec![10, 10]);
1399 assert_eq!(A::count(), 2);
1400
1401 C::insert((3, 30, 300), 10);
1402 C::insert((4, 40, 400), 10);
1403 A::translate_values::<u8, _>(|v| Some((v * 2).into()));
1404 assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40, 400), 20), ((3, 30, 300), 20)]);
1405 assert_eq!(A::count(), 2);
1406
1407 A::insert((3, 30, 300), 10);
1408 A::insert((4, 40, 400), 10);
1409 assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40, 400), 10), ((3, 30, 300), 10)]);
1410 assert_eq!(
1411 A::drain().collect::<Vec<_>>(),
1412 vec![((4, 40, 400), 10), ((3, 30, 300), 10)]
1413 );
1414 assert_eq!(A::iter().collect::<Vec<_>>(), vec![]);
1415 assert_eq!(A::count(), 0);
1416
1417 C::insert((3, 30, 300), 10);
1418 C::insert((4, 40, 400), 10);
1419 A::translate::<u8, _>(|(k1, k2, k3), v| {
1420 Some((k1 * k2 as u16 * v as u16 / k3 as u16).into())
1421 });
1422 assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40, 400), 4), ((3, 30, 300), 3)]);
1423 assert_eq!(A::count(), 2);
1424
1425 let mut entries = vec![];
1426 A::build_metadata(
1427 sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1428 vec![],
1429 &mut entries,
1430 );
1431 AValueQueryWithAnOnEmpty::build_metadata(
1432 sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1433 vec![],
1434 &mut entries,
1435 );
1436 assert_eq!(
1437 entries,
1438 vec![
1439 StorageEntryMetadataIR {
1440 name: "Foo",
1441 modifier: StorageEntryModifierIR::Optional,
1442 ty: StorageEntryTypeIR::Map {
1443 hashers: vec![
1444 StorageHasherIR::Blake2_128Concat,
1445 StorageHasherIR::Blake2_128Concat,
1446 StorageHasherIR::Twox64Concat
1447 ],
1448 key: scale_info::meta_type::<(u16, u16, u16)>(),
1449 value: scale_info::meta_type::<u32>(),
1450 },
1451 default: Option::<u32>::None.encode(),
1452 docs: vec![],
1453 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1454 },
1455 StorageEntryMetadataIR {
1456 name: "Foo",
1457 modifier: StorageEntryModifierIR::Default,
1458 ty: StorageEntryTypeIR::Plain(scale_info::meta_type::<u32>()),
1459 default: vec![0, 0, 0, 0],
1460 docs: if cfg!(feature = "no-metadata-docs") {
1461 vec![]
1462 } else {
1463 vec!["Counter for the related counted storage map"]
1464 },
1465 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1466 },
1467 StorageEntryMetadataIR {
1468 name: "Foo",
1469 modifier: StorageEntryModifierIR::Default,
1470 ty: StorageEntryTypeIR::Map {
1471 hashers: vec![
1472 StorageHasherIR::Blake2_128Concat,
1473 StorageHasherIR::Blake2_128Concat,
1474 StorageHasherIR::Twox64Concat
1475 ],
1476 key: scale_info::meta_type::<(u16, u16, u16)>(),
1477 value: scale_info::meta_type::<u32>(),
1478 },
1479 default: 98u32.encode(),
1480 docs: vec![],
1481 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1482 },
1483 StorageEntryMetadataIR {
1484 name: "Foo",
1485 modifier: StorageEntryModifierIR::Default,
1486 ty: StorageEntryTypeIR::Plain(scale_info::meta_type::<u32>()),
1487 default: vec![0, 0, 0, 0],
1488 docs: if cfg!(feature = "no-metadata-docs") {
1489 vec![]
1490 } else {
1491 vec!["Counter for the related counted storage map"]
1492 },
1493 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1494 },
1495 ]
1496 );
1497
1498 let _ = WithLen::clear(u32::max_value(), None);
1499 assert_eq!(WithLen::decode_len((3, 30, 300)), None);
1500 WithLen::append((0, 100, 1000), 10);
1501 assert_eq!(WithLen::decode_len((0, 100, 1000)), Some(1));
1502
1503 A::insert((3, 30, 300), 11);
1504 A::insert((3, 30, 301), 12);
1505 A::insert((4, 40, 400), 13);
1506 A::insert((4, 40, 401), 14);
1507 assert_eq!(A::iter_prefix_values((3,)).collect::<Vec<_>>(), vec![11, 12]);
1508 assert_eq!(A::iter_prefix_values((4,)).collect::<Vec<_>>(), vec![14, 13]);
1509 assert_eq!(A::iter_prefix_values((3, 30)).collect::<Vec<_>>(), vec![11, 12]);
1510 assert_eq!(A::iter_prefix_values((4, 40)).collect::<Vec<_>>(), vec![14, 13]);
1511 assert_eq!(A::count(), 5);
1512 });
1513 }
1514}