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