frame_support_procedural/construct_runtime/expand/
config.rs
1use 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 #[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}