frame_support_procedural/pallet/expand/
pallet_struct.rs
1use crate::pallet::{expand::merge_where_clauses, Def};
19use frame_support_procedural_tools::get_doc_literals;
20
21pub fn expand_pallet_struct(def: &mut Def) -> proc_macro2::TokenStream {
31 let frame_support = &def.frame_support;
32 let frame_system = &def.frame_system;
33 let type_impl_gen = &def.type_impl_generics(def.pallet_struct.attr_span);
34 let type_use_gen = &def.type_use_generics(def.pallet_struct.attr_span);
35 let type_decl_gen = &def.type_decl_generics(def.pallet_struct.attr_span);
36 let pallet_ident = &def.pallet_struct.pallet;
37 let config_where_clause = &def.config.where_clause;
38 let deprecation_status =
39 match crate::deprecation::get_deprecation("e::quote! {#frame_support}, &def.item.attrs)
40 {
41 Ok(deprecation) => deprecation,
42 Err(e) => return e.into_compile_error(),
43 };
44
45 let mut storages_where_clauses = vec![&def.config.where_clause];
46 storages_where_clauses.extend(def.storages.iter().map(|storage| &storage.where_clause));
47 let storages_where_clauses = merge_where_clauses(&storages_where_clauses);
48
49 let pallet_item = {
50 let pallet_module_items = &mut def.item.content.as_mut().expect("Checked by def").1;
51 let item = &mut pallet_module_items[def.pallet_struct.index];
52 if let syn::Item::Struct(item) = item {
53 item
54 } else {
55 unreachable!("Checked by pallet struct parser")
56 }
57 };
58
59 if let Some(field) = pallet_item.fields.iter_mut().next() {
61 if field.ty == syn::parse_quote!(_) {
62 field.ty = syn::parse_quote!(
63 core::marker::PhantomData<(#type_use_gen)>
64 );
65 }
66 }
67
68 if get_doc_literals(&pallet_item.attrs).is_empty() {
69 pallet_item.attrs.push(syn::parse_quote!(
70 #[doc = r"
71 The `Pallet` struct, the main type that implements traits and standalone
72 functions within the pallet.
73 "]
74 ));
75 }
76
77 pallet_item.attrs.push(syn::parse_quote!(
78 #[derive(
79 #frame_support::CloneNoBound,
80 #frame_support::EqNoBound,
81 #frame_support::PartialEqNoBound,
82 #frame_support::RuntimeDebugNoBound,
83 )]
84 ));
85
86 let pallet_error_metadata = if let Some(error_def) = &def.error {
87 let error_ident = &error_def.error;
88 quote::quote_spanned!(def.pallet_struct.attr_span =>
89 impl<#type_impl_gen> #pallet_ident<#type_use_gen> #config_where_clause {
90 #[doc(hidden)]
91 #[allow(deprecated)]
92 pub fn error_metadata() -> Option<#frame_support::__private::metadata_ir::PalletErrorMetadataIR> {
93 Some(<#error_ident<#type_use_gen>>::error_metadata())
94 }
95 }
96 )
97 } else {
98 quote::quote_spanned!(def.pallet_struct.attr_span =>
99 impl<#type_impl_gen> #pallet_ident<#type_use_gen> #config_where_clause {
100 #[doc(hidden)]
101 pub fn error_metadata() -> Option<#frame_support::__private::metadata_ir::PalletErrorMetadataIR> {
102 None
103 }
104 }
105 )
106 };
107
108 let storage_info_span =
109 def.pallet_struct.without_storage_info.unwrap_or(def.pallet_struct.attr_span);
110
111 let storage_names = &def.storages.iter().map(|storage| &storage.ident).collect::<Vec<_>>();
112 let storage_cfg_attrs =
113 &def.storages.iter().map(|storage| &storage.cfg_attrs).collect::<Vec<_>>();
114 let storage_maybe_allow_attrs = &def
115 .storages
116 .iter()
117 .map(|storage| crate::deprecation::extract_or_return_allow_attrs(&storage.attrs).collect())
118 .collect::<Vec<Vec<_>>>();
119 let storage_info_traits = &def
122 .storages
123 .iter()
124 .map(|storage| {
125 if storage.unbounded || def.pallet_struct.without_storage_info.is_some() {
126 quote::quote_spanned!(storage_info_span => PartialStorageInfoTrait)
127 } else {
128 quote::quote_spanned!(storage_info_span => StorageInfoTrait)
129 }
130 })
131 .collect::<Vec<_>>();
132
133 let storage_info_methods = &def
134 .storages
135 .iter()
136 .map(|storage| {
137 if storage.unbounded || def.pallet_struct.without_storage_info.is_some() {
138 quote::quote_spanned!(storage_info_span => partial_storage_info)
139 } else {
140 quote::quote_spanned!(storage_info_span => storage_info)
141 }
142 })
143 .collect::<Vec<_>>();
144
145 let storage_info = quote::quote_spanned!(storage_info_span =>
146 impl<#type_impl_gen> #frame_support::traits::StorageInfoTrait
147 for #pallet_ident<#type_use_gen>
148 #storages_where_clauses
149 {
150 fn storage_info()
151 -> #frame_support::__private::Vec<#frame_support::traits::StorageInfo>
152 {
153 #[allow(unused_mut)]
154 let mut res = #frame_support::__private::vec![];
155
156 #(
157 #(#storage_cfg_attrs)*
158 #(#storage_maybe_allow_attrs)*
159 {
160 let mut storage_info = <
161 #storage_names<#type_use_gen>
162 as #frame_support::traits::#storage_info_traits
163 >::#storage_info_methods();
164 res.append(&mut storage_info);
165 }
166 )*
167
168 res
169 }
170 }
171 );
172
173 let (storage_version, in_code_storage_version_ty) =
174 if let Some(v) = def.pallet_struct.storage_version.as_ref() {
175 (quote::quote! { #v }, quote::quote! { #frame_support::traits::StorageVersion })
176 } else {
177 (
178 quote::quote! { core::default::Default::default() },
179 quote::quote! { #frame_support::traits::NoStorageVersionSet },
180 )
181 };
182
183 let whitelisted_storage_idents: Vec<syn::Ident> = def
184 .storages
185 .iter()
186 .filter_map(|s| s.whitelisted.then(|| s.ident.clone()))
187 .collect();
188
189 let whitelisted_storage_keys_impl = quote::quote![
190 use #frame_support::traits::{StorageInfoTrait, TrackedStorageKey, WhitelistedStorageKeys};
191 impl<#type_impl_gen> WhitelistedStorageKeys for #pallet_ident<#type_use_gen> #storages_where_clauses {
192 fn whitelisted_storage_keys() -> #frame_support::__private::Vec<TrackedStorageKey> {
193 use #frame_support::__private::vec;
194 vec![#(
195 TrackedStorageKey::new(#whitelisted_storage_idents::<#type_use_gen>::hashed_key().to_vec())
196 ),*]
197 }
198 }
199 ];
200
201 quote::quote_spanned!(def.pallet_struct.attr_span =>
202 #pallet_error_metadata
203
204 #[deprecated(note = "use `Pallet` instead")]
208 #[allow(dead_code)]
209 pub type Module<#type_decl_gen> = #pallet_ident<#type_use_gen>;
210
211 impl<#type_impl_gen> #frame_support::traits::GetStorageVersion
213 for #pallet_ident<#type_use_gen>
214 #config_where_clause
215 {
216 type InCodeStorageVersion = #in_code_storage_version_ty;
217
218 fn in_code_storage_version() -> Self::InCodeStorageVersion {
219 #storage_version
220 }
221
222 fn on_chain_storage_version() -> #frame_support::traits::StorageVersion {
223 #frame_support::traits::StorageVersion::get::<Self>()
224 }
225 }
226
227 impl<#type_impl_gen> #frame_support::traits::OnGenesis
229 for #pallet_ident<#type_use_gen>
230 #config_where_clause
231 {
232 fn on_genesis() {
233 let storage_version: #frame_support::traits::StorageVersion = #storage_version;
234 storage_version.put::<Self>();
235 }
236 }
237
238 impl<#type_impl_gen> #frame_support::traits::PalletInfoAccess
240 for #pallet_ident<#type_use_gen>
241 #config_where_clause
242 {
243 fn index() -> usize {
244 <
245 <T as #frame_system::Config>::PalletInfo as #frame_support::traits::PalletInfo
246 >::index::<Self>()
247 .expect("Pallet is part of the runtime because pallet `Config` trait is \
248 implemented by the runtime")
249 }
250
251 fn name() -> &'static str {
252 <
253 <T as #frame_system::Config>::PalletInfo as #frame_support::traits::PalletInfo
254 >::name::<Self>()
255 .expect("Pallet is part of the runtime because pallet `Config` trait is \
256 implemented by the runtime")
257 }
258
259 fn name_hash() -> [u8; 16] {
260 <
261 <T as #frame_system::Config>::PalletInfo as #frame_support::traits::PalletInfo
262 >::name_hash::<Self>()
263 .expect("Pallet is part of the runtime because pallet `Config` trait is \
264 implemented by the runtime")
265 }
266
267 fn module_name() -> &'static str {
268 <
269 <T as #frame_system::Config>::PalletInfo as #frame_support::traits::PalletInfo
270 >::module_name::<Self>()
271 .expect("Pallet is part of the runtime because pallet `Config` trait is \
272 implemented by the runtime")
273 }
274
275 fn crate_version() -> #frame_support::traits::CrateVersion {
276 #frame_support::crate_to_crate_version!()
277 }
278 }
279
280 impl<#type_impl_gen> #frame_support::traits::PalletsInfoAccess
281 for #pallet_ident<#type_use_gen>
282 #config_where_clause
283 {
284 fn count() -> usize { 1 }
285 fn infos() -> #frame_support::__private::Vec<#frame_support::traits::PalletInfoData> {
286 use #frame_support::traits::PalletInfoAccess;
287 let item = #frame_support::traits::PalletInfoData {
288 index: Self::index(),
289 name: Self::name(),
290 module_name: Self::module_name(),
291 crate_version: Self::crate_version(),
292 };
293 #frame_support::__private::vec![item]
294 }
295 }
296
297 #storage_info
298 #whitelisted_storage_keys_impl
299
300 impl<#type_use_gen> #pallet_ident<#type_use_gen> {
301 #[allow(dead_code)]
302 #[doc(hidden)]
303 pub fn deprecation_info() -> #frame_support::__private::metadata_ir::ItemDeprecationInfoIR {
304 #deprecation_status
305 }
306 }
307 )
308}