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