Read constants from metadata at runtime (#494)

* Read constants from metadata at runtime

* Update polkadot codegen

* Update polkadot.rs

* Update polkadot.rs
This commit is contained in:
Andrew Jones
2022-03-31 11:36:43 +01:00
committed by GitHub
parent 9318f62850
commit cc0b1ec84a
3 changed files with 1044 additions and 1174 deletions
+19 -6
View File
@@ -15,7 +15,10 @@
// along with subxt. If not, see <http://www.gnu.org/licenses/>. // along with subxt. If not, see <http://www.gnu.org/licenses/>.
use crate::types::TypeGenerator; use crate::types::TypeGenerator;
use frame_metadata::PalletConstantMetadata; use frame_metadata::{
PalletConstantMetadata,
PalletMetadata,
};
use heck::ToSnakeCase as _; use heck::ToSnakeCase as _;
use proc_macro2::TokenStream as TokenStream2; use proc_macro2::TokenStream as TokenStream2;
use quote::{ use quote::{
@@ -26,18 +29,22 @@ use scale_info::form::PortableForm;
pub fn generate_constants( pub fn generate_constants(
type_gen: &TypeGenerator, type_gen: &TypeGenerator,
pallet: &PalletMetadata<PortableForm>,
constants: &[PalletConstantMetadata<PortableForm>], constants: &[PalletConstantMetadata<PortableForm>],
types_mod_ident: &syn::Ident, types_mod_ident: &syn::Ident,
) -> TokenStream2 { ) -> TokenStream2 {
let constant_fns = constants.iter().map(|constant| { let constant_fns = constants.iter().map(|constant| {
let fn_name = format_ident!("{}", constant.name.to_snake_case()); let fn_name = format_ident!("{}", constant.name.to_snake_case());
let pallet_name = &pallet.name;
let constant_name = &constant.name;
let return_ty = type_gen.resolve_type_path(constant.ty.id(), &[]); let return_ty = type_gen.resolve_type_path(constant.ty.id(), &[]);
let ref_slice = constant.value.as_slice();
quote! { quote! {
pub fn #fn_name(&self) -> ::core::result::Result<#return_ty, ::subxt::BasicError> { pub fn #fn_name(&self) -> ::core::result::Result<#return_ty, ::subxt::BasicError> {
Ok(::subxt::codec::Decode::decode(&mut &[#(#ref_slice,)*][..])?) let pallet = self.client.metadata().pallet(#pallet_name)?;
let constant = pallet.constant(#constant_name)?;
let value = ::subxt::codec::Decode::decode(&mut &constant.value[..])?;
Ok(value)
} }
} }
}); });
@@ -46,9 +53,15 @@ pub fn generate_constants(
pub mod constants { pub mod constants {
use super::#types_mod_ident; use super::#types_mod_ident;
pub struct ConstantsApi; pub struct ConstantsApi<'a, T: ::subxt::Config> {
client: &'a ::subxt::Client<T>,
}
impl<'a, T: ::subxt::Config> ConstantsApi<'a, T> {
pub fn new(client: &'a ::subxt::Client<T>) -> Self {
Self { client }
}
impl ConstantsApi {
#(#constant_fns)* #(#constant_fns)*
} }
} }
+9 -6
View File
@@ -203,6 +203,7 @@ impl RuntimeGenerator {
let constants_mod = if !pallet.constants.is_empty() { let constants_mod = if !pallet.constants.is_empty() {
constants::generate_constants( constants::generate_constants(
&type_gen, &type_gen,
pallet,
&pallet.constants, &pallet.constants,
types_mod_ident, types_mod_ident,
) )
@@ -300,8 +301,8 @@ impl RuntimeGenerator {
T: ::subxt::Config, T: ::subxt::Config,
X: ::subxt::extrinsic::ExtrinsicParams<T>, X: ::subxt::extrinsic::ExtrinsicParams<T>,
{ {
pub fn constants(&'a self) -> ConstantsApi { pub fn constants(&'a self) -> ConstantsApi<'a, T> {
ConstantsApi ConstantsApi { client: &self.client }
} }
pub fn storage(&'a self) -> StorageApi<'a, T> { pub fn storage(&'a self) -> StorageApi<'a, T> {
@@ -335,12 +336,14 @@ impl RuntimeGenerator {
} }
} }
pub struct ConstantsApi; pub struct ConstantsApi<'a, T: ::subxt::Config> {
client: &'a ::subxt::Client<T>,
}
impl ConstantsApi { impl<'a, T: ::subxt::Config> ConstantsApi<'a, T> {
#( #(
pub fn #pallets_with_constants(&self) -> #pallets_with_constants::constants::ConstantsApi { pub fn #pallets_with_constants(&self) -> #pallets_with_constants::constants::ConstantsApi<'a, T> {
#pallets_with_constants::constants::ConstantsApi #pallets_with_constants::constants::ConstantsApi::new(self.client)
} }
)* )*
} }
File diff suppressed because it is too large Load Diff