pezframe_support_procedural/lib.rs
1// This file is part of Bizinikiwi.
2
3// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Proc macro of Support code for the runtime.
19
20#![recursion_limit = "512"]
21#![deny(rustdoc::broken_intra_doc_links)]
22
23mod benchmark;
24mod construct_runtime;
25mod crate_version;
26mod deprecation;
27mod derive_impl;
28mod dummy_part_checker;
29mod dynamic_params;
30mod key_prefix;
31mod match_and_insert;
32mod no_bound;
33mod pezpallet;
34mod pezpallet_error;
35mod runtime;
36mod storage_alias;
37mod transactional;
38mod tt_macro;
39
40use macro_magic::{import_tokens_attr, import_tokens_attr_verbatim};
41use pezframe_support_procedural_tools::generate_access_from_frame_or_crate;
42use proc_macro::TokenStream;
43use quote::{quote, ToTokens};
44use std::{cell::RefCell, str::FromStr};
45use syn::{parse_macro_input, Error, ItemImpl, ItemMod, TraitItemType};
46
47pub(crate) const INHERENT_INSTANCE_NAME: &str = "__InherentHiddenInstance";
48
49thread_local! {
50 /// A global counter, can be used to generate a relatively unique identifier.
51 static COUNTER: RefCell<Counter> = RefCell::new(Counter(0));
52}
53
54/// Counter to generate a relatively unique identifier for macros. This is necessary because
55/// declarative macros gets hoisted to the crate root, which shares the namespace with other pallets
56/// containing the very same macros.
57struct Counter(u64);
58
59impl Counter {
60 fn inc(&mut self) -> u64 {
61 let ret = self.0;
62 self.0 += 1;
63 ret
64 }
65}
66
67/// Get the value from the given environment variable set by cargo.
68///
69/// The value is parsed into the requested destination type.
70fn get_cargo_env_var<T: FromStr>(version_env: &str) -> std::result::Result<T, ()> {
71 let version = std::env::var(version_env)
72 .unwrap_or_else(|_| panic!("`{}` is always set by cargo; qed", version_env));
73
74 T::from_str(&version).map_err(drop)
75}
76
77/// Generate the counter_prefix related to the storage.
78/// counter_prefix is used by counted storage map.
79fn counter_prefix(prefix: &str) -> String {
80 format!("CounterFor{}", prefix)
81}
82
83/// Construct a runtime, with the given name and the given pallets.
84///
85/// NOTE: A new version of this macro is available at `pezframe_support::runtime`. This macro will
86/// soon be deprecated. Please use the new macro instead.
87///
88/// The parameters here are specific types for `Block`, `NodeBlock`, and `UncheckedExtrinsic`
89/// and the pallets that are used by the runtime.
90/// `Block` is the block type that is used in the runtime and `NodeBlock` is the block type
91/// that is used in the node. For instance they can differ in the extrinsics type.
92///
93/// # Example:
94///
95/// ```ignore
96/// construct_runtime!(
97/// pub enum Runtime where
98/// Block = Block,
99/// NodeBlock = node::Block,
100/// UncheckedExtrinsic = UncheckedExtrinsic
101/// {
102/// System: pezframe_system::{Pezpallet, Call, Event<T>, Config<T>} = 0,
103/// Test: path::to::test::{Pezpallet, Call} = 1,
104///
105/// // Pallets with instances.
106/// Test2_Instance1: test2::<Instance1>::{Pezpallet, Call, Storage, Event<T, I>, Config<T, I>, Origin<T, I>},
107/// Test2_DefaultInstance: test2::{Pezpallet, Call, Storage, Event<T>, Config<T>, Origin<T>} = 4,
108///
109/// // Pallets declared with `pezpallet` attribute macro: no need to define the parts
110/// Test3_Instance1: test3::<Instance1>,
111/// Test3_DefaultInstance: test3,
112///
113/// // with `exclude_parts` keyword some part can be excluded.
114/// Test4_Instance1: test4::<Instance1> exclude_parts { Call, Origin },
115/// Test4_DefaultInstance: test4 exclude_parts { Storage },
116///
117/// // with `use_parts` keyword, a subset of the pezpallet parts can be specified.
118/// Test4_Instance1: test4::<Instance1> use_parts { Pezpallet, Call},
119/// Test4_DefaultInstance: test4 use_parts { Pezpallet },
120/// }
121/// )
122/// ```
123///
124/// Each pezpallet is declared as such:
125/// * `Identifier`: name given to the pezpallet that uniquely identifies it.
126///
127/// * `:`: colon separator
128///
129/// * `path::to::pezpallet`: identifiers separated by colons which declare the path to a pezpallet
130/// definition.
131///
132/// * `::<InstanceN>` optional: specify the instance of the pezpallet to use. If not specified it
133/// will use the default instance (or the only instance in case of non-instantiable pallets).
134///
135/// * `::{ Part1, Part2<T>, .. }` optional if pezpallet declared with `pezframe_support::pezpallet`:
136/// Comma separated parts declared with their generic. If a pezpallet is declared with
137/// `pezframe_support::pezpallet` macro then the parts can be automatically derived if not
138/// explicitly provided. We provide support for the following module parts in a pezpallet:
139///
140/// - `Pezpallet` - Required for all pallets
141/// - `Call` - If the pezpallet has callable functions
142/// - `Storage` - If the pezpallet uses storage
143/// - `Event` or `Event<T>` (if the event is generic) - If the pezpallet emits events
144/// - `Origin` or `Origin<T>` (if the origin is generic) - If the pezpallet has instantiable
145/// origins
146/// - `Config` or `Config<T>` (if the config is generic) - If the pezpallet builds the genesis
147/// storage with `GenesisConfig`
148/// - `Inherent` - If the pezpallet provides/can check inherents.
149/// - `ValidateUnsigned` - If the pezpallet validates unsigned extrinsics.
150///
151/// It is important to list these parts here to export them correctly in the metadata or to make
152/// the pezpallet usable in the runtime.
153///
154/// * `exclude_parts { Part1, Part2 }` optional: comma separated parts without generics. I.e. one of
155/// `Pezpallet`, `Call`, `Storage`, `Event`, `Origin`, `Config`, `Inherent`, `ValidateUnsigned`.
156/// It is incompatible with `use_parts`. This specifies the part to exclude. In order to select
157/// subset of the pezpallet parts.
158///
159/// For example excluding the part `Call` can be useful if the runtime doesn't want to make the
160/// pezpallet calls available.
161///
162/// * `use_parts { Part1, Part2 }` optional: comma separated parts without generics. I.e. one of
163/// `Pezpallet`, `Call`, `Storage`, `Event`, `Origin`, `Config`, `Inherent`, `ValidateUnsigned`.
164/// It is incompatible with `exclude_parts`. This specifies the part to use. In order to select a
165/// subset of the pezpallet parts.
166///
167/// For example not using the part `Call` can be useful if the runtime doesn't want to make the
168/// pezpallet calls available.
169///
170/// * `= $n` optional: number to define at which index the pezpallet variants in `OriginCaller`,
171/// `Call` and `Event` are encoded, and to define the ModuleToIndex value.
172///
173/// if `= $n` is not given, then index is resolved in the same way as fieldless enum in Rust
174/// (i.e. incrementally from previous index):
175/// ```nocompile
176/// pallet1 .. = 2,
177/// pallet2 .., // Here pallet2 is given index 3
178/// pallet3 .. = 0,
179/// pallet4 .., // Here pallet4 is given index 1
180/// ```
181///
182/// # Note
183///
184/// The population of the genesis storage depends on the order of pallets. So, if one of your
185/// pallets depends on another pezpallet, the pezpallet that is depended upon needs to come before
186/// the pezpallet depending on it.
187///
188/// # Type definitions
189///
190/// * The macro generates a type alias for each pezpallet to their `Pezpallet`. E.g. `type System =
191/// pezframe_system::Pezpallet<Runtime>`
192#[proc_macro]
193pub fn construct_runtime(input: TokenStream) -> TokenStream {
194 construct_runtime::construct_runtime(input)
195}
196
197///
198/// ---
199///
200/// Documentation for this macro can be found at `pezframe_support::pezpallet`.
201#[proc_macro_attribute]
202pub fn pezpallet(attr: TokenStream, item: TokenStream) -> TokenStream {
203 pezpallet::pezpallet(attr, item)
204}
205
206/// An attribute macro that can be attached to a (non-empty) module declaration. Doing so will
207/// designate that module as a benchmarking module.
208///
209/// See `pezframe_benchmarking::v2` for more info.
210#[proc_macro_attribute]
211pub fn benchmarks(attr: TokenStream, tokens: TokenStream) -> TokenStream {
212 match benchmark::benchmarks(attr, tokens, false) {
213 Ok(tokens) => tokens,
214 Err(err) => err.to_compile_error().into(),
215 }
216}
217
218/// An attribute macro that can be attached to a (non-empty) module declaration. Doing so will
219/// designate that module as an instance benchmarking module.
220///
221/// See `pezframe_benchmarking::v2` for more info.
222#[proc_macro_attribute]
223pub fn instance_benchmarks(attr: TokenStream, tokens: TokenStream) -> TokenStream {
224 match benchmark::benchmarks(attr, tokens, true) {
225 Ok(tokens) => tokens,
226 Err(err) => err.to_compile_error().into(),
227 }
228}
229
230/// An attribute macro used to declare a benchmark within a benchmarking module. Must be
231/// attached to a function definition containing an `#[extrinsic_call]` or `#[block]`
232/// attribute.
233///
234/// See `pezframe_benchmarking::v2` for more info.
235#[proc_macro_attribute]
236pub fn benchmark(_attrs: TokenStream, _tokens: TokenStream) -> TokenStream {
237 quote!(compile_error!(
238 "`#[benchmark]` must be in a module labeled with #[benchmarks] or #[instance_benchmarks]."
239 ))
240 .into()
241}
242
243/// An attribute macro used to specify the extrinsic call inside a benchmark function, and also
244/// used as a boundary designating where the benchmark setup code ends, and the benchmark
245/// verification code begins.
246///
247/// See `pezframe_benchmarking::v2` for more info.
248#[proc_macro_attribute]
249pub fn extrinsic_call(_attrs: TokenStream, _tokens: TokenStream) -> TokenStream {
250 quote!(compile_error!(
251 "`#[extrinsic_call]` must be in a benchmark function definition labeled with `#[benchmark]`."
252 );)
253 .into()
254}
255
256/// An attribute macro used to specify that a block should be the measured portion of the
257/// enclosing benchmark function, This attribute is also used as a boundary designating where
258/// the benchmark setup code ends, and the benchmark verification code begins.
259///
260/// See `pezframe_benchmarking::v2` for more info.
261#[proc_macro_attribute]
262pub fn block(_attrs: TokenStream, _tokens: TokenStream) -> TokenStream {
263 quote!(compile_error!(
264 "`#[block]` must be in a benchmark function definition labeled with `#[benchmark]`."
265 ))
266 .into()
267}
268
269/// Execute the annotated function in a new storage transaction.
270///
271/// The return type of the annotated function must be `Result`. All changes to storage performed
272/// by the annotated function are discarded if it returns `Err`, or committed if `Ok`.
273///
274/// # Example
275///
276/// ```nocompile
277/// #[transactional]
278/// fn value_commits(v: u32) -> result::Result<u32, &'static str> {
279/// Value::set(v);
280/// Ok(v)
281/// }
282///
283/// #[transactional]
284/// fn value_rollbacks(v: u32) -> result::Result<u32, &'static str> {
285/// Value::set(v);
286/// Err("nah")
287/// }
288/// ```
289#[proc_macro_attribute]
290pub fn transactional(attr: TokenStream, input: TokenStream) -> TokenStream {
291 transactional::transactional(attr, input).unwrap_or_else(|e| e.to_compile_error().into())
292}
293
294///
295/// ---
296///
297/// Documentation for this macro can be found at `pezframe_support::require_transactional`.
298#[proc_macro_attribute]
299pub fn require_transactional(attr: TokenStream, input: TokenStream) -> TokenStream {
300 transactional::require_transactional(attr, input)
301 .unwrap_or_else(|e| e.to_compile_error().into())
302}
303
304/// Derive [`Clone`] but do not bound any generic.
305///
306/// Docs at `pezframe_support::CloneNoBound`.
307#[proc_macro_derive(CloneNoBound)]
308pub fn derive_clone_no_bound(input: TokenStream) -> TokenStream {
309 no_bound::clone::derive_clone_no_bound(input)
310}
311
312/// Derive [`Debug`] but do not bound any generics.
313///
314/// Docs at `pezframe_support::DebugNoBound`.
315#[proc_macro_derive(DebugNoBound)]
316pub fn derive_debug_no_bound(input: TokenStream) -> TokenStream {
317 no_bound::debug::derive_debug_no_bound(input)
318}
319
320/// Derive [`Debug`], if `std` is enabled it uses `pezframe_support::DebugNoBound`, if `std` is not
321/// enabled it just returns `"<wasm:stripped>"`.
322/// This behaviour is useful to prevent bloating the runtime WASM blob from unneeded code.
323#[proc_macro_derive(RuntimeDebugNoBound)]
324pub fn derive_runtime_debug_no_bound(input: TokenStream) -> TokenStream {
325 let try_runtime_or_std_impl: proc_macro2::TokenStream =
326 no_bound::debug::derive_debug_no_bound(input.clone()).into();
327
328 let stripped_impl = {
329 let input = syn::parse_macro_input!(input as syn::DeriveInput);
330
331 let name = &input.ident;
332 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
333
334 quote::quote!(
335 const _: () = {
336 impl #impl_generics ::core::fmt::Debug for #name #ty_generics #where_clause {
337 fn fmt(&self, fmt: &mut ::core::fmt::Formatter) -> core::fmt::Result {
338 fmt.write_str("<wasm:stripped>")
339 }
340 }
341 };
342 )
343 };
344
345 let pezframe_support = match generate_access_from_frame_or_crate("pezframe-support") {
346 Ok(pezframe_support) => pezframe_support,
347 Err(e) => return e.to_compile_error().into(),
348 };
349
350 quote::quote!(
351 #pezframe_support::try_runtime_or_std_enabled! {
352 #try_runtime_or_std_impl
353 }
354 #pezframe_support::try_runtime_and_std_not_enabled! {
355 #stripped_impl
356 }
357 )
358 .into()
359}
360
361/// Derive [`PartialEq`] but do not bound any generic.
362///
363/// Docs at `pezframe_support::PartialEqNoBound`.
364#[proc_macro_derive(PartialEqNoBound)]
365pub fn derive_partial_eq_no_bound(input: TokenStream) -> TokenStream {
366 no_bound::partial_eq::derive_partial_eq_no_bound(input)
367}
368
369/// DeriveEq but do no bound any generic.
370///
371/// Docs at `pezframe_support::EqNoBound`.
372#[proc_macro_derive(EqNoBound)]
373pub fn derive_eq_no_bound(input: TokenStream) -> TokenStream {
374 let input = syn::parse_macro_input!(input as syn::DeriveInput);
375
376 let name = &input.ident;
377 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
378
379 quote::quote_spanned!(name.span() =>
380 #[allow(deprecated)]
381 const _: () = {
382 impl #impl_generics ::core::cmp::Eq for #name #ty_generics #where_clause {}
383 };
384 )
385 .into()
386}
387
388/// Derive [`PartialOrd`] but do not bound any generic. Docs are at
389/// `pezframe_support::PartialOrdNoBound`.
390#[proc_macro_derive(PartialOrdNoBound)]
391pub fn derive_partial_ord_no_bound(input: TokenStream) -> TokenStream {
392 no_bound::partial_ord::derive_partial_ord_no_bound(input)
393}
394
395/// Derive [`Ord`] but do no bound any generic. Docs are at `pezframe_support::OrdNoBound`.
396#[proc_macro_derive(OrdNoBound)]
397pub fn derive_ord_no_bound(input: TokenStream) -> TokenStream {
398 no_bound::ord::derive_ord_no_bound(input)
399}
400
401/// derive `Default` but do no bound any generic. Docs are at `pezframe_support::DefaultNoBound`.
402#[proc_macro_derive(DefaultNoBound, attributes(default))]
403pub fn derive_default_no_bound(input: TokenStream) -> TokenStream {
404 no_bound::default::derive_default_no_bound(input)
405}
406
407/// Macro used internally in FRAME to generate the crate version for a pezpallet.
408#[proc_macro]
409pub fn crate_to_crate_version(input: TokenStream) -> TokenStream {
410 crate_version::crate_to_crate_version(input)
411 .unwrap_or_else(|e| e.to_compile_error())
412 .into()
413}
414
415/// The number of module instances supported by the runtime, starting at index 1,
416/// and up to `NUMBER_OF_INSTANCE`.
417pub(crate) const NUMBER_OF_INSTANCE: u8 = 16;
418
419/// This macro is meant to be used by pezframe-support only.
420/// It implements the trait `HasKeyPrefix` and `HasReversibleKeyPrefix` for tuple of `Key`.
421#[proc_macro]
422pub fn impl_key_prefix_for_tuples(input: TokenStream) -> TokenStream {
423 key_prefix::impl_key_prefix_for_tuples(input)
424 .unwrap_or_else(syn::Error::into_compile_error)
425 .into()
426}
427
428/// Internal macro use by pezframe_support to generate dummy part checker for old pezpallet
429/// declaration
430#[proc_macro]
431pub fn __generate_dummy_part_checker(input: TokenStream) -> TokenStream {
432 dummy_part_checker::generate_dummy_part_checker(input)
433}
434
435/// Macro that inserts some tokens after the first match of some pattern.
436///
437/// # Example:
438///
439/// ```nocompile
440/// match_and_insert!(
441/// target = [{ Some content with { at some point match pattern } other match pattern are ignored }]
442/// pattern = [{ match pattern }] // the match pattern cannot contain any group: `[]`, `()`, `{}`
443/// // can relax this constraint, but will require modifying the match logic in code
444/// tokens = [{ expansion tokens }] // content inside braces can be anything including groups
445/// );
446/// ```
447///
448/// will generate:
449///
450/// ```nocompile
451/// Some content with { at some point match pattern expansion tokens } other match patterns are
452/// ignored
453/// ```
454#[proc_macro]
455pub fn match_and_insert(input: TokenStream) -> TokenStream {
456 match_and_insert::match_and_insert(input)
457}
458
459#[proc_macro_derive(PalletError, attributes(codec))]
460pub fn derive_pallet_error(input: TokenStream) -> TokenStream {
461 pezpallet_error::derive_pallet_error(input)
462}
463
464/// Internal macro used by `pezframe_support` to create tt-call-compliant macros
465#[proc_macro]
466pub fn __create_tt_macro(input: TokenStream) -> TokenStream {
467 tt_macro::create_tt_return_macro(input)
468}
469
470///
471/// ---
472///
473/// Documentation for this macro can be found at
474/// `pezframe_support::pezpallet_macros::storage_alias`.
475#[proc_macro_attribute]
476pub fn storage_alias(attributes: TokenStream, input: TokenStream) -> TokenStream {
477 storage_alias::storage_alias(attributes.into(), input.into())
478 .unwrap_or_else(|r| r.into_compile_error())
479 .into()
480}
481
482/// This attribute can be used to derive a full implementation of a trait based on a local partial
483/// impl and an external impl containing defaults that can be overridden in the local impl.
484///
485/// For a full end-to-end example, see [below](#use-case-auto-derive-test-pezpallet-config-traits).
486///
487/// # Usage
488///
489/// The attribute should be attached to an impl block (strictly speaking a `syn::ItemImpl`) for
490/// which we want to inject defaults in the event of missing trait items in the block.
491///
492/// The attribute minimally takes a single `default_impl_path` argument, which should be the module
493/// path to an impl registered via [`#[register_default_impl]`](`macro@register_default_impl`) that
494/// contains the default trait items we want to potentially inject, with the general form:
495///
496/// ```ignore
497/// #[derive_impl(default_impl_path)]
498/// impl SomeTrait for SomeStruct {
499/// ...
500/// }
501/// ```
502///
503/// Optionally, a `disambiguation_path` can be specified as follows by providing `as path::here`
504/// after the `default_impl_path`:
505///
506/// ```ignore
507/// #[derive_impl(default_impl_path as disambiguation_path)]
508/// impl SomeTrait for SomeStruct {
509/// ...
510/// }
511/// ```
512///
513/// The `disambiguation_path`, if specified, should be the path to a trait that will be used to
514/// qualify all default entries that are injected into the local impl. For example if your
515/// `default_impl_path` is `some::path::TestTraitImpl` and your `disambiguation_path` is
516/// `another::path::DefaultTrait`, any items injected into the local impl will be qualified as
517/// `<some::path::TestTraitImpl as another::path::DefaultTrait>::specific_trait_item`.
518///
519/// If you omit the `as disambiguation_path` portion, the `disambiguation_path` will internally
520/// default to `A` from the `impl A for B` part of the default impl. This is useful for scenarios
521/// where all of the relevant types are already in scope via `use` statements.
522///
523/// In case the `default_impl_path` is scoped to a different module such as
524/// `some::path::TestTraitImpl`, the same scope is assumed for the `disambiguation_path`, i.e.
525/// `some::A`. This enables the use of `derive_impl` attribute without having to specify the
526/// `disambiguation_path` in most (if not all) uses within FRAME's context.
527///
528/// Conversely, the `default_impl_path` argument is required and cannot be omitted.
529///
530/// Optionally, `no_aggregated_types` can be specified as follows:
531///
532/// ```ignore
533/// #[derive_impl(default_impl_path as disambiguation_path, no_aggregated_types)]
534/// impl SomeTrait for SomeStruct {
535/// ...
536/// }
537/// ```
538///
539/// If specified, this indicates that the aggregated types (as denoted by impl items
540/// attached with [`#[inject_runtime_type]`]) should not be injected with the respective concrete
541/// types. By default, all such types are injected.
542///
543/// You can also make use of `#[pezpallet::no_default]` on specific items in your default impl that
544/// you want to ensure will not be copied over but that you nonetheless want to use locally in the
545/// context of the foreign impl and the pezpallet (or context) in which it is defined.
546///
547/// ## Use-Case Example: Auto-Derive Test Pezpallet Config Traits
548///
549/// The `#[derive_imp(..)]` attribute can be used to derive a test pezpallet `Config` based on an
550/// existing pezpallet `Config` that has been marked with
551/// [`#[pezpallet::config(with_default)]`](`macro@config`) (which under the hood, generates a
552/// `DefaultConfig` trait in the pezpallet in which the macro was invoked).
553///
554/// In this case, the `#[derive_impl(..)]` attribute should be attached to an `impl` block that
555/// implements a compatible `Config` such as `pezframe_system::Config` for a test/mock runtime, and
556/// should receive as its first argument the path to a `DefaultConfig` impl that has been registered
557/// via [`#[register_default_impl]`](`macro@register_default_impl`), and as its second argument, the
558/// path to the auto-generated `DefaultConfig` for the existing pezpallet `Config` we want to base
559/// our test config off of.
560///
561/// The following is what the `basic` example pezpallet would look like with a default testing
562/// config:
563///
564/// ```ignore
565/// #[derive_impl(pezframe_system::config_preludes::TestDefaultConfig as pezframe_system::pezpallet::DefaultConfig)]
566/// impl pezframe_system::Config for Test {
567/// // These are all defined by system as mandatory.
568/// type BaseCallFilter = pezframe_support::traits::Everything;
569/// type RuntimeEvent = RuntimeEvent;
570/// type RuntimeCall = RuntimeCall;
571/// type RuntimeOrigin = RuntimeOrigin;
572/// type OnSetCode = ();
573/// type PalletInfo = PalletInfo;
574/// type Block = Block;
575/// // We decide to override this one.
576/// type AccountData = pezpallet_balances::AccountData<u64>;
577/// }
578/// ```
579///
580/// where `TestDefaultConfig` was defined and registered as follows:
581/// ```ignore
582/// pub struct TestDefaultConfig;
583///
584/// #[register_default_impl(TestDefaultConfig)]
585/// impl DefaultConfig for TestDefaultConfig {
586/// type Version = ();
587/// type BlockWeights = ();
588/// type BlockLength = ();
589/// type DbWeight = ();
590/// type Nonce = u64;
591/// type BlockNumber = u64;
592/// type Hash = pezsp_core::hash::H256;
593/// type Hashing = pezsp_runtime::traits::BlakeTwo256;
594/// type AccountId = AccountId;
595/// type Lookup = IdentityLookup<AccountId>;
596/// type BlockHashCount = pezframe_support::traits::ConstU64<10>;
597/// type AccountData = u32;
598/// type OnNewAccount = ();
599/// type OnKilledAccount = ();
600/// type SystemWeightInfo = ();
601/// type SS58Prefix = ();
602/// type MaxConsumers = pezframe_support::traits::ConstU32<16>;
603/// }
604/// ```
605///
606/// The above call to `derive_impl` would expand to roughly the following:
607/// ```ignore
608/// impl pezframe_system::Config for Test {
609/// use pezframe_system::config_preludes::TestDefaultConfig;
610/// use pezframe_system::pezpallet::DefaultConfig;
611///
612/// type BaseCallFilter = pezframe_support::traits::Everything;
613/// type RuntimeEvent = RuntimeEvent;
614/// type RuntimeCall = RuntimeCall;
615/// type RuntimeOrigin = RuntimeOrigin;
616/// type OnSetCode = ();
617/// type PalletInfo = PalletInfo;
618/// type Block = Block;
619/// type AccountData = pezpallet_balances::AccountData<u64>;
620/// type Version = <TestDefaultConfig as DefaultConfig>::Version;
621/// type BlockWeights = <TestDefaultConfig as DefaultConfig>::BlockWeights;
622/// type BlockLength = <TestDefaultConfig as DefaultConfig>::BlockLength;
623/// type DbWeight = <TestDefaultConfig as DefaultConfig>::DbWeight;
624/// type Nonce = <TestDefaultConfig as DefaultConfig>::Nonce;
625/// type BlockNumber = <TestDefaultConfig as DefaultConfig>::BlockNumber;
626/// type Hash = <TestDefaultConfig as DefaultConfig>::Hash;
627/// type Hashing = <TestDefaultConfig as DefaultConfig>::Hashing;
628/// type AccountId = <TestDefaultConfig as DefaultConfig>::AccountId;
629/// type Lookup = <TestDefaultConfig as DefaultConfig>::Lookup;
630/// type BlockHashCount = <TestDefaultConfig as DefaultConfig>::BlockHashCount;
631/// type OnNewAccount = <TestDefaultConfig as DefaultConfig>::OnNewAccount;
632/// type OnKilledAccount = <TestDefaultConfig as DefaultConfig>::OnKilledAccount;
633/// type SystemWeightInfo = <TestDefaultConfig as DefaultConfig>::SystemWeightInfo;
634/// type SS58Prefix = <TestDefaultConfig as DefaultConfig>::SS58Prefix;
635/// type MaxConsumers = <TestDefaultConfig as DefaultConfig>::MaxConsumers;
636/// }
637/// ```
638///
639/// You can then use the resulting `Test` config in test scenarios.
640///
641/// Note that items that are _not_ present in our local `DefaultConfig` are automatically copied
642/// from the foreign trait (in this case `TestDefaultConfig`) into the local trait impl (in this
643/// case `Test`), unless the trait item in the local trait impl is marked with
644/// [`#[pezpallet::no_default]`](`macro@no_default`), in which case it cannot be overridden, and any
645/// attempts to do so will result in a compiler error.
646///
647/// See `frame/examples/default-config/tests.rs` for a runnable end-to-end example pezpallet that
648/// makes use of `derive_impl` to derive its testing config.
649///
650/// See [here](`macro@config`) for more information and caveats about the auto-generated
651/// `DefaultConfig` trait.
652///
653/// ## Optional Conventions
654///
655/// Note that as an optional convention, we encourage creating a `config_preludes` module inside of
656/// your pezpallet. This is the convention we follow for `pezframe_system`'s `TestDefaultConfig`
657/// which, as shown above, is located at `pezframe_system::config_preludes::TestDefaultConfig`. This
658/// is just a suggested convention -- there is nothing in the code that expects modules with these
659/// names to be in place, so there is no imperative to follow this pattern unless desired.
660///
661/// In `config_preludes`, you can place types named like:
662///
663/// * `TestDefaultConfig`
664/// * `TeyrchainDefaultConfig`
665/// * `SolochainDefaultConfig`
666///
667/// Signifying in which context they can be used.
668///
669/// # Advanced Usage
670///
671/// ## Expansion
672///
673/// The `#[derive_impl(default_impl_path as disambiguation_path)]` attribute will expand to the
674/// local impl, with any extra items from the foreign impl that aren't present in the local impl
675/// also included. In the case of a colliding trait item, the version of the item that exists in the
676/// local impl will be retained. All imported items are qualified by the `disambiguation_path`, as
677/// discussed above.
678///
679/// ## Handling of Unnamed Trait Items
680///
681/// Items that lack a `syn::Ident` for whatever reason are first checked to see if they exist,
682/// verbatim, in the local/destination trait before they are copied over, so you should not need to
683/// worry about collisions between identical unnamed items.
684#[import_tokens_attr_verbatim {
685 format!(
686 "{}::macro_magic",
687 match generate_access_from_frame_or_crate("pezframe-support") {
688 Ok(path) => Ok(path),
689 Err(_) => generate_access_from_frame_or_crate("pezkuwi-sdk-frame"),
690 }
691 .expect("Failed to find either `pezframe-support` or `pezkuwi-sdk-frame` in `Cargo.toml` dependencies.")
692 .to_token_stream()
693 .to_string()
694 )
695}]
696#[with_custom_parsing(derive_impl::DeriveImplAttrArgs)]
697#[proc_macro_attribute]
698pub fn derive_impl(attrs: TokenStream, input: TokenStream) -> TokenStream {
699 let custom_attrs = parse_macro_input!(__custom_tokens as derive_impl::DeriveImplAttrArgs);
700 derive_impl::derive_impl(
701 __source_path.into(),
702 attrs.into(),
703 input.into(),
704 custom_attrs.disambiguation_path,
705 custom_attrs.no_aggregated_types,
706 custom_attrs.generics,
707 )
708 .unwrap_or_else(|r| r.into_compile_error())
709 .into()
710}
711
712///
713/// ---
714///
715/// Documentation for this macro can be found at `pezframe_support::pezpallet_macros::no_default`.
716#[proc_macro_attribute]
717pub fn no_default(_: TokenStream, _: TokenStream) -> TokenStream {
718 pezpallet_macro_stub()
719}
720
721///
722/// ---
723///
724/// Documentation for this macro can be found at
725/// `pezframe_support::pezpallet_macros::no_default_bounds`.
726#[proc_macro_attribute]
727pub fn no_default_bounds(_: TokenStream, _: TokenStream) -> TokenStream {
728 pezpallet_macro_stub()
729}
730
731/// Attach this attribute to an impl statement that you want to use with
732/// [`#[derive_impl(..)]`](`macro@derive_impl`).
733///
734/// You must also provide an identifier/name as the attribute's argument. This is the name you
735/// must provide to [`#[derive_impl(..)]`](`macro@derive_impl`) when you import this impl via
736/// the `default_impl_path` argument. This name should be unique at the crate-level.
737///
738/// ## Example
739///
740/// ```ignore
741/// pub struct ExampleTestDefaultConfig;
742///
743/// #[register_default_impl(ExampleTestDefaultConfig)]
744/// impl DefaultConfig for ExampleTestDefaultConfig {
745/// type Version = ();
746/// type BlockWeights = ();
747/// type BlockLength = ();
748/// ...
749/// type SS58Prefix = ();
750/// type MaxConsumers = pezframe_support::traits::ConstU32<16>;
751/// }
752/// ```
753///
754/// ## Advanced Usage
755///
756/// This macro acts as a thin wrapper around macro_magic's `#[export_tokens]`. See the docs
757/// [here](https://docs.rs/macro_magic/latest/macro_magic/attr.export_tokens.html) for more
758/// info.
759///
760/// There are some caveats when applying a `use` statement to bring a
761/// `#[register_default_impl]` item into scope. If you have a `#[register_default_impl]`
762/// defined in `my_crate::submodule::MyItem`, it is currently not sufficient to do something
763/// like:
764///
765/// ```ignore
766/// use my_crate::submodule::MyItem;
767/// #[derive_impl(MyItem as Whatever)]
768/// ```
769///
770/// This will fail with a mysterious message about `__export_tokens_tt_my_item` not being
771/// defined.
772///
773/// You can, however, do any of the following:
774/// ```ignore
775/// // partial path works
776/// use my_crate::submodule;
777/// #[derive_impl(submodule::MyItem as Whatever)]
778/// ```
779/// ```ignore
780/// // full path works
781/// #[derive_impl(my_crate::submodule::MyItem as Whatever)]
782/// ```
783/// ```ignore
784/// // wild-cards work
785/// use my_crate::submodule::*;
786/// #[derive_impl(MyItem as Whatever)]
787/// ```
788#[proc_macro_attribute]
789pub fn register_default_impl(attrs: TokenStream, tokens: TokenStream) -> TokenStream {
790 // ensure this is a impl statement
791 let item_impl = syn::parse_macro_input!(tokens as ItemImpl);
792
793 // internally wrap macro_magic's `#[export_tokens]` macro
794 match macro_magic::mm_core::export_tokens_internal(
795 attrs,
796 item_impl.to_token_stream(),
797 true,
798 false,
799 ) {
800 Ok(tokens) => tokens.into(),
801 Err(err) => err.to_compile_error().into(),
802 }
803}
804
805/// The optional attribute `#[inject_runtime_type]` can be attached to `RuntimeCall`,
806/// `RuntimeEvent`, `RuntimeOrigin` or `PalletInfo` in an impl statement that has
807/// `#[register_default_impl]` attached to indicate that this item is generated by
808/// `construct_runtime`.
809///
810/// Attaching this attribute to such an item ensures that the combined impl generated via
811/// [`#[derive_impl(..)]`](macro@derive_impl) will use the correct type auto-generated by
812/// `construct_runtime!`.
813#[doc = docify::embed!("examples/proc_main/inject_runtime_type.rs", derive_impl_works_with_runtime_type_injection)]
814///
815/// However, if `no_aggregated_types` is specified while using
816/// [`#[derive_impl(..)]`](macro@derive_impl), then these items are attached verbatim to the
817/// combined impl.
818#[doc = docify::embed!("examples/proc_main/inject_runtime_type.rs", derive_impl_works_with_no_aggregated_types)]
819#[proc_macro_attribute]
820pub fn inject_runtime_type(_: TokenStream, tokens: TokenStream) -> TokenStream {
821 let item = tokens.clone();
822 let item = syn::parse_macro_input!(item as TraitItemType);
823 if item.ident != "RuntimeCall"
824 && item.ident != "RuntimeEvent"
825 && item.ident != "RuntimeTask"
826 && item.ident != "RuntimeViewFunction"
827 && item.ident != "RuntimeOrigin"
828 && item.ident != "RuntimeHoldReason"
829 && item.ident != "RuntimeFreezeReason"
830 && item.ident != "RuntimeParameters"
831 && item.ident != "PalletInfo"
832 {
833 return syn::Error::new_spanned(
834 item,
835 "`#[inject_runtime_type]` can only be attached to `RuntimeCall`, `RuntimeEvent`, \
836 `RuntimeTask`, `RuntimeViewFunction`, `RuntimeOrigin`, `RuntimeParameters` or `PalletInfo`",
837 )
838 .to_compile_error()
839 .into();
840 }
841 tokens
842}
843
844/// Used internally to decorate pezpallet attribute macro stubs when they are erroneously used
845/// outside of a pezpallet module
846fn pezpallet_macro_stub() -> TokenStream {
847 quote!(compile_error!(
848 "This attribute can only be used from within a pezpallet module marked with `#[pezframe_support::pezpallet]`"
849 ))
850 .into()
851}
852
853///
854/// ---
855///
856/// Documentation for this macro can be found at `pezframe_support::pezpallet_macros::config`.
857#[proc_macro_attribute]
858pub fn config(_: TokenStream, _: TokenStream) -> TokenStream {
859 pezpallet_macro_stub()
860}
861
862///
863/// ---
864///
865/// Documentation for this macro can be found at `pezframe_support::pezpallet_macros::constant`.
866#[proc_macro_attribute]
867pub fn constant(_: TokenStream, _: TokenStream) -> TokenStream {
868 pezpallet_macro_stub()
869}
870
871///
872/// ---
873///
874/// Documentation for this macro can be found at
875/// `pezframe_support::pezpallet_macros::constant_name`.
876#[proc_macro_attribute]
877pub fn constant_name(_: TokenStream, _: TokenStream) -> TokenStream {
878 pezpallet_macro_stub()
879}
880
881///
882/// ---
883///
884/// Documentation for this macro can be found at
885/// `pezframe_support::pezpallet_macros::disable_pezframe_system_supertrait_check`.
886#[proc_macro_attribute]
887pub fn disable_pezframe_system_supertrait_check(_: TokenStream, _: TokenStream) -> TokenStream {
888 pezpallet_macro_stub()
889}
890
891///
892/// ---
893///
894/// Documentation for this macro can be found at
895/// `pezframe_support::pezpallet_macros::storage_version`.
896#[proc_macro_attribute]
897pub fn storage_version(_: TokenStream, _: TokenStream) -> TokenStream {
898 pezpallet_macro_stub()
899}
900
901///
902/// ---
903///
904/// Documentation for this macro can be found at `pezframe_support::pezpallet_macros::hooks`.
905#[proc_macro_attribute]
906pub fn hooks(_: TokenStream, _: TokenStream) -> TokenStream {
907 pezpallet_macro_stub()
908}
909
910///
911/// ---
912///
913/// Documentation for this macro can be found at `pezframe_support::pezpallet_macros::weight`.
914#[proc_macro_attribute]
915pub fn weight(_: TokenStream, _: TokenStream) -> TokenStream {
916 pezpallet_macro_stub()
917}
918
919///
920/// ---
921///
922/// Documentation for this macro can be found at `pezframe_support::pezpallet_macros::compact`.
923#[proc_macro_attribute]
924pub fn compact(_: TokenStream, _: TokenStream) -> TokenStream {
925 pezpallet_macro_stub()
926}
927
928///
929/// ---
930///
931/// Documentation for this macro can be found at `pezframe_support::pezpallet_macros::call`.
932#[proc_macro_attribute]
933pub fn call(_: TokenStream, _: TokenStream) -> TokenStream {
934 pezpallet_macro_stub()
935}
936
937/// Each dispatchable may also be annotated with the `#[pezpallet::call_index($idx)]` attribute,
938/// which explicitly defines the codec index for the dispatchable function in the `Call` enum.
939///
940/// ---
941///
942/// Documentation for this macro can be found at `pezframe_support::pezpallet_macros::call_index`.
943#[proc_macro_attribute]
944pub fn call_index(_: TokenStream, _: TokenStream) -> TokenStream {
945 pezpallet_macro_stub()
946}
947
948///
949/// ---
950///
951/// Documentation for this macro can be found at `pezframe_support::pezpallet_macros::feeless_if`.
952#[proc_macro_attribute]
953pub fn feeless_if(_: TokenStream, _: TokenStream) -> TokenStream {
954 pezpallet_macro_stub()
955}
956
957///
958/// ---
959///
960/// Documentation for this macro can be found at
961/// `pezframe_support::pezpallet_macros::extra_constants`.
962#[proc_macro_attribute]
963pub fn extra_constants(_: TokenStream, _: TokenStream) -> TokenStream {
964 pezpallet_macro_stub()
965}
966
967///
968/// ---
969///
970/// Documentation for this macro can be found at `pezframe_support::pezpallet_macros::error`.
971#[proc_macro_attribute]
972pub fn error(_: TokenStream, _: TokenStream) -> TokenStream {
973 pezpallet_macro_stub()
974}
975
976///
977/// ---
978///
979/// Documentation for this macro can be found at `pezframe_support::pezpallet_macros::event`.
980#[proc_macro_attribute]
981pub fn event(_: TokenStream, _: TokenStream) -> TokenStream {
982 pezpallet_macro_stub()
983}
984
985///
986/// ---
987///
988/// Documentation for this macro can be found at
989/// `pezframe_support::pezpallet_macros::include_metadata`.
990#[proc_macro_attribute]
991pub fn include_metadata(_: TokenStream, _: TokenStream) -> TokenStream {
992 pezpallet_macro_stub()
993}
994
995///
996/// ---
997///
998/// Documentation for this macro can be found at
999/// `pezframe_support::pezpallet_macros::generate_deposit`.
1000#[proc_macro_attribute]
1001pub fn generate_deposit(_: TokenStream, _: TokenStream) -> TokenStream {
1002 pezpallet_macro_stub()
1003}
1004
1005///
1006/// ---
1007///
1008/// Documentation for this macro can be found at `pezframe_support::pezpallet_macros::storage`.
1009#[proc_macro_attribute]
1010pub fn storage(_: TokenStream, _: TokenStream) -> TokenStream {
1011 pezpallet_macro_stub()
1012}
1013
1014///
1015/// ---
1016///
1017/// Documentation for this macro can be found at `pezframe_support::pezpallet_macros::getter`.
1018#[proc_macro_attribute]
1019pub fn getter(_: TokenStream, _: TokenStream) -> TokenStream {
1020 pezpallet_macro_stub()
1021}
1022
1023///
1024/// ---
1025///
1026/// Documentation for this macro can be found at
1027/// `pezframe_support::pezpallet_macros::storage_prefix`.
1028#[proc_macro_attribute]
1029pub fn storage_prefix(_: TokenStream, _: TokenStream) -> TokenStream {
1030 pezpallet_macro_stub()
1031}
1032
1033///
1034/// ---
1035///
1036/// Documentation for this macro can be found at `pezframe_support::pezpallet_macros::unbounded`.
1037#[proc_macro_attribute]
1038pub fn unbounded(_: TokenStream, _: TokenStream) -> TokenStream {
1039 pezpallet_macro_stub()
1040}
1041
1042///
1043/// ---
1044///
1045/// Documentation for this macro can be found at
1046/// `pezframe_support::pezpallet_macros::whitelist_storage`.
1047#[proc_macro_attribute]
1048pub fn whitelist_storage(_: TokenStream, _: TokenStream) -> TokenStream {
1049 pezpallet_macro_stub()
1050}
1051
1052///
1053/// ---
1054///
1055/// Documentation for this macro can be found at
1056/// `pezframe_support::pezpallet_macros::disable_try_decode_storage`.
1057#[proc_macro_attribute]
1058pub fn disable_try_decode_storage(_: TokenStream, _: TokenStream) -> TokenStream {
1059 pezpallet_macro_stub()
1060}
1061
1062///
1063/// ---
1064///
1065/// Documentation for this macro can be found at `pezframe_support::pezpallet_macros::type_value`.
1066#[proc_macro_attribute]
1067pub fn type_value(_: TokenStream, _: TokenStream) -> TokenStream {
1068 pezpallet_macro_stub()
1069}
1070
1071///
1072/// ---
1073///
1074/// Documentation for this macro can be found at
1075/// `pezframe_support::pezpallet_macros::genesis_config`.
1076#[proc_macro_attribute]
1077pub fn genesis_config(_: TokenStream, _: TokenStream) -> TokenStream {
1078 pezpallet_macro_stub()
1079}
1080
1081///
1082/// ---
1083///
1084/// Documentation for this macro can be found at
1085/// `pezframe_support::pezpallet_macros::genesis_build`.
1086#[proc_macro_attribute]
1087pub fn genesis_build(_: TokenStream, _: TokenStream) -> TokenStream {
1088 pezpallet_macro_stub()
1089}
1090
1091///
1092/// ---
1093///
1094/// Documentation for this macro can be found at `pezframe_support::pezpallet_macros::inherent`.
1095#[proc_macro_attribute]
1096pub fn inherent(_: TokenStream, _: TokenStream) -> TokenStream {
1097 pezpallet_macro_stub()
1098}
1099
1100///
1101/// ---
1102///
1103/// Documentation for this macro can be found at
1104/// `pezframe_support::pezpallet_macros::validate_unsigned`.
1105#[proc_macro_attribute]
1106pub fn validate_unsigned(_: TokenStream, _: TokenStream) -> TokenStream {
1107 pezpallet_macro_stub()
1108}
1109
1110///
1111/// ---
1112///
1113/// Documentation for this macro can be found at
1114/// `pezframe_support::pezpallet_macros::view_functions`.
1115#[proc_macro_attribute]
1116pub fn view_functions(_: TokenStream, _: TokenStream) -> TokenStream {
1117 pezpallet_macro_stub()
1118}
1119
1120///
1121/// ---
1122///
1123/// Documentation for this macro can be found at `pezframe_support::pezpallet_macros::origin`.
1124#[proc_macro_attribute]
1125pub fn origin(_: TokenStream, _: TokenStream) -> TokenStream {
1126 pezpallet_macro_stub()
1127}
1128
1129///
1130/// ---
1131///
1132/// Documentation for this macro can be found at
1133/// `pezframe_support::pezpallet_macros::composite_enum`.
1134#[proc_macro_attribute]
1135pub fn composite_enum(_: TokenStream, _: TokenStream) -> TokenStream {
1136 pezpallet_macro_stub()
1137}
1138
1139/// Allows you to define some service work that can be recognized by the off-chain worker.
1140///
1141/// The off-chain worker can then create and submit all such work items at any given time.
1142///
1143/// These work items are defined as instances of the `Task` trait (found at
1144/// `pezframe_support::traits::Task`). [`pezpallet:tasks_experimental`](macro@tasks_experimental)
1145/// when attached to an `impl` block inside a pezpallet, will generate an enum `Task<T>` whose
1146/// variants are mapped to functions inside this `impl` block.
1147///
1148/// Each such function must have the following set of attributes:
1149///
1150/// * [`pezpallet::task_list`](macro@task_list)
1151/// * [`pezpallet::task_condition`](macro@task_condition)
1152/// * [`pezpallet::task_weight`](macro@task_weight)
1153/// * [`pezpallet::task_index`](macro@task_index)
1154///
1155/// All of such Tasks are then aggregated into a `RuntimeTask` by
1156/// [`construct_runtime`](macro@construct_runtime).
1157///
1158/// Finally, the `RuntimeTask` can then be used by the off-chain worker to create and
1159/// submit such tasks via an extrinsic defined in `pezframe_system` called `do_task` which accepts
1160/// unsigned transaction from local source.
1161///
1162/// When submitted as unsigned transactions, note that the tasks will be executed in a random order.
1163///
1164/// ## Example
1165#[doc = docify::embed!("examples/proc_main/tasks.rs", tasks_example)]
1166/// Now, this can be executed as follows:
1167#[doc = docify::embed!("examples/proc_main/tasks.rs", tasks_work)]
1168#[proc_macro_attribute]
1169pub fn tasks_experimental(_: TokenStream, _: TokenStream) -> TokenStream {
1170 pezpallet_macro_stub()
1171}
1172
1173/// Allows defining an iterator over available work items for a task.
1174///
1175/// This attribute is attached to a function inside an `impl` block annotated with
1176/// [`pezpallet::tasks_experimental`](macro@tasks_experimental).
1177///
1178/// It takes an iterator as input that yields a tuple with same types as the function
1179/// arguments.
1180#[proc_macro_attribute]
1181pub fn task_list(_: TokenStream, _: TokenStream) -> TokenStream {
1182 pezpallet_macro_stub()
1183}
1184
1185/// Allows defining conditions for a task to run.
1186///
1187/// This attribute is attached to a function inside an `impl` block annotated with
1188/// [`pezpallet::tasks_experimental`](macro@tasks_experimental) to define the conditions for a
1189/// given work item to be valid.
1190///
1191/// It takes a closure as input, which is then used to define the condition. The closure
1192/// should have the same signature as the function it is attached to, except that it should
1193/// return a `bool` instead.
1194#[proc_macro_attribute]
1195pub fn task_condition(_: TokenStream, _: TokenStream) -> TokenStream {
1196 pezpallet_macro_stub()
1197}
1198
1199/// Allows defining the weight of a task.
1200///
1201/// This attribute is attached to a function inside an `impl` block annotated with
1202/// [`pezpallet::tasks_experimental`](macro@tasks_experimental) define the weight of a given work
1203/// item.
1204///
1205/// It takes a closure as input, which should return a `Weight` value.
1206#[proc_macro_attribute]
1207pub fn task_weight(_: TokenStream, _: TokenStream) -> TokenStream {
1208 pezpallet_macro_stub()
1209}
1210
1211/// Allows defining an index for a task.
1212///
1213/// This attribute is attached to a function inside an `impl` block annotated with
1214/// [`pezpallet::tasks_experimental`](macro@tasks_experimental) to define the index of a given
1215/// work item.
1216///
1217/// It takes an integer literal as input, which is then used to define the index. This
1218/// index should be unique for each function in the `impl` block.
1219#[proc_macro_attribute]
1220pub fn task_index(_: TokenStream, _: TokenStream) -> TokenStream {
1221 pezpallet_macro_stub()
1222}
1223
1224///
1225/// ---
1226///
1227/// **Rust-Analyzer users**: See the documentation of the Rust item in
1228/// `pezframe_support::pezpallet_macros::pezpallet_section`.
1229#[proc_macro_attribute]
1230pub fn pezpallet_section(attr: TokenStream, tokens: TokenStream) -> TokenStream {
1231 let tokens_clone = tokens.clone();
1232 // ensure this can only be attached to a module
1233 let _mod = parse_macro_input!(tokens_clone as ItemMod);
1234
1235 // use macro_magic's export_tokens as the internal implementation otherwise
1236 match macro_magic::mm_core::export_tokens_internal(attr, tokens, false, true) {
1237 Ok(tokens) => tokens.into(),
1238 Err(err) => err.to_compile_error().into(),
1239 }
1240}
1241
1242///
1243/// ---
1244///
1245/// **Rust-Analyzer users**: See the documentation of the Rust item in
1246/// `pezframe_support::pezpallet_macros::import_section`.
1247#[import_tokens_attr {
1248 format!(
1249 "{}::macro_magic",
1250 match generate_access_from_frame_or_crate("pezframe-support") {
1251 Ok(path) => Ok(path),
1252 Err(_) => generate_access_from_frame_or_crate("pezkuwi-sdk-frame"),
1253 }
1254 .expect("Failed to find either `pezframe-support` or `pezkuwi-sdk-frame` in `Cargo.toml` dependencies.")
1255 .to_token_stream()
1256 .to_string()
1257 )
1258}]
1259#[proc_macro_attribute]
1260pub fn import_section(attr: TokenStream, tokens: TokenStream) -> TokenStream {
1261 let foreign_mod = parse_macro_input!(attr as ItemMod);
1262 let mut internal_mod = parse_macro_input!(tokens as ItemMod);
1263
1264 // check that internal_mod is a pezpallet module
1265 if !internal_mod.attrs.iter().any(|attr| {
1266 if let Some(last_seg) = attr.path().segments.last() {
1267 last_seg.ident == "pezpallet"
1268 } else {
1269 false
1270 }
1271 }) {
1272 return Error::new(
1273 internal_mod.ident.span(),
1274 "`#[import_section]` can only be applied to a valid pezpallet module",
1275 )
1276 .to_compile_error()
1277 .into();
1278 }
1279
1280 if let Some(ref mut content) = internal_mod.content {
1281 if let Some(foreign_content) = foreign_mod.content {
1282 content.1.extend(foreign_content.1);
1283 }
1284 }
1285
1286 quote! {
1287 #internal_mod
1288 }
1289 .into()
1290}
1291
1292/// Construct a runtime, with the given name and the given pallets.
1293///
1294/// # Example:
1295#[doc = docify::embed!("examples/proc_main/runtime.rs", runtime_macro)]
1296///
1297/// # Supported Attributes:
1298///
1299/// ## Legacy Ordering
1300///
1301/// An optional attribute can be defined as #[pezframe_support::runtime(legacy_ordering)] to
1302/// ensure that the order of hooks is same as the order of pallets (and not based on the
1303/// pezpallet_index). This is to support legacy runtimes and should be avoided for new ones.
1304///
1305/// # Note
1306///
1307/// The population of the genesis storage depends on the order of pallets. So, if one of your
1308/// pallets depends on another pezpallet, the pezpallet that is depended upon needs to come before
1309/// the pezpallet depending on it.
1310///
1311/// # Type definitions
1312///
1313/// * The macro generates a type alias for each pezpallet to their `Pezpallet`. E.g. `type System =
1314/// pezframe_system::Pezpallet<Runtime>`
1315#[proc_macro_attribute]
1316pub fn runtime(attr: TokenStream, item: TokenStream) -> TokenStream {
1317 runtime::runtime(attr, item)
1318}
1319
1320/// Mark a module that contains dynamic parameters.
1321///
1322/// See the `pezpallet_parameters` for a full example.
1323///
1324/// # Arguments
1325///
1326/// The macro accepts two positional arguments, of which the second is optional.
1327///
1328/// ## Aggregated Enum Name
1329///
1330/// This sets the name that the aggregated Key-Value enum will be named after. Common names would be
1331/// `RuntimeParameters`, akin to `RuntimeCall`, `RuntimeOrigin` etc. There is no default value for
1332/// this argument.
1333///
1334/// ## Parameter Storage Backend
1335///
1336/// The second argument provides access to the storage of the parameters. It can either be set on
1337/// on this attribute, or on the inner ones. If set on both, the inner one takes precedence.
1338#[proc_macro_attribute]
1339pub fn dynamic_params(attrs: TokenStream, input: TokenStream) -> TokenStream {
1340 dynamic_params::dynamic_params(attrs.into(), input.into())
1341 .unwrap_or_else(|r| r.into_compile_error())
1342 .into()
1343}
1344
1345/// Define a module inside a [`macro@dynamic_params`] module that contains dynamic parameters.
1346///
1347/// See the `pezpallet_parameters` for a full example.
1348///
1349/// # Argument
1350///
1351/// This attribute takes one optional argument. The argument can either be put here or on the
1352/// surrounding `#[dynamic_params]` attribute. If set on both, the inner one takes precedence.
1353#[proc_macro_attribute]
1354pub fn dynamic_pallet_params(attrs: TokenStream, input: TokenStream) -> TokenStream {
1355 dynamic_params::dynamic_pallet_params(attrs.into(), input.into())
1356 .unwrap_or_else(|r| r.into_compile_error())
1357 .into()
1358}
1359
1360/// Used internally by [`dynamic_params`].
1361#[doc(hidden)]
1362#[proc_macro_attribute]
1363pub fn dynamic_aggregated_params_internal(attrs: TokenStream, input: TokenStream) -> TokenStream {
1364 dynamic_params::dynamic_aggregated_params_internal(attrs.into(), input.into())
1365 .unwrap_or_else(|r| r.into_compile_error())
1366 .into()
1367}
1368
1369/// Allows to authorize some general transactions with specific dispatchable functions
1370/// (dispatchable functions a.k.a. calls).
1371///
1372/// This attribute allows to specify a special validation logic for a specific call.
1373/// A general transaction with this specific call can then be validated by the given function,
1374/// and if valid then dispatched with the origin `pezframe_system::Origin::Authorized`.
1375///
1376/// To ensure the origin of the call is the authorization process, the call must check the origin
1377/// with `pezframe_system::ensure_authorized` function.
1378///
1379/// To enable the authorization process on the extrinsic, the runtime must use
1380/// `pezframe_system::AuthorizeCall` transaction extension in the transaction extension pipeline.
1381///
1382/// To enable the creation of authorized call from offchain worker. The runtime should implement
1383/// `pezframe_system::CreateAuthorizedTransaction`. This trait allows to specify which transaction
1384/// extension to use when creating a transaction for an authorized call.
1385///
1386/// # Usage in the pezpallet
1387///
1388/// ## Example/Overview:
1389///
1390/// ```
1391/// # #[allow(unused)]
1392/// #[pezframe_support::pezpallet]
1393/// pub mod pezpallet {
1394/// use pezframe_support::pezpallet_prelude::*;
1395/// use pezframe_system::pezpallet_prelude::*;
1396///
1397/// #[pezpallet::pezpallet]
1398/// pub struct Pezpallet<T>(_);
1399///
1400/// #[pezpallet::config]
1401/// pub trait Config: pezframe_system::Config {}
1402///
1403/// #[pezpallet::call]
1404/// impl<T: Config> Pezpallet<T> {
1405/// #[pezpallet::weight(Weight::zero())]
1406/// #[pezpallet::authorize(|_source, foo| if *foo == 42 {
1407/// // The amount to refund, here we refund nothing
1408/// let refund = Weight::zero();
1409/// // The validity, here we accept the call and it provides itself.
1410/// // See `ValidTransaction` for more information.
1411/// let validity = ValidTransaction::with_tag_prefix("my-pezpallet")
1412/// .and_provides("some_call")
1413/// .into();
1414/// Ok((validity, refund))
1415/// } else {
1416/// Err(TransactionValidityError::Invalid(InvalidTransaction::Call))
1417/// })]
1418/// #[pezpallet::weight_of_authorize(Weight::zero())]
1419/// #[pezpallet::call_index(0)]
1420/// pub fn some_call(origin: OriginFor<T>, arg: u32) -> DispatchResult {
1421/// ensure_authorized(origin)?;
1422///
1423/// Ok(())
1424/// }
1425///
1426/// #[pezpallet::weight(Weight::zero())]
1427/// // We can also give the callback as a function
1428/// #[pezpallet::authorize(Self::authorize_some_other_call)]
1429/// #[pezpallet::weight_of_authorize(Weight::zero())]
1430/// #[pezpallet::call_index(1)]
1431/// pub fn some_other_call(origin: OriginFor<T>, arg: u32) -> DispatchResult {
1432/// ensure_authorized(origin)?;
1433///
1434/// Ok(())
1435/// }
1436/// }
1437///
1438/// impl<T: Config> Pezpallet<T> {
1439/// fn authorize_some_other_call(
1440/// source: TransactionSource,
1441/// foo: &u32
1442/// ) -> TransactionValidityWithRefund {
1443/// if *foo == 42 {
1444/// let refund = Weight::zero();
1445/// let validity = ValidTransaction::default();
1446/// Ok((validity, refund))
1447/// } else {
1448/// Err(TransactionValidityError::Invalid(InvalidTransaction::Call))
1449/// }
1450/// }
1451/// }
1452///
1453/// #[pezframe_benchmarking::v2::benchmarks]
1454/// mod benchmarks {
1455/// use super::*;
1456/// use pezframe_benchmarking::v2::BenchmarkError;
1457///
1458/// #[benchmark]
1459/// fn authorize_some_call() -> Result<(), BenchmarkError> {
1460/// let call = Call::<T>::some_call { arg: 42 };
1461///
1462/// #[block]
1463/// {
1464/// use pezframe_support::pezpallet_prelude::Authorize;
1465/// call.authorize(TransactionSource::External)
1466/// .ok_or("Call must give some authorization")??;
1467/// }
1468///
1469/// Ok(())
1470/// }
1471/// }
1472/// }
1473/// ```
1474///
1475/// ## Specification:
1476///
1477/// Authorize process comes with 2 attributes macro on top of the authorized call:
1478///
1479/// * `#[pezpallet::authorize($authorized_function)]` - defines the function that authorizes the
1480/// call. First argument is the transaction source `TransactionSource` then followed by the same
1481/// as call arguments but by reference `&`. Return type is `TransactionValidityWithRefund`.
1482/// * `#[pezpallet::weight_of_authorize($weight)]` - defines the value of the weight of the
1483/// authorize function. This attribute is similar to `#[pezpallet::weight]`:
1484/// * it can be ignore in `dev_mode`
1485/// * it can be automatically infered from weight info. For the call `foo` the function
1486/// `authorize_foo` in the weight info will be used. (weight info needs to be provided in the
1487/// call attribute: `#[pezpallet::call(weight = T::WeightInfo)]`).
1488/// * it can be a fixed value like `Weight::from_all(0)` (not recommended in production).
1489///
1490/// The weight must be small enough so that nodes don't get DDOS by validating transactions.
1491///
1492/// Then in the call it must be ensured that the origin is the authorization process. This can
1493/// be done using `pezframe_system::ensure_authorized` function.
1494///
1495/// # The macro expansion
1496///
1497/// From the given "authorize" function and weight, the macro will implement the trait
1498/// `Authorize` on the call.
1499///
1500/// # How to benchmark
1501///
1502/// The authorize function is used as the implementation of the trait
1503/// `Authorize` for the call.
1504/// To benchmark a call variant, use the function
1505/// `Authorize::authorize` on a call value.
1506/// See the example in the first section.
1507#[proc_macro_attribute]
1508pub fn authorize(_: TokenStream, _: TokenStream) -> TokenStream {
1509 pezpallet_macro_stub()
1510}
1511
1512/// Allows to define the weight of the authorize function.
1513///
1514/// See [`authorize`](macro@authorize) for more information on how authorization works.
1515///
1516/// Defines the value of the weight of the authorize function. This attribute is similar to
1517/// `#[pezpallet::weight]`:
1518/// * it can be ignore in `dev_mode`
1519/// * it can be automatically infered from weight info. For the call `foo` the function
1520/// `authorize_foo` in the weight info will be used.
1521/// * it can be a fixed value like `Weight::from_all(0)` (not recommended in production).
1522#[proc_macro_attribute]
1523pub fn weight_of_authorize(_: TokenStream, _: TokenStream) -> TokenStream {
1524 pezpallet_macro_stub()
1525}