1use crate::{
22 storage::{
23 types::{
24 EncodeLikeTuple, HasKeyPrefix, HasReversibleKeyPrefix, OptionQuery, QueryKindTrait,
25 StorageEntryMetadataBuilder, TupleToEncodedIter,
26 },
27 KeyGenerator, PrefixIterator, StorageAppend, StorageDecodeLength, StoragePrefixedMap,
28 StorageTryAppend,
29 },
30 traits::{Get, GetDefault, StorageInfo, StorageInstance},
31};
32use alloc::{vec, vec::Vec};
33use codec::{Decode, Encode, EncodeLike, FullCodec, MaxEncodedLen};
34use sp_metadata_ir::{StorageEntryMetadataIR, StorageEntryTypeIR};
35use sp_runtime::SaturatedConversion;
36
37pub struct StorageNMap<
86 Prefix,
87 Key,
88 Value,
89 QueryKind = OptionQuery,
90 OnEmpty = GetDefault,
91 MaxValues = GetDefault,
92>(core::marker::PhantomData<(Prefix, Key, Value, QueryKind, OnEmpty, MaxValues)>);
93
94impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
95 crate::storage::generator::StorageNMap<Key, Value>
96 for StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
97where
98 Prefix: StorageInstance,
99 Key: super::key::KeyGenerator,
100 Value: FullCodec,
101 QueryKind: QueryKindTrait<Value, OnEmpty>,
102 OnEmpty: Get<QueryKind::Query> + 'static,
103 MaxValues: Get<Option<u32>>,
104{
105 type Query = QueryKind::Query;
106 fn pallet_prefix() -> &'static [u8] {
107 Prefix::pallet_prefix().as_bytes()
108 }
109 fn storage_prefix() -> &'static [u8] {
110 Prefix::STORAGE_PREFIX.as_bytes()
111 }
112 fn prefix_hash() -> [u8; 32] {
113 Prefix::prefix_hash()
114 }
115 fn from_optional_value_to_query(v: Option<Value>) -> Self::Query {
116 QueryKind::from_optional_value_to_query(v)
117 }
118 fn from_query_to_optional_value(v: Self::Query) -> Option<Value> {
119 QueryKind::from_query_to_optional_value(v)
120 }
121}
122
123impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues> crate::storage::StoragePrefixedMap<Value>
124 for StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
125where
126 Prefix: StorageInstance,
127 Key: super::key::KeyGenerator,
128 Value: FullCodec,
129 QueryKind: QueryKindTrait<Value, OnEmpty>,
130 OnEmpty: Get<QueryKind::Query> + 'static,
131 MaxValues: Get<Option<u32>>,
132{
133 fn pallet_prefix() -> &'static [u8] {
134 <Self as crate::storage::generator::StorageNMap<Key, Value>>::pallet_prefix()
135 }
136 fn storage_prefix() -> &'static [u8] {
137 <Self as crate::storage::generator::StorageNMap<Key, Value>>::storage_prefix()
138 }
139}
140
141impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
142 StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
143where
144 Prefix: StorageInstance,
145 Key: super::key::KeyGenerator,
146 Value: FullCodec,
147 QueryKind: QueryKindTrait<Value, OnEmpty>,
148 OnEmpty: Get<QueryKind::Query> + 'static,
149 MaxValues: Get<Option<u32>>,
150{
151 pub fn hashed_key_for<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
153 key: KArg,
154 ) -> Vec<u8> {
155 <Self as crate::storage::StorageNMap<Key, Value>>::hashed_key_for(key)
156 }
157
158 pub fn contains_key<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(key: KArg) -> bool {
160 <Self as crate::storage::StorageNMap<Key, Value>>::contains_key(key)
161 }
162
163 pub fn get<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
165 key: KArg,
166 ) -> QueryKind::Query {
167 <Self as crate::storage::StorageNMap<Key, Value>>::get(key)
168 }
169
170 pub fn try_get<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
174 key: KArg,
175 ) -> Result<Value, ()> {
176 <Self as crate::storage::StorageNMap<Key, Value>>::try_get(key)
177 }
178
179 pub fn set<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
181 key: KArg,
182 query: QueryKind::Query,
183 ) {
184 <Self as crate::storage::StorageNMap<Key, Value>>::set(key, query)
185 }
186
187 pub fn take<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
189 key: KArg,
190 ) -> QueryKind::Query {
191 <Self as crate::storage::StorageNMap<Key, Value>>::take(key)
192 }
193
194 pub fn swap<KOther, KArg1, KArg2>(key1: KArg1, key2: KArg2)
196 where
197 KOther: KeyGenerator,
198 KArg1: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
199 KArg2: EncodeLikeTuple<KOther::KArg> + TupleToEncodedIter,
200 {
201 <Self as crate::storage::StorageNMap<Key, Value>>::swap::<KOther, _, _>(key1, key2)
202 }
203
204 pub fn insert<KArg, VArg>(key: KArg, val: VArg)
206 where
207 KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
208 VArg: EncodeLike<Value>,
209 {
210 <Self as crate::storage::StorageNMap<Key, Value>>::insert(key, val)
211 }
212
213 pub fn remove<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(key: KArg) {
215 <Self as crate::storage::StorageNMap<Key, Value>>::remove(key)
216 }
217
218 #[deprecated = "Use `clear_prefix` instead"]
231 pub fn remove_prefix<KP>(partial_key: KP, limit: Option<u32>) -> sp_io::KillStorageResult
232 where
233 Key: HasKeyPrefix<KP>,
234 {
235 #[allow(deprecated)]
236 <Self as crate::storage::StorageNMap<Key, Value>>::remove_prefix(partial_key, limit)
237 }
238
239 pub fn clear_prefix<KP>(
263 partial_key: KP,
264 limit: u32,
265 maybe_cursor: Option<&[u8]>,
266 ) -> sp_io::MultiRemovalResults
267 where
268 Key: HasKeyPrefix<KP>,
269 {
270 <Self as crate::storage::StorageNMap<Key, Value>>::clear_prefix(
271 partial_key,
272 limit,
273 maybe_cursor,
274 )
275 }
276
277 pub fn iter_prefix_values<KP>(partial_key: KP) -> PrefixIterator<Value>
279 where
280 Key: HasKeyPrefix<KP>,
281 {
282 <Self as crate::storage::StorageNMap<Key, Value>>::iter_prefix_values(partial_key)
283 }
284
285 pub fn mutate<KArg, R, F>(key: KArg, f: F) -> R
287 where
288 KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
289 F: FnOnce(&mut QueryKind::Query) -> R,
290 {
291 <Self as crate::storage::StorageNMap<Key, Value>>::mutate(key, f)
292 }
293
294 pub fn try_mutate<KArg, R, E, F>(key: KArg, f: F) -> Result<R, E>
296 where
297 KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
298 F: FnOnce(&mut QueryKind::Query) -> Result<R, E>,
299 {
300 <Self as crate::storage::StorageNMap<Key, Value>>::try_mutate(key, f)
301 }
302
303 pub fn mutate_exists<KArg, R, F>(key: KArg, f: F) -> R
305 where
306 KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
307 F: FnOnce(&mut Option<Value>) -> R,
308 {
309 <Self as crate::storage::StorageNMap<Key, Value>>::mutate_exists(key, f)
310 }
311
312 pub fn try_mutate_exists<KArg, R, E, F>(key: KArg, f: F) -> Result<R, E>
316 where
317 KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
318 F: FnOnce(&mut Option<Value>) -> Result<R, E>,
319 {
320 <Self as crate::storage::StorageNMap<Key, Value>>::try_mutate_exists(key, f)
321 }
322
323 pub fn append<Item, EncodeLikeItem, KArg>(key: KArg, item: EncodeLikeItem)
333 where
334 KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
335 Item: Encode,
336 EncodeLikeItem: EncodeLike<Item>,
337 Value: StorageAppend<Item>,
338 {
339 <Self as crate::storage::StorageNMap<Key, Value>>::append(key, item)
340 }
341
342 pub fn try_append<KArg, Item, EncodeLikeItem>(key: KArg, item: EncodeLikeItem) -> Result<(), ()>
346 where
347 KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter + Clone,
348 Item: Encode,
349 EncodeLikeItem: EncodeLike<Item>,
350 Value: StorageTryAppend<Item>,
351 {
352 <Self as crate::storage::TryAppendNMap<Key, Value, Item>>::try_append(key, item)
353 }
354
355 pub fn decode_len<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
368 key: KArg,
369 ) -> Option<usize>
370 where
371 Value: StorageDecodeLength,
372 {
373 <Self as crate::storage::StorageNMap<Key, Value>>::decode_len(key)
374 }
375
376 pub fn migrate_keys<KArg>(key: KArg, hash_fns: Key::HArg) -> Option<Value>
380 where
381 KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
382 {
383 <Self as crate::storage::StorageNMap<Key, Value>>::migrate_keys::<_>(key, hash_fns)
384 }
385
386 #[deprecated = "Use `clear` instead"]
398 pub fn remove_all(limit: Option<u32>) -> sp_io::KillStorageResult {
399 #[allow(deprecated)]
400 <Self as crate::storage::StoragePrefixedMap<Value>>::remove_all(limit).into()
401 }
402
403 pub fn clear(limit: u32, maybe_cursor: Option<&[u8]>) -> sp_io::MultiRemovalResults {
427 <Self as crate::storage::StoragePrefixedMap<Value>>::clear(limit, maybe_cursor)
428 }
429
430 pub fn iter_values() -> crate::storage::PrefixIterator<Value> {
434 <Self as crate::storage::StoragePrefixedMap<Value>>::iter_values()
435 }
436
437 pub fn translate_values<OldValue: Decode, F: FnMut(OldValue) -> Option<Value>>(f: F) {
451 <Self as crate::storage::StoragePrefixedMap<Value>>::translate_values(f)
452 }
453}
454
455impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
456 StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
457where
458 Prefix: StorageInstance,
459 Key: super::key::ReversibleKeyGenerator,
460 Value: FullCodec,
461 QueryKind: QueryKindTrait<Value, OnEmpty>,
462 OnEmpty: Get<QueryKind::Query> + 'static,
463 MaxValues: Get<Option<u32>>,
464{
465 pub fn iter_prefix<KP>(
470 kp: KP,
471 ) -> crate::storage::PrefixIterator<(<Key as HasKeyPrefix<KP>>::Suffix, Value)>
472 where
473 Key: HasReversibleKeyPrefix<KP>,
474 {
475 <Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_prefix(kp)
476 }
477
478 pub fn iter_prefix_from<KP>(
484 kp: KP,
485 starting_raw_key: Vec<u8>,
486 ) -> crate::storage::PrefixIterator<(<Key as HasKeyPrefix<KP>>::Suffix, Value)>
487 where
488 Key: HasReversibleKeyPrefix<KP>,
489 {
490 <Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_prefix_from(
491 kp,
492 starting_raw_key,
493 )
494 }
495
496 pub fn iter_key_prefix<KP>(
501 kp: KP,
502 ) -> crate::storage::KeyPrefixIterator<<Key as HasKeyPrefix<KP>>::Suffix>
503 where
504 Key: HasReversibleKeyPrefix<KP>,
505 {
506 <Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_key_prefix(kp)
507 }
508
509 pub fn iter_key_prefix_from<KP>(
515 kp: KP,
516 starting_raw_key: Vec<u8>,
517 ) -> crate::storage::KeyPrefixIterator<<Key as HasKeyPrefix<KP>>::Suffix>
518 where
519 Key: HasReversibleKeyPrefix<KP>,
520 {
521 <Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_key_prefix_from(
522 kp,
523 starting_raw_key,
524 )
525 }
526
527 pub fn drain_prefix<KP>(
533 kp: KP,
534 ) -> crate::storage::PrefixIterator<(<Key as HasKeyPrefix<KP>>::Suffix, Value)>
535 where
536 Key: HasReversibleKeyPrefix<KP>,
537 {
538 <Self as crate::storage::IterableStorageNMap<Key, Value>>::drain_prefix(kp)
539 }
540
541 pub fn iter() -> crate::storage::PrefixIterator<(Key::Key, Value)> {
545 <Self as crate::storage::IterableStorageNMap<Key, Value>>::iter()
546 }
547
548 pub fn iter_from(
552 starting_raw_key: Vec<u8>,
553 ) -> crate::storage::PrefixIterator<(Key::Key, Value)> {
554 <Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_from(starting_raw_key)
555 }
556
557 pub fn iter_keys() -> crate::storage::KeyPrefixIterator<Key::Key> {
561 <Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_keys()
562 }
563
564 pub fn iter_keys_from(
568 starting_raw_key: Vec<u8>,
569 ) -> crate::storage::KeyPrefixIterator<Key::Key> {
570 <Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_keys_from(starting_raw_key)
571 }
572
573 pub fn drain() -> crate::storage::PrefixIterator<(Key::Key, Value)> {
577 <Self as crate::storage::IterableStorageNMap<Key, Value>>::drain()
578 }
579
580 pub fn translate<O: Decode, F: FnMut(Key::Key, O) -> Option<Value>>(f: F) {
586 <Self as crate::storage::IterableStorageNMap<Key, Value>>::translate(f)
587 }
588}
589
590impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues> StorageEntryMetadataBuilder
591 for StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
592where
593 Prefix: StorageInstance,
594 Key: super::key::KeyGenerator,
595 Value: FullCodec + scale_info::StaticTypeInfo,
596 QueryKind: QueryKindTrait<Value, OnEmpty>,
597 OnEmpty: Get<QueryKind::Query> + 'static,
598 MaxValues: Get<Option<u32>>,
599{
600 fn build_metadata(
601 deprecation_status: sp_metadata_ir::ItemDeprecationInfoIR,
602 docs: Vec<&'static str>,
603 entries: &mut Vec<StorageEntryMetadataIR>,
604 ) {
605 let docs = if cfg!(feature = "no-metadata-docs") { vec![] } else { docs };
606
607 let entry = StorageEntryMetadataIR {
608 name: Prefix::STORAGE_PREFIX,
609 modifier: QueryKind::METADATA,
610 ty: StorageEntryTypeIR::Map {
611 key: scale_info::meta_type::<Key::Key>(),
612 hashers: Key::HASHER_METADATA.to_vec(),
613 value: scale_info::meta_type::<Value>(),
614 },
615 default: OnEmpty::get().encode(),
616 docs,
617 deprecation_info: deprecation_status,
618 };
619
620 entries.push(entry);
621 }
622}
623
624impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues> crate::traits::StorageInfoTrait
625 for StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
626where
627 Prefix: StorageInstance,
628 Key: super::key::KeyGenerator + super::key::KeyGeneratorMaxEncodedLen,
629 Value: FullCodec + MaxEncodedLen,
630 QueryKind: QueryKindTrait<Value, OnEmpty>,
631 OnEmpty: Get<QueryKind::Query> + 'static,
632 MaxValues: Get<Option<u32>>,
633{
634 fn storage_info() -> Vec<StorageInfo> {
635 vec![StorageInfo {
636 pallet_name: Self::pallet_prefix().to_vec(),
637 storage_name: Self::storage_prefix().to_vec(),
638 prefix: Self::final_prefix().to_vec(),
639 max_values: MaxValues::get(),
640 max_size: Some(
641 Key::key_max_encoded_len()
642 .saturating_add(Value::max_encoded_len())
643 .saturated_into(),
644 ),
645 }]
646 }
647}
648
649impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues> crate::traits::PartialStorageInfoTrait
651 for StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
652where
653 Prefix: StorageInstance,
654 Key: super::key::KeyGenerator,
655 Value: FullCodec,
656 QueryKind: QueryKindTrait<Value, OnEmpty>,
657 OnEmpty: Get<QueryKind::Query> + 'static,
658 MaxValues: Get<Option<u32>>,
659{
660 fn partial_storage_info() -> Vec<StorageInfo> {
661 vec![StorageInfo {
662 pallet_name: Self::pallet_prefix().to_vec(),
663 storage_name: Self::storage_prefix().to_vec(),
664 prefix: Self::final_prefix().to_vec(),
665 max_values: MaxValues::get(),
666 max_size: None,
667 }]
668 }
669}
670#[cfg(test)]
671mod test {
672 use super::*;
673 use crate::{
674 hash::{StorageHasher as _, *},
675 storage::types::{Key as NMapKey, ValueQuery},
676 };
677 use alloc::boxed::Box;
678 use sp_io::{hashing::twox_128, TestExternalities};
679 use sp_metadata_ir::{StorageEntryModifierIR, StorageHasherIR};
680
681 struct Prefix;
682 impl StorageInstance for Prefix {
683 fn pallet_prefix() -> &'static str {
684 "test"
685 }
686 const STORAGE_PREFIX: &'static str = "Foo";
687 }
688
689 struct ADefault;
690 impl crate::traits::Get<u32> for ADefault {
691 fn get() -> u32 {
692 98
693 }
694 }
695
696 #[test]
697 fn test_1_key() {
698 type A = StorageNMap<Prefix, NMapKey<Blake2_128Concat, u16>, u32, OptionQuery>;
699 type AValueQueryWithAnOnEmpty =
700 StorageNMap<Prefix, NMapKey<Blake2_128Concat, u16>, u32, ValueQuery, ADefault>;
701 type B = StorageNMap<Prefix, NMapKey<Blake2_256, u16>, u32, ValueQuery>;
702 type C = StorageNMap<Prefix, NMapKey<Blake2_128Concat, u16>, u8, ValueQuery>;
703 type WithLen = StorageNMap<Prefix, NMapKey<Blake2_128Concat, u16>, Vec<u32>>;
704
705 TestExternalities::default().execute_with(|| {
706 let mut k: Vec<u8> = vec![];
707 k.extend(&twox_128(b"test"));
708 k.extend(&twox_128(b"Foo"));
709 k.extend(&3u16.blake2_128_concat());
710 assert_eq!(A::hashed_key_for((&3,)).to_vec(), k);
711
712 assert_eq!(A::contains_key((3,)), false);
713 assert_eq!(A::get((3,)), None);
714 assert_eq!(AValueQueryWithAnOnEmpty::get((3,)), 98);
715
716 A::insert((3,), 10);
717 assert_eq!(A::contains_key((3,)), true);
718 assert_eq!(A::get((3,)), Some(10));
719 assert_eq!(AValueQueryWithAnOnEmpty::get((3,)), 10);
720
721 {
722 #[crate::storage_alias]
723 type Foo = StorageNMap<test, (NMapKey<Blake2_128Concat, u16>), u32>;
724
725 assert_eq!(Foo::contains_key((3,)), true);
726 assert_eq!(Foo::get((3,)), Some(10));
727 }
728
729 A::swap::<NMapKey<Blake2_128Concat, u16>, _, _>((3,), (2,));
730 assert_eq!(A::contains_key((3,)), false);
731 assert_eq!(A::contains_key((2,)), true);
732 assert_eq!(A::get((3,)), None);
733 assert_eq!(AValueQueryWithAnOnEmpty::get((3,)), 98);
734 assert_eq!(A::get((2,)), Some(10));
735 assert_eq!(AValueQueryWithAnOnEmpty::get((2,)), 10);
736
737 A::remove((2,));
738 assert_eq!(A::contains_key((2,)), false);
739 assert_eq!(A::get((2,)), None);
740
741 AValueQueryWithAnOnEmpty::mutate((2,), |v| *v = *v * 2);
742 AValueQueryWithAnOnEmpty::mutate((2,), |v| *v = *v * 2);
743 assert_eq!(A::contains_key((2,)), true);
744 assert_eq!(A::get((2,)), Some(98 * 4));
745
746 A::remove((2,));
747 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate((2,), |v| {
748 *v = *v * 2;
749 Ok(())
750 });
751 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate((2,), |v| {
752 *v = *v * 2;
753 Ok(())
754 });
755 assert_eq!(A::contains_key((2,)), true);
756 assert_eq!(A::get((2,)), Some(98 * 4));
757
758 A::remove((2,));
759 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate((2,), |v| {
760 *v = *v * 2;
761 Err(())
762 });
763 assert_eq!(A::contains_key((2,)), false);
764
765 A::remove((2,));
766 AValueQueryWithAnOnEmpty::mutate_exists((2,), |v| {
767 assert!(v.is_none());
768 *v = Some(10);
769 });
770 assert_eq!(A::contains_key((2,)), true);
771 assert_eq!(A::get((2,)), Some(10));
772 AValueQueryWithAnOnEmpty::mutate_exists((2,), |v| {
773 *v = Some(v.unwrap() * 10);
774 });
775 assert_eq!(A::contains_key((2,)), true);
776 assert_eq!(A::get((2,)), Some(100));
777
778 A::remove((2,));
779 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists((2,), |v| {
780 assert!(v.is_none());
781 *v = Some(10);
782 Ok(())
783 });
784 assert_eq!(A::contains_key((2,)), true);
785 assert_eq!(A::get((2,)), Some(10));
786 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists((2,), |v| {
787 *v = Some(v.unwrap() * 10);
788 Ok(())
789 });
790 assert_eq!(A::contains_key((2,)), true);
791 assert_eq!(A::get((2,)), Some(100));
792 assert_eq!(A::try_get((2,)), Ok(100));
793 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists((2,), |v| {
794 *v = Some(v.unwrap() * 10);
795 Err(())
796 });
797 assert_eq!(A::contains_key((2,)), true);
798 assert_eq!(A::get((2,)), Some(100));
799
800 A::insert((2,), 10);
801 assert_eq!(A::take((2,)), Some(10));
802 assert_eq!(A::contains_key((2,)), false);
803 assert_eq!(AValueQueryWithAnOnEmpty::take((2,)), 98);
804 assert_eq!(A::contains_key((2,)), false);
805 assert_eq!(A::try_get((2,)), Err(()));
806
807 B::insert((2,), 10);
808 assert_eq!(
809 A::migrate_keys((2,), (Box::new(|key| Blake2_256::hash(key).to_vec()),),),
810 Some(10)
811 );
812 assert_eq!(A::contains_key((2,)), true);
813 assert_eq!(A::get((2,)), Some(10));
814
815 A::insert((3,), 10);
816 A::insert((4,), 10);
817 let _ = A::clear(u32::max_value(), None);
818 assert_eq!(A::contains_key((3,)), false);
819 assert_eq!(A::contains_key((4,)), false);
820
821 A::insert((3,), 10);
822 A::insert((4,), 10);
823 assert_eq!(A::iter_values().collect::<Vec<_>>(), vec![10, 10]);
824
825 C::insert((3,), 10);
826 C::insert((4,), 10);
827 A::translate_values::<u8, _>(|v| Some((v * 2).into()));
828 assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 20), (3, 20)]);
829
830 A::insert((3,), 10);
831 A::insert((4,), 10);
832 assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 10), (3, 10)]);
833 assert_eq!(A::drain().collect::<Vec<_>>(), vec![(4, 10), (3, 10)]);
834 assert_eq!(A::iter().collect::<Vec<_>>(), vec![]);
835
836 C::insert((3,), 10);
837 C::insert((4,), 10);
838 A::translate::<u8, _>(|k1, v| Some((k1 as u16 * v as u16).into()));
839 assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 40), (3, 30)]);
840
841 let mut entries = vec![];
842 A::build_metadata(
843 sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
844 vec![],
845 &mut entries,
846 );
847 AValueQueryWithAnOnEmpty::build_metadata(
848 sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
849 vec![],
850 &mut entries,
851 );
852 assert_eq!(
853 entries,
854 vec![
855 StorageEntryMetadataIR {
856 name: "Foo",
857 modifier: StorageEntryModifierIR::Optional,
858 ty: StorageEntryTypeIR::Map {
859 hashers: vec![StorageHasherIR::Blake2_128Concat],
860 key: scale_info::meta_type::<u16>(),
861 value: scale_info::meta_type::<u32>(),
862 },
863 default: Option::<u32>::None.encode(),
864 docs: vec![],
865 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
866 },
867 StorageEntryMetadataIR {
868 name: "Foo",
869 modifier: StorageEntryModifierIR::Default,
870 ty: StorageEntryTypeIR::Map {
871 hashers: vec![StorageHasherIR::Blake2_128Concat],
872 key: scale_info::meta_type::<u16>(),
873 value: scale_info::meta_type::<u32>(),
874 },
875 default: 98u32.encode(),
876 docs: vec![],
877 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
878 }
879 ]
880 );
881
882 let _ = WithLen::clear(u32::max_value(), None);
883 assert_eq!(WithLen::decode_len((3,)), None);
884 WithLen::append((0,), 10);
885 assert_eq!(WithLen::decode_len((0,)), Some(1));
886 });
887 }
888
889 #[test]
890 fn test_2_keys() {
891 type A = StorageNMap<
892 Prefix,
893 (NMapKey<Blake2_128Concat, u16>, NMapKey<Twox64Concat, u8>),
894 u32,
895 OptionQuery,
896 >;
897 type AValueQueryWithAnOnEmpty = StorageNMap<
898 Prefix,
899 (NMapKey<Blake2_128Concat, u16>, NMapKey<Twox64Concat, u8>),
900 u32,
901 ValueQuery,
902 ADefault,
903 >;
904 type B =
905 StorageNMap<Prefix, (NMapKey<Blake2_256, u16>, NMapKey<Twox128, u8>), u32, ValueQuery>;
906 type C = StorageNMap<
907 Prefix,
908 (NMapKey<Blake2_128Concat, u16>, NMapKey<Twox64Concat, u8>),
909 u8,
910 ValueQuery,
911 >;
912 type WithLen = StorageNMap<
913 Prefix,
914 (NMapKey<Blake2_128Concat, u16>, NMapKey<Twox64Concat, u8>),
915 Vec<u32>,
916 >;
917
918 TestExternalities::default().execute_with(|| {
919 let mut k: Vec<u8> = vec![];
920 k.extend(&twox_128(b"test"));
921 k.extend(&twox_128(b"Foo"));
922 k.extend(&3u16.blake2_128_concat());
923 k.extend(&30u8.twox_64_concat());
924 assert_eq!(A::hashed_key_for((3, 30)).to_vec(), k);
925
926 assert_eq!(A::contains_key((3, 30)), false);
927 assert_eq!(A::get((3, 30)), None);
928 assert_eq!(AValueQueryWithAnOnEmpty::get((3, 30)), 98);
929
930 A::insert((3, 30), 10);
931 assert_eq!(A::contains_key((3, 30)), true);
932 assert_eq!(A::get((3, 30)), Some(10));
933 assert_eq!(AValueQueryWithAnOnEmpty::get((3, 30)), 10);
934
935 A::swap::<(NMapKey<Blake2_128Concat, u16>, NMapKey<Twox64Concat, u8>), _, _>(
936 (3, 30),
937 (2, 20),
938 );
939 assert_eq!(A::contains_key((3, 30)), false);
940 assert_eq!(A::contains_key((2, 20)), true);
941 assert_eq!(A::get((3, 30)), None);
942 assert_eq!(AValueQueryWithAnOnEmpty::get((3, 30)), 98);
943 assert_eq!(A::get((2, 20)), Some(10));
944 assert_eq!(AValueQueryWithAnOnEmpty::get((2, 20)), 10);
945
946 A::remove((2, 20));
947 assert_eq!(A::contains_key((2, 20)), false);
948 assert_eq!(A::get((2, 20)), None);
949
950 AValueQueryWithAnOnEmpty::mutate((2, 20), |v| *v = *v * 2);
951 AValueQueryWithAnOnEmpty::mutate((2, 20), |v| *v = *v * 2);
952 assert_eq!(A::contains_key((2, 20)), true);
953 assert_eq!(A::get((2, 20)), Some(98 * 4));
954
955 A::remove((2, 20));
956 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate((2, 20), |v| {
957 *v = *v * 2;
958 Err(())
959 });
960 assert_eq!(A::contains_key((2, 20)), false);
961
962 A::remove((2, 20));
963 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate((2, 20), |v| {
964 *v = *v * 2;
965 Err(())
966 });
967 assert_eq!(A::contains_key((2, 20)), false);
968
969 A::remove((2, 20));
970 AValueQueryWithAnOnEmpty::mutate_exists((2, 20), |v| {
971 assert!(v.is_none());
972 *v = Some(10);
973 });
974 assert_eq!(A::contains_key((2, 20)), true);
975 assert_eq!(A::get((2, 20)), Some(10));
976 AValueQueryWithAnOnEmpty::mutate_exists((2, 20), |v| {
977 *v = Some(v.unwrap() * 10);
978 });
979 assert_eq!(A::contains_key((2, 20)), true);
980 assert_eq!(A::get((2, 20)), Some(100));
981
982 A::remove((2, 20));
983 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists((2, 20), |v| {
984 assert!(v.is_none());
985 *v = Some(10);
986 Ok(())
987 });
988 assert_eq!(A::contains_key((2, 20)), true);
989 assert_eq!(A::get((2, 20)), Some(10));
990 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists((2, 20), |v| {
991 *v = Some(v.unwrap() * 10);
992 Ok(())
993 });
994 assert_eq!(A::contains_key((2, 20)), true);
995 assert_eq!(A::get((2, 20)), Some(100));
996 assert_eq!(A::try_get((2, 20)), Ok(100));
997 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists((2, 20), |v| {
998 *v = Some(v.unwrap() * 10);
999 Err(())
1000 });
1001 assert_eq!(A::contains_key((2, 20)), true);
1002 assert_eq!(A::get((2, 20)), Some(100));
1003
1004 A::insert((2, 20), 10);
1005 assert_eq!(A::take((2, 20)), Some(10));
1006 assert_eq!(A::contains_key((2, 20)), false);
1007 assert_eq!(AValueQueryWithAnOnEmpty::take((2, 20)), 98);
1008 assert_eq!(A::contains_key((2, 20)), false);
1009 assert_eq!(A::try_get((2, 20)), Err(()));
1010
1011 B::insert((2, 20), 10);
1012 assert_eq!(
1013 A::migrate_keys(
1014 (2, 20),
1015 (
1016 Box::new(|key| Blake2_256::hash(key).to_vec()),
1017 Box::new(|key| Twox128::hash(key).to_vec()),
1018 ),
1019 ),
1020 Some(10)
1021 );
1022 assert_eq!(A::contains_key((2, 20)), true);
1023 assert_eq!(A::get((2, 20)), Some(10));
1024
1025 A::insert((3, 30), 10);
1026 A::insert((4, 40), 10);
1027 let _ = A::clear(u32::max_value(), None);
1028 assert_eq!(A::contains_key((3, 30)), false);
1029 assert_eq!(A::contains_key((4, 40)), false);
1030
1031 A::insert((3, 30), 10);
1032 A::insert((4, 40), 10);
1033 assert_eq!(A::iter_values().collect::<Vec<_>>(), vec![10, 10]);
1034
1035 C::insert((3, 30), 10);
1036 C::insert((4, 40), 10);
1037 A::translate_values::<u8, _>(|v| Some((v * 2).into()));
1038 assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40), 20), ((3, 30), 20)]);
1039
1040 A::insert((3, 30), 10);
1041 A::insert((4, 40), 10);
1042 assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40), 10), ((3, 30), 10)]);
1043 assert_eq!(A::drain().collect::<Vec<_>>(), vec![((4, 40), 10), ((3, 30), 10)]);
1044 assert_eq!(A::iter().collect::<Vec<_>>(), vec![]);
1045
1046 C::insert((3, 30), 10);
1047 C::insert((4, 40), 10);
1048 A::translate::<u8, _>(|(k1, k2), v| Some((k1 * k2 as u16 * v as u16).into()));
1049 assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40), 1600), ((3, 30), 900)]);
1050
1051 let mut entries = vec![];
1052 A::build_metadata(
1053 sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1054 vec![],
1055 &mut entries,
1056 );
1057 AValueQueryWithAnOnEmpty::build_metadata(
1058 sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1059 vec![],
1060 &mut entries,
1061 );
1062 assert_eq!(
1063 entries,
1064 vec![
1065 StorageEntryMetadataIR {
1066 name: "Foo",
1067 modifier: StorageEntryModifierIR::Optional,
1068 ty: StorageEntryTypeIR::Map {
1069 hashers: vec![
1070 StorageHasherIR::Blake2_128Concat,
1071 StorageHasherIR::Twox64Concat
1072 ],
1073 key: scale_info::meta_type::<(u16, u8)>(),
1074 value: scale_info::meta_type::<u32>(),
1075 },
1076 default: Option::<u32>::None.encode(),
1077 docs: vec![],
1078 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1079 },
1080 StorageEntryMetadataIR {
1081 name: "Foo",
1082 modifier: StorageEntryModifierIR::Default,
1083 ty: StorageEntryTypeIR::Map {
1084 hashers: vec![
1085 StorageHasherIR::Blake2_128Concat,
1086 StorageHasherIR::Twox64Concat
1087 ],
1088 key: scale_info::meta_type::<(u16, u8)>(),
1089 value: scale_info::meta_type::<u32>(),
1090 },
1091 default: 98u32.encode(),
1092 docs: vec![],
1093 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1094 }
1095 ]
1096 );
1097
1098 let _ = WithLen::clear(u32::max_value(), None);
1099 assert_eq!(WithLen::decode_len((3, 30)), None);
1100 WithLen::append((0, 100), 10);
1101 assert_eq!(WithLen::decode_len((0, 100)), Some(1));
1102
1103 A::insert((3, 30), 11);
1104 A::insert((3, 31), 12);
1105 A::insert((4, 40), 13);
1106 A::insert((4, 41), 14);
1107 assert_eq!(A::iter_prefix_values((3,)).collect::<Vec<_>>(), vec![12, 11]);
1108 assert_eq!(A::iter_prefix_values((4,)).collect::<Vec<_>>(), vec![13, 14]);
1109 });
1110 }
1111
1112 #[test]
1113 fn test_3_keys() {
1114 type A = StorageNMap<
1115 Prefix,
1116 (
1117 NMapKey<Blake2_128Concat, u16>,
1118 NMapKey<Blake2_128Concat, u16>,
1119 NMapKey<Twox64Concat, u16>,
1120 ),
1121 u32,
1122 OptionQuery,
1123 >;
1124 type AValueQueryWithAnOnEmpty = StorageNMap<
1125 Prefix,
1126 (
1127 NMapKey<Blake2_128Concat, u16>,
1128 NMapKey<Blake2_128Concat, u16>,
1129 NMapKey<Twox64Concat, u16>,
1130 ),
1131 u32,
1132 ValueQuery,
1133 ADefault,
1134 >;
1135 type B = StorageNMap<
1136 Prefix,
1137 (NMapKey<Blake2_256, u16>, NMapKey<Blake2_256, u16>, NMapKey<Twox128, u16>),
1138 u32,
1139 ValueQuery,
1140 >;
1141 type C = StorageNMap<
1142 Prefix,
1143 (
1144 NMapKey<Blake2_128Concat, u16>,
1145 NMapKey<Blake2_128Concat, u16>,
1146 NMapKey<Twox64Concat, u16>,
1147 ),
1148 u8,
1149 ValueQuery,
1150 >;
1151 type WithLen = StorageNMap<
1152 Prefix,
1153 (
1154 NMapKey<Blake2_128Concat, u16>,
1155 NMapKey<Blake2_128Concat, u16>,
1156 NMapKey<Twox64Concat, u16>,
1157 ),
1158 Vec<u32>,
1159 >;
1160
1161 TestExternalities::default().execute_with(|| {
1162 let mut k: Vec<u8> = vec![];
1163 k.extend(&twox_128(b"test"));
1164 k.extend(&twox_128(b"Foo"));
1165 k.extend(&1u16.blake2_128_concat());
1166 k.extend(&10u16.blake2_128_concat());
1167 k.extend(&100u16.twox_64_concat());
1168 assert_eq!(A::hashed_key_for((1, 10, 100)).to_vec(), k);
1169
1170 assert_eq!(A::contains_key((1, 10, 100)), false);
1171 assert_eq!(A::get((1, 10, 100)), None);
1172 assert_eq!(AValueQueryWithAnOnEmpty::get((1, 10, 100)), 98);
1173
1174 A::insert((1, 10, 100), 30);
1175 assert_eq!(A::contains_key((1, 10, 100)), true);
1176 assert_eq!(A::get((1, 10, 100)), Some(30));
1177 assert_eq!(AValueQueryWithAnOnEmpty::get((1, 10, 100)), 30);
1178
1179 A::swap::<
1180 (
1181 NMapKey<Blake2_128Concat, u16>,
1182 NMapKey<Blake2_128Concat, u16>,
1183 NMapKey<Twox64Concat, u16>,
1184 ),
1185 _,
1186 _,
1187 >((1, 10, 100), (2, 20, 200));
1188 assert_eq!(A::contains_key((1, 10, 100)), false);
1189 assert_eq!(A::contains_key((2, 20, 200)), true);
1190 assert_eq!(A::get((1, 10, 100)), None);
1191 assert_eq!(AValueQueryWithAnOnEmpty::get((1, 10, 100)), 98);
1192 assert_eq!(A::get((2, 20, 200)), Some(30));
1193 assert_eq!(AValueQueryWithAnOnEmpty::get((2, 20, 200)), 30);
1194
1195 A::remove((2, 20, 200));
1196 assert_eq!(A::contains_key((2, 20, 200)), false);
1197 assert_eq!(A::get((2, 20, 200)), None);
1198
1199 AValueQueryWithAnOnEmpty::mutate((2, 20, 200), |v| *v = *v * 2);
1200 AValueQueryWithAnOnEmpty::mutate((2, 20, 200), |v| *v = *v * 2);
1201 assert_eq!(A::contains_key((2, 20, 200)), true);
1202 assert_eq!(A::get((2, 20, 200)), Some(98 * 4));
1203
1204 A::remove((2, 20, 200));
1205 let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate((2, 20, 200), |v| {
1206 *v = *v * 2;
1207 Err(())
1208 });
1209 assert_eq!(A::contains_key((2, 20, 200)), false);
1210
1211 A::remove((2, 20, 200));
1212 AValueQueryWithAnOnEmpty::mutate_exists((2, 20, 200), |v| {
1213 assert!(v.is_none());
1214 *v = Some(10);
1215 });
1216 assert_eq!(A::contains_key((2, 20, 200)), true);
1217 assert_eq!(A::get((2, 20, 200)), Some(10));
1218 AValueQueryWithAnOnEmpty::mutate_exists((2, 20, 200), |v| {
1219 *v = Some(v.unwrap() * 10);
1220 });
1221 assert_eq!(A::contains_key((2, 20, 200)), true);
1222 assert_eq!(A::get((2, 20, 200)), Some(100));
1223
1224 A::remove((2, 20, 200));
1225 let _: Result<(), ()> =
1226 AValueQueryWithAnOnEmpty::try_mutate_exists((2, 20, 200), |v| {
1227 assert!(v.is_none());
1228 *v = Some(10);
1229 Ok(())
1230 });
1231 assert_eq!(A::contains_key((2, 20, 200)), true);
1232 assert_eq!(A::get((2, 20, 200)), Some(10));
1233 let _: Result<(), ()> =
1234 AValueQueryWithAnOnEmpty::try_mutate_exists((2, 20, 200), |v| {
1235 *v = Some(v.unwrap() * 10);
1236 Ok(())
1237 });
1238 assert_eq!(A::contains_key((2, 20, 200)), true);
1239 assert_eq!(A::get((2, 20, 200)), Some(100));
1240 assert_eq!(A::try_get((2, 20, 200)), Ok(100));
1241 let _: Result<(), ()> =
1242 AValueQueryWithAnOnEmpty::try_mutate_exists((2, 20, 200), |v| {
1243 *v = Some(v.unwrap() * 10);
1244 Err(())
1245 });
1246 assert_eq!(A::contains_key((2, 20, 200)), true);
1247 assert_eq!(A::get((2, 20, 200)), Some(100));
1248
1249 A::insert((2, 20, 200), 10);
1250 assert_eq!(A::take((2, 20, 200)), Some(10));
1251 assert_eq!(A::contains_key((2, 20, 200)), false);
1252 assert_eq!(AValueQueryWithAnOnEmpty::take((2, 20, 200)), 98);
1253 assert_eq!(A::contains_key((2, 20, 200)), false);
1254 assert_eq!(A::try_get((2, 20, 200)), Err(()));
1255
1256 B::insert((2, 20, 200), 10);
1257 assert_eq!(
1258 A::migrate_keys(
1259 (2, 20, 200),
1260 (
1261 Box::new(|key| Blake2_256::hash(key).to_vec()),
1262 Box::new(|key| Blake2_256::hash(key).to_vec()),
1263 Box::new(|key| Twox128::hash(key).to_vec()),
1264 ),
1265 ),
1266 Some(10)
1267 );
1268 assert_eq!(A::contains_key((2, 20, 200)), true);
1269 assert_eq!(A::get((2, 20, 200)), Some(10));
1270
1271 A::insert((3, 30, 300), 10);
1272 A::insert((4, 40, 400), 10);
1273 let _ = A::clear(u32::max_value(), None);
1274 assert_eq!(A::contains_key((3, 30, 300)), false);
1275 assert_eq!(A::contains_key((4, 40, 400)), false);
1276
1277 A::insert((3, 30, 300), 10);
1278 A::insert((4, 40, 400), 10);
1279 assert_eq!(A::iter_values().collect::<Vec<_>>(), vec![10, 10]);
1280
1281 C::insert((3, 30, 300), 10);
1282 C::insert((4, 40, 400), 10);
1283 A::translate_values::<u8, _>(|v| Some((v * 2).into()));
1284 assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40, 400), 20), ((3, 30, 300), 20)]);
1285
1286 A::insert((3, 30, 300), 10);
1287 A::insert((4, 40, 400), 10);
1288 assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40, 400), 10), ((3, 30, 300), 10)]);
1289 assert_eq!(
1290 A::drain().collect::<Vec<_>>(),
1291 vec![((4, 40, 400), 10), ((3, 30, 300), 10)]
1292 );
1293 assert_eq!(A::iter().collect::<Vec<_>>(), vec![]);
1294
1295 C::insert((3, 30, 300), 10);
1296 C::insert((4, 40, 400), 10);
1297 A::translate::<u8, _>(|(k1, k2, k3), v| {
1298 Some((k1 * k2 as u16 * v as u16 / k3 as u16).into())
1299 });
1300 assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40, 400), 4), ((3, 30, 300), 3)]);
1301
1302 let mut entries = vec![];
1303 A::build_metadata(
1304 sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1305 vec![],
1306 &mut entries,
1307 );
1308 AValueQueryWithAnOnEmpty::build_metadata(
1309 sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1310 vec![],
1311 &mut entries,
1312 );
1313 assert_eq!(
1314 entries,
1315 vec![
1316 StorageEntryMetadataIR {
1317 name: "Foo",
1318 modifier: StorageEntryModifierIR::Optional,
1319 ty: StorageEntryTypeIR::Map {
1320 hashers: vec![
1321 StorageHasherIR::Blake2_128Concat,
1322 StorageHasherIR::Blake2_128Concat,
1323 StorageHasherIR::Twox64Concat
1324 ],
1325 key: scale_info::meta_type::<(u16, u16, u16)>(),
1326 value: scale_info::meta_type::<u32>(),
1327 },
1328 default: Option::<u32>::None.encode(),
1329 docs: vec![],
1330 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1331 },
1332 StorageEntryMetadataIR {
1333 name: "Foo",
1334 modifier: StorageEntryModifierIR::Default,
1335 ty: StorageEntryTypeIR::Map {
1336 hashers: vec![
1337 StorageHasherIR::Blake2_128Concat,
1338 StorageHasherIR::Blake2_128Concat,
1339 StorageHasherIR::Twox64Concat
1340 ],
1341 key: scale_info::meta_type::<(u16, u16, u16)>(),
1342 value: scale_info::meta_type::<u32>(),
1343 },
1344 default: 98u32.encode(),
1345 docs: vec![],
1346 deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1347 }
1348 ]
1349 );
1350
1351 let _ = WithLen::clear(u32::max_value(), None);
1352 assert_eq!(WithLen::decode_len((3, 30, 300)), None);
1353 WithLen::append((0, 100, 1000), 10);
1354 assert_eq!(WithLen::decode_len((0, 100, 1000)), Some(1));
1355
1356 A::insert((3, 30, 300), 11);
1357 A::insert((3, 30, 301), 12);
1358 A::insert((4, 40, 400), 13);
1359 A::insert((4, 40, 401), 14);
1360 assert_eq!(A::iter_prefix_values((3,)).collect::<Vec<_>>(), vec![11, 12]);
1361 assert_eq!(A::iter_prefix_values((4,)).collect::<Vec<_>>(), vec![14, 13]);
1362 assert_eq!(A::iter_prefix_values((3, 30)).collect::<Vec<_>>(), vec![11, 12]);
1363 assert_eq!(A::iter_prefix_values((4, 40)).collect::<Vec<_>>(), vec![14, 13]);
1364 });
1365 }
1366}