referrerpolicy=no-referrer-when-downgrade

frame_support_procedural/pallet/expand/
genesis_config.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
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
18use crate::{pallet::Def, COUNTER};
19use frame_support_procedural_tools::get_doc_literals;
20use quote::ToTokens;
21use syn::{spanned::Spanned, Ident};
22
23///
24/// * add various derive trait on GenesisConfig struct.
25pub fn expand_genesis_config(def: &mut Def) -> proc_macro2::TokenStream {
26	let count = COUNTER.with(|counter| counter.borrow_mut().inc());
27
28	let (genesis_config, def_macro_ident, std_macro_ident) =
29		if let Some(genesis_config) = &def.genesis_config {
30			let def_macro_ident = Ident::new(
31				&format!("__is_genesis_config_defined_{}", count),
32				genesis_config.genesis_config.span(),
33			);
34
35			let std_macro_ident = Ident::new(
36				&format!("__is_std_macro_defined_for_genesis_{}", count),
37				genesis_config.genesis_config.span(),
38			);
39
40			(genesis_config, def_macro_ident, std_macro_ident)
41		} else {
42			let def_macro_ident =
43				Ident::new(&format!("__is_genesis_config_defined_{}", count), def.item.span());
44
45			let std_macro_ident =
46				Ident::new(&format!("__is_std_enabled_for_genesis_{}", count), def.item.span());
47
48			return quote::quote! {
49				#[doc(hidden)]
50				pub mod __substrate_genesis_config_check {
51					#[macro_export]
52					#[doc(hidden)]
53					macro_rules! #def_macro_ident {
54						($pallet_name:ident) => {
55							compile_error!(concat!(
56								"`",
57								stringify!($pallet_name),
58								"` does not have #[pallet::genesis_config] defined, perhaps you should \
59								remove `Config` from construct_runtime?",
60							));
61						}
62					}
63
64					#[macro_export]
65					#[doc(hidden)]
66					macro_rules! #std_macro_ident {
67						($pallet_name:ident, $pallet_path:expr) => {};
68					}
69
70					#[doc(hidden)]
71					pub use #def_macro_ident as is_genesis_config_defined;
72					#[doc(hidden)]
73					pub use #std_macro_ident as is_std_enabled_for_genesis;
74				}
75			}
76		};
77
78	let frame_support = &def.frame_support;
79
80	let genesis_config_item =
81		&mut def.item.content.as_mut().expect("Checked by def parser").1[genesis_config.index];
82
83	let serde_crate = format!("{}::__private::serde", frame_support.to_token_stream());
84
85	match genesis_config_item {
86		syn::Item::Enum(syn::ItemEnum { attrs, .. }) |
87		syn::Item::Struct(syn::ItemStruct { attrs, .. }) |
88		syn::Item::Type(syn::ItemType { attrs, .. }) => {
89			if get_doc_literals(attrs).is_empty() {
90				attrs.push(syn::parse_quote!(
91					#[doc = r"
92					Can be used to configure the
93					[genesis state](https://docs.substrate.io/build/genesis-configuration/)
94					of this pallet.
95					"]
96				));
97			}
98			attrs.push(syn::parse_quote!(
99				#[derive(#frame_support::Serialize, #frame_support::Deserialize)]
100			));
101			attrs.push(syn::parse_quote!( #[serde(rename_all = "camelCase")] ));
102			attrs.push(syn::parse_quote!( #[serde(deny_unknown_fields)] ));
103			attrs.push(syn::parse_quote!( #[serde(bound(serialize = ""))] ));
104			attrs.push(syn::parse_quote!( #[serde(bound(deserialize = ""))] ));
105			attrs.push(syn::parse_quote!( #[serde(crate = #serde_crate)] ));
106		},
107		_ => unreachable!("Checked by genesis_config parser"),
108	}
109
110	quote::quote! {
111		#[doc(hidden)]
112		pub mod __substrate_genesis_config_check {
113			#[macro_export]
114			#[doc(hidden)]
115			macro_rules! #def_macro_ident {
116				($pallet_name:ident) => {};
117			}
118
119			#[cfg(not(feature = "std"))]
120			#[macro_export]
121			#[doc(hidden)]
122			macro_rules! #std_macro_ident {
123				($pallet_name:ident, $pallet_path:expr) => {
124					compile_error!(concat!(
125						"`",
126						stringify!($pallet_name),
127						"` does not have the std feature enabled, this will cause the `",
128						$pallet_path,
129						"::GenesisConfig` type to not implement serde traits."
130					));
131				};
132			}
133
134			#[cfg(feature = "std")]
135			#[macro_export]
136			#[doc(hidden)]
137			macro_rules! #std_macro_ident {
138				($pallet_name:ident, $pallet_path:expr) => {};
139			}
140
141			#[doc(hidden)]
142			pub use #def_macro_ident as is_genesis_config_defined;
143			#[doc(hidden)]
144			pub use #std_macro_ident as is_std_enabled_for_genesis;
145		}
146	}
147}