frame_decode/utils/
list_storage_entries.rs1use alloc::borrow::Cow;
17use alloc::boxed::Box;
18use frame_metadata::RuntimeMetadata;
19
20pub fn list_storage_entries<Md: ToStorageEntriesList>(
24 metadata: &Md,
25) -> impl Iterator<Item = StorageEntry<'_>> {
26 metadata.storage_entries_list()
27}
28
29pub fn list_storage_entries_any(
33 metadata: &RuntimeMetadata,
34) -> impl Iterator<Item = StorageEntry<'_>> {
35 match metadata {
36 RuntimeMetadata::V0(_deprecated_metadata)
37 | RuntimeMetadata::V1(_deprecated_metadata)
38 | RuntimeMetadata::V2(_deprecated_metadata)
39 | RuntimeMetadata::V3(_deprecated_metadata)
40 | RuntimeMetadata::V4(_deprecated_metadata)
41 | RuntimeMetadata::V5(_deprecated_metadata)
42 | RuntimeMetadata::V6(_deprecated_metadata)
43 | RuntimeMetadata::V7(_deprecated_metadata) => {
44 Box::new(core::iter::empty()) as Box<dyn Iterator<Item = StorageEntry<'_>>>
45 }
46 #[cfg(feature = "legacy")]
47 RuntimeMetadata::V8(m) => Box::new(m.storage_entries_list()),
48 #[cfg(not(feature = "legacy"))]
49 RuntimeMetadata::V8(_opaque) => Box::new(core::iter::empty()),
50 #[cfg(feature = "legacy")]
51 RuntimeMetadata::V9(m) => Box::new(m.storage_entries_list()),
52 #[cfg(not(feature = "legacy"))]
53 RuntimeMetadata::V9(_opaque) => Box::new(core::iter::empty()),
54 #[cfg(feature = "legacy")]
55 RuntimeMetadata::V10(m) => Box::new(m.storage_entries_list()),
56 #[cfg(not(feature = "legacy"))]
57 RuntimeMetadata::V10(_opaque) => Box::new(core::iter::empty()),
58 #[cfg(feature = "legacy")]
59 RuntimeMetadata::V11(m) => Box::new(m.storage_entries_list()),
60 #[cfg(not(feature = "legacy"))]
61 RuntimeMetadata::V11(_opaque) => Box::new(core::iter::empty()),
62 #[cfg(feature = "legacy")]
63 RuntimeMetadata::V12(m) => Box::new(m.storage_entries_list()),
64 #[cfg(not(feature = "legacy"))]
65 RuntimeMetadata::V12(_opaque) => Box::new(core::iter::empty()),
66 #[cfg(feature = "legacy")]
67 RuntimeMetadata::V13(m) => Box::new(m.storage_entries_list()),
68 #[cfg(not(feature = "legacy"))]
69 RuntimeMetadata::V13(_opaque) => Box::new(core::iter::empty()),
70 RuntimeMetadata::V14(m) => Box::new(m.storage_entries_list()),
71 RuntimeMetadata::V15(m) => Box::new(m.storage_entries_list()),
72 RuntimeMetadata::V16(m) => Box::new(m.storage_entries_list()),
73 }
74}
75
76#[derive(Debug, Clone)]
78pub struct StorageEntry<'a> {
79 pallet: Cow<'a, str>,
80 entry: Cow<'a, str>,
81}
82
83impl StorageEntry<'_> {
84 pub fn into_owned(self) -> StorageEntry<'static> {
86 StorageEntry {
87 pallet: Cow::Owned(self.pallet.into_owned()),
88 entry: Cow::Owned(self.entry.into_owned()),
89 }
90 }
91
92 pub fn pallet(&self) -> &str {
94 &self.pallet
95 }
96
97 pub fn entry(&self) -> &str {
99 &self.entry
100 }
101}
102
103pub trait ToStorageEntriesList {
104 fn storage_entries_list(&self) -> impl Iterator<Item = StorageEntry<'_>>;
106}
107
108#[cfg(feature = "legacy")]
109const _: () = {
110 macro_rules! impl_storage_entries_list_for_v8_to_v13 {
111 ($path:path) => {
112 impl ToStorageEntriesList for $path {
113 fn storage_entries_list(&self) -> impl Iterator<Item = StorageEntry<'_>> {
114 use crate::utils::as_decoded;
115 as_decoded(&self.modules).iter().flat_map(|module| {
116 let Some(storage) = &module.storage else {
117 return Either::Left(core::iter::empty());
118 };
119 let pallet = as_decoded(&module.name);
120 let storage = as_decoded(storage);
121 let entries = as_decoded(&storage.entries);
122
123 Either::Right(entries.iter().map(|entry_meta| {
124 let entry = as_decoded(&entry_meta.name);
125 StorageEntry {
126 pallet: Cow::Borrowed(pallet.as_ref()),
127 entry: Cow::Borrowed(entry.as_ref()),
128 }
129 }))
130 })
131 }
132 }
133 };
134 }
135
136 impl_storage_entries_list_for_v8_to_v13!(frame_metadata::v8::RuntimeMetadataV8);
137 impl_storage_entries_list_for_v8_to_v13!(frame_metadata::v9::RuntimeMetadataV9);
138 impl_storage_entries_list_for_v8_to_v13!(frame_metadata::v10::RuntimeMetadataV10);
139 impl_storage_entries_list_for_v8_to_v13!(frame_metadata::v11::RuntimeMetadataV11);
140 impl_storage_entries_list_for_v8_to_v13!(frame_metadata::v12::RuntimeMetadataV12);
141 impl_storage_entries_list_for_v8_to_v13!(frame_metadata::v13::RuntimeMetadataV13);
142};
143
144macro_rules! impl_storage_entries_list_for_v14_to_v16 {
145 ($path:path) => {
146 impl ToStorageEntriesList for $path {
147 fn storage_entries_list(&self) -> impl Iterator<Item = StorageEntry<'_>> {
148 self.pallets.iter().flat_map(|pallet| {
149 let Some(storage) = &pallet.storage else {
150 return Either::Left(core::iter::empty());
151 };
152
153 Either::Right(storage.entries.iter().map(|entry_meta| {
154 let entry = &entry_meta.name;
155 StorageEntry {
156 pallet: Cow::Borrowed(pallet.name.as_ref()),
157 entry: Cow::Borrowed(entry.as_ref()),
158 }
159 }))
160 })
161 }
162 }
163 };
164}
165
166impl_storage_entries_list_for_v14_to_v16!(frame_metadata::v14::RuntimeMetadataV14);
167impl_storage_entries_list_for_v14_to_v16!(frame_metadata::v15::RuntimeMetadataV15);
168impl_storage_entries_list_for_v14_to_v16!(frame_metadata::v16::RuntimeMetadataV16);
169
170enum Either<L, R> {
171 Left(L),
172 Right(R),
173}
174
175impl<L, R> Iterator for Either<L, R>
176where
177 L: Iterator,
178 R: Iterator<Item = L::Item>,
179{
180 type Item = L::Item;
181 fn next(&mut self) -> Option<L::Item> {
182 match self {
183 Either::Left(l) => l.next(),
184 Either::Right(r) => r.next(),
185 }
186 }
187}