use std::marker::PhantomData; use parity_scale_codec::Decode; use proc_macro2::TokenStream; use scale_info::PortableRegistry; use scale_typegen::{typegen::ir::ToTokensWithSettings, TypeGenerator, TypeGeneratorSettings}; use syn::parse_quote; #[allow(unused)] pub struct DecodedBits { bits: scale_bits::Bits, _marker: PhantomData<(Store, Order)>, } /// This example shows how to use metadata from a polkadot node to generate rust types. pub fn main() { let type_registry = read_registry_from_scale_metadata(); let settings = TypeGeneratorSettings::default() .type_mod_name("my_types") .decoded_bits_type_path(parse_quote!(DecodedBits)) .compact_as_type_path(parse_quote!(parity_scale_codec::CompactAs)) .compact_type_path(parse_quote!(parity_scale_codec::Compact)) .add_derives_for_all([parse_quote!(Debug), parse_quote!(Clone)]); let type_generator = TypeGenerator::new(&type_registry, &settings); let code = type_generator .generate_types_mod() .unwrap() .to_token_stream(&settings); write_pretty_tokens(code, "./artifacts/generated_polkadot.rs"); } fn read_registry_from_scale_metadata() -> PortableRegistry { let bytes = std::fs::read("./artifacts/polkadot_metadata.scale") .expect("File polkadot_metadata not found!"); let metadata = frame_metadata::RuntimeMetadataPrefixed::decode(&mut &bytes[..]) .expect("Metadata decoding failed"); match metadata.1 { frame_metadata::RuntimeMetadata::V14(m) => m.types, frame_metadata::RuntimeMetadata::V15(m) => m.types, _ => panic!("Metadata too old, needs to be V14 or V15"), } } fn write_pretty_tokens(tokens: TokenStream, path: &str) { let syn_tree = syn::parse_file(&tokens.to_string()).unwrap(); let pretty = prettyplease::unparse(&syn_tree); std::fs::write(path, pretty).unwrap(); }