Add 'Static' type and improve type substitution codegen to accept it (#886)

* Add Static type which defers to Encode/Decode and impls EncodeAsType/DecodeAsType

* rename to static_type and impl Deref/Mut

* Improve type substitution in codegen so that concrete types can be swapped in

* A couple of comment tweaks and no need for a macro export

* Extend type substitution logic to work recursively on destination type

* cargo fmt

* Fix a couple of comments

* update ui test outpuot

* Add docs and missing_docs lint

* Add test for replacing multiple of Ident

* Update codegen/src/error.rs

Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>

* update copyright year and fix ui test

* simplify another error

---------

Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>
This commit is contained in:
James Wilson
2023-03-31 16:56:19 +01:00
committed by GitHub
parent 42bcddeecb
commit a2b8dde5e6
132 changed files with 5810 additions and 5442 deletions
+32 -5
View File
@@ -1,4 +1,4 @@
// Copyright 2019-2022 Parity Technologies (UK) Ltd.
// Copyright 2019-2023 Parity Technologies (UK) Ltd.
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
// see LICENSE for license details.
@@ -6,7 +6,7 @@ use clap::Parser as ClapParser;
use color_eyre::eyre;
use jsonrpsee::client_transport::ws::Uri;
use std::{fs, io::Read, path::PathBuf};
use subxt_codegen::{DerivesRegistry, TypeSubstitutes};
use subxt_codegen::{DerivesRegistry, TypeSubstitutes, TypeSubstitutionError};
/// Generate runtime API client code from metadata.
///
@@ -29,6 +29,11 @@ pub struct Opts {
/// Example `--derive-for-type my_module::my_type=serde::Serialize`.
#[clap(long = "derive-for-type", value_parser = derive_for_type_parser)]
derives_for_type: Vec<(String, String)>,
/// Substitute a type for another.
///
/// Example `--substitute-type sp_runtime::MultiAddress<A,B>=subxt::utils::Static<::sp_runtime::MultiAddress<A,B>>`
#[clap(long = "substitute-type", value_parser = substitute_type_parser)]
substitute_types: Vec<(String, String)>,
/// The `subxt` crate access path in the generated code.
/// Defaults to `::subxt`.
#[clap(long = "crate")]
@@ -51,6 +56,14 @@ fn derive_for_type_parser(src: &str) -> Result<(String, String), String> {
Ok((ty.to_string(), derive.to_string()))
}
fn substitute_type_parser(src: &str) -> Result<(String, String), String> {
let (from, to) = src
.split_once('=')
.ok_or_else(|| String::from("Invalid pattern for `substitute-type`. It should be something like `input::Type<A>=replacement::Type<A>`"))?;
Ok((from.to_string(), to.to_string()))
}
pub async fn run(opts: Opts) -> color_eyre::Result<()> {
let bytes = if let Some(file) = opts.file.as_ref() {
if opts.url.is_some() {
@@ -74,6 +87,7 @@ pub async fn run(opts: Opts) -> color_eyre::Result<()> {
&bytes,
opts.derives,
opts.derives_for_type,
opts.substitute_types,
opts.crate_path,
opts.no_docs,
opts.runtime_types_only,
@@ -85,6 +99,7 @@ fn codegen(
metadata_bytes: &[u8],
raw_derives: Vec<String>,
derives_for_type: Vec<(String, String)>,
substitute_types: Vec<(String, String)>,
crate_path: Option<String>,
no_docs: bool,
runtime_types_only: bool,
@@ -102,13 +117,25 @@ fn codegen(
let mut derives = DerivesRegistry::new(&crate_path);
derives.extend_for_all(p.into_iter());
for (ty, derive) in derives_for_type.into_iter() {
for (ty, derive) in derives_for_type {
let ty = syn::parse_str(&ty)?;
let derive = syn::parse_str(&derive)?;
derives.extend_for_type(ty, std::iter::once(derive), &crate_path)
derives.extend_for_type(ty, std::iter::once(derive), &crate_path);
}
let type_substitutes = TypeSubstitutes::new(&crate_path);
let mut type_substitutes = TypeSubstitutes::new(&crate_path);
for (from_str, to_str) in substitute_types {
let from: syn::Path = syn::parse_str(&from_str)?;
let to: syn::Path = syn::parse_str(&to_str)?;
let to = to.try_into().map_err(|e: TypeSubstitutionError| {
eyre::eyre!("Cannot parse substitute '{from_str}={to_str}': {e}")
})?;
type_substitutes
.insert(from, to)
.map_err(|e: TypeSubstitutionError| {
eyre::eyre!("Cannot parse substitute '{from_str}={to_str}': {e}")
})?;
}
let should_gen_docs = !no_docs;
let runtime_api = subxt_codegen::generate_runtime_api_from_bytes(