Skip to content

Commit

Permalink
add constants api to codegen
Browse files Browse the repository at this point in the history
Signed-off-by: Gregory Hill <[email protected]>
  • Loading branch information
gregdhill committed Jan 20, 2022
1 parent 6437959 commit 7d92051
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 0 deletions.
72 changes: 72 additions & 0 deletions codegen/src/api/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright 2019-2022 Parity Technologies (UK) Ltd.
// This file is part of subxt.
//
// subxt is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// subxt is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with subxt. If not, see <http://www.gnu.org/licenses/>.

use crate::types::TypeGenerator;
use frame_metadata::{
PalletConstantMetadata,
PalletMetadata,
StorageEntryMetadata,
StorageEntryModifier,
StorageEntryType,
StorageHasher,
};
use heck::SnakeCase as _;
use proc_macro2::TokenStream as TokenStream2;
use proc_macro_error::abort_call_site;
use quote::{
format_ident,
quote,
};
use scale_info::{
form::PortableForm,
TypeDef,
};

pub fn generate_constants(
type_gen: &TypeGenerator,
pallet: &PalletMetadata<PortableForm>,
constants: &Vec<PalletConstantMetadata<PortableForm>>,
types_mod_ident: &syn::Ident,
) -> TokenStream2 {
let constant_fns = constants.iter().map(|constant| {
let const_fn_ident = format_ident!("{}", constant.name.to_snake_case());
let const_ty = type_gen.resolve_type_path(constant.ty.id(), &[]);

let ref_slice = constant.value.as_slice();

quote! {
pub fn #const_fn_ident(&self) -> #const_ty {
::subxt::codec::Decode::decode(&mut &vec![#(#ref_slice,)*][..]).unwrap()
}
}
});

quote! {
pub mod constants {
use super::#types_mod_ident;

pub struct ConstantsApi { }

impl ConstantsApi {
pub fn new() -> Self {
Self { }
}

#(#constant_fns)*
}
}
}
}
34 changes: 34 additions & 0 deletions codegen/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// along with subxt. If not, see <http://www.gnu.org/licenses/>.

mod calls;
mod constants;
mod errors;
mod events;
mod storage;
Expand Down Expand Up @@ -173,12 +174,24 @@ impl RuntimeGenerator {
quote!()
};

let constants_mod = if !pallet.constants.is_empty() {
constants::generate_constants(
&type_gen,
pallet,
&pallet.constants,
types_mod_ident,
)
} else {
quote!()
};

quote! {
pub mod #mod_name {
use super::#types_mod_ident;
#calls
#event
#storage_mod
#constants_mod
}
}
});
Expand All @@ -204,6 +217,12 @@ impl RuntimeGenerator {
};

let mod_ident = item_mod_ir.ident;
let pallets_with_constants =
pallets_with_mod_names
.iter()
.filter_map(|(pallet, pallet_mod_name)| {
(!pallet.constants.is_empty()).then(|| pallet_mod_name)
});
let pallets_with_storage =
pallets_with_mod_names
.iter()
Expand Down Expand Up @@ -270,6 +289,10 @@ impl RuntimeGenerator {
T: ::subxt::Config,
X: ::subxt::SignedExtra<T>,
{
pub fn constants(&'a self) -> ConstantsApi {
ConstantsApi { }
}

pub fn storage(&'a self) -> StorageApi<'a, T> {
StorageApi { client: &self.client }
}
Expand All @@ -279,6 +302,17 @@ impl RuntimeGenerator {
}
}

pub struct ConstantsApi { }

impl ConstantsApi
{
#(
pub fn #pallets_with_constants(&self) -> #pallets_with_constants::constants::ConstantsApi {
#pallets_with_constants::constants::ConstantsApi::new()
}
)*
}

pub struct StorageApi<'a, T: ::subxt::Config> {
client: &'a ::subxt::Client<T>,
}
Expand Down
4 changes: 4 additions & 0 deletions tests/integration/frame/balances.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,4 +261,8 @@ async fn constant_existential_deposit() {
let constant_metadata = balances_metadata.constant("ExistentialDeposit").unwrap();
let existential_deposit = u128::decode(&mut &constant_metadata.value[..]).unwrap();
assert_eq!(existential_deposit, 100_000_000_000_000);
assert_eq!(
existential_deposit,
cxt.api.constants().balances().existential_deposit()
);
}

0 comments on commit 7d92051

Please sign in to comment.