referrerpolicy=no-referrer-when-downgrade

frame_support_procedural/construct_runtime/expand/
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::construct_runtime::Pallet;
19use inflector::Inflector;
20use proc_macro2::TokenStream;
21use quote::{format_ident, quote, ToTokens};
22use syn::Ident;
23
24pub fn expand_outer_config(
25	runtime: &Ident,
26	pallet_decls: &[Pallet],
27	scrate: &TokenStream,
28) -> TokenStream {
29	let mut types = TokenStream::new();
30	let mut fields = TokenStream::new();
31	let mut genesis_build_calls = TokenStream::new();
32	let mut query_genesis_config_part_macros = Vec::new();
33
34	for decl in pallet_decls {
35		if let Some(pallet_entry) = decl.find_part("Config") {
36			let path = &decl.path;
37			let pallet_name = &decl.name;
38			let path_str = path.into_token_stream().to_string();
39			let config = format_ident!("{}Config", pallet_name);
40			let field_name =
41				&Ident::new(&pallet_name.to_string().to_snake_case(), decl.name.span());
42			let part_is_generic = !pallet_entry.generics.params.is_empty();
43			let attr = &decl.get_attributes();
44
45			types.extend(expand_config_types(attr, runtime, decl, &config, part_is_generic));
46			fields.extend(quote!(#attr pub #field_name: #config,));
47			genesis_build_calls
48				.extend(expand_config_build_storage_call(scrate, &config, attr, field_name));
49			query_genesis_config_part_macros.push(quote! {
50				#path::__substrate_genesis_config_check::is_genesis_config_defined!(#pallet_name);
51				#[cfg(feature = "std")]
52				#path::__substrate_genesis_config_check::is_std_enabled_for_genesis!(#pallet_name, #path_str);
53			});
54		}
55	}
56
57	quote! {
58		#( #query_genesis_config_part_macros )*
59
60		#types
61
62		use #scrate::__private::serde as __genesis_config_serde_import__;
63		#[derive(#scrate::__private::serde::Serialize, #scrate::__private::serde::Deserialize, Default)]
64		#[serde(rename_all = "camelCase")]
65		#[serde(deny_unknown_fields)]
66		#[serde(crate = "__genesis_config_serde_import__")]
67		pub struct RuntimeGenesisConfig {
68			#fields
69		}
70
71		#[cfg(any(feature = "std", test))]
72		impl #scrate::sp_runtime::BuildStorage for RuntimeGenesisConfig {
73			fn assimilate_storage(
74				&self,
75				storage: &mut #scrate::sp_runtime::Storage,
76			) -> std::result::Result<(), String> {
77				#scrate::__private::BasicExternalities::execute_with_storage(storage, || {
78					<Self as #scrate::traits::BuildGenesisConfig>::build(&self);
79					Ok(())
80				})
81			}
82		}
83
84		impl #scrate::traits::BuildGenesisConfig for RuntimeGenesisConfig {
85			fn build(&self) {
86				#genesis_build_calls
87				<AllPalletsWithSystem as #scrate::traits::OnGenesis>::on_genesis();
88			}
89		}
90
91		/// Test the `Default` derive impl of the `RuntimeGenesisConfig`.
92		#[cfg(test)]
93		#[test]
94		fn test_genesis_config_builds() {
95			#scrate::__private::sp_io::TestExternalities::default().execute_with(|| {
96				<RuntimeGenesisConfig as #scrate::traits::BuildGenesisConfig>::build(
97					&RuntimeGenesisConfig::default()
98				);
99			});
100		}
101	}
102}
103
104fn expand_config_types(
105	attr: &TokenStream,
106	runtime: &Ident,
107	decl: &Pallet,
108	config: &Ident,
109	part_is_generic: bool,
110) -> TokenStream {
111	let path = &decl.path;
112
113	match (decl.instance.as_ref(), part_is_generic) {
114		(Some(inst), true) => quote! {
115			#attr
116			pub type #config = #path::GenesisConfig<#runtime, #path::#inst>;
117		},
118		(None, true) => quote! {
119			#attr
120			pub type #config = #path::GenesisConfig<#runtime>;
121		},
122		(_, false) => quote! {
123			#attr
124			pub type #config = #path::GenesisConfig;
125		},
126	}
127}
128
129fn expand_config_build_storage_call(
130	scrate: &TokenStream,
131	pallet_genesis_config: &Ident,
132	attr: &TokenStream,
133	field_name: &Ident,
134) -> TokenStream {
135	quote! {
136		#attr
137		<#pallet_genesis_config as #scrate::traits::BuildGenesisConfig>::build(&self.#field_name);
138	}
139}