frame_support_procedural/pallet/expand/
genesis_config.rs1use crate::{pallet::Def, COUNTER};
19use frame_support_procedural_tools::get_doc_literals;
20use quote::ToTokens;
21use syn::{spanned::Spanned, Ident};
22
23pub 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}