Allow for remapping type parameters in type substitutions (#735)

* feat!: Allow for remapping type parameters in type substitutions

* chore: cargo fmt

* chore: cargo clippy

* chore: Remove some old code

* a little tidy

* address comment nit

Co-authored-by: James Wilson <james@jsdw.me>
This commit is contained in:
Igor Matuszewski
2023-01-19 10:49:57 +00:00
committed by GitHub
parent b7a29a5efe
commit 977f2a3333
14 changed files with 541 additions and 331 deletions
+43 -53
View File
@@ -4,6 +4,7 @@
mod composite_def;
mod derives;
mod substitutes;
#[cfg(test)]
mod tests;
mod type_def;
@@ -27,10 +28,7 @@ use scale_info::{
Type,
TypeDef,
};
use std::collections::{
BTreeMap,
HashMap,
};
use std::collections::BTreeMap;
pub use self::{
composite_def::{
@@ -42,6 +40,7 @@ pub use self::{
Derives,
DerivesRegistry,
},
substitutes::TypeSubstitutes,
type_def::TypeDefGen,
type_def_params::TypeDefParameters,
type_path::{
@@ -61,7 +60,7 @@ pub struct TypeGenerator<'a> {
/// Registry of type definitions to be transformed into Rust type definitions.
type_registry: &'a PortableRegistry,
/// User defined overrides for generated types.
type_substitutes: HashMap<String, syn::TypePath>,
type_substitutes: TypeSubstitutes,
/// Set of derives with which to annotate generated types.
derives: DerivesRegistry,
/// The `subxt` crate access path in the generated code.
@@ -73,7 +72,7 @@ impl<'a> TypeGenerator<'a> {
pub fn new(
type_registry: &'a PortableRegistry,
root_mod: &'static str,
type_substitutes: HashMap<String, syn::TypePath>,
type_substitutes: TypeSubstitutes,
derives: DerivesRegistry,
crate_path: CratePath,
) -> Self {
@@ -89,55 +88,43 @@ impl<'a> TypeGenerator<'a> {
/// Generate a module containing all types defined in the supplied type registry.
pub fn generate_types_mod(&self) -> Module {
let mut root_mod =
Module::new(self.types_mod_ident.clone(), self.types_mod_ident.clone());
let root_mod_ident = &self.types_mod_ident;
let mut root_mod = Module::new(root_mod_ident.clone(), root_mod_ident.clone());
for ty in self.type_registry.types().iter() {
if ty.ty().path().namespace().is_empty() {
// prelude types e.g. Option/Result have no namespace, so we don't generate them
for ty in self.type_registry.types() {
let path = ty.ty().path();
// Don't generate a type if it was substituted - the target type might
// not be in the type registry + our resolution already performs the substitution.
if self.type_substitutes.for_path(path).is_some() {
continue
}
self.insert_type(
ty.ty().clone(),
ty.ty().path().namespace().to_vec(),
&self.types_mod_ident,
&mut root_mod,
)
let namespace = path.namespace();
// prelude types e.g. Option/Result have no namespace, so we don't generate them
if namespace.is_empty() {
continue
}
// Lazily create submodules for the encountered namespace path, if they don't exist
let innermost_module = namespace
.iter()
.map(|segment| Ident::new(segment, Span::call_site()))
.fold(&mut root_mod, |module, ident| {
module
.children
.entry(ident.clone())
.or_insert_with(|| Module::new(ident, root_mod_ident.clone()))
});
innermost_module.types.insert(
path.clone(),
TypeDefGen::from_type(ty.ty(), self, &self.crate_path),
);
}
root_mod
}
fn insert_type(
&'a self,
ty: Type<PortableForm>,
path: Vec<String>,
root_mod_ident: &Ident,
module: &mut Module,
) {
let joined_path = path.join("::");
if self.type_substitutes.contains_key(&joined_path) {
return
}
let segment = path.first().expect("path has at least one segment");
let mod_ident = Ident::new(segment, Span::call_site());
let child_mod = module
.children
.entry(mod_ident.clone())
.or_insert_with(|| Module::new(mod_ident, root_mod_ident.clone()));
if path.len() == 1 {
child_mod.types.insert(
ty.path().clone(),
TypeDefGen::from_type(ty, self, &self.crate_path),
);
} else {
self.insert_type(ty, path[1..].to_vec(), root_mod_ident, child_mod)
}
}
/// # Panics
///
/// If no type with the given id found in the type registry.
@@ -208,7 +195,7 @@ impl<'a> TypeGenerator<'a> {
)
}
let params = ty
let params: Vec<_> = ty
.type_params()
.iter()
.filter_map(|f| {
@@ -220,13 +207,16 @@ impl<'a> TypeGenerator<'a> {
let ty = match ty.type_def() {
TypeDef::Composite(_) | TypeDef::Variant(_) => {
let joined_path = ty.path().segments().join("::");
if let Some(substitute_type_path) =
self.type_substitutes.get(&joined_path)
if let Some((path, params)) = self
.type_substitutes
.for_path_with_params(ty.path(), &params)
{
TypePathType::Path {
path: substitute_type_path.clone(),
params,
path: syn::TypePath {
qself: None,
path: path.clone(),
},
params: params.to_vec(),
}
} else {
TypePathType::from_type_def_path(
+254
View File
@@ -0,0 +1,254 @@
// 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.
use crate::CratePath;
use proc_macro_error::abort;
use std::{
borrow::Cow,
collections::HashMap,
};
use syn::{
parse_quote,
spanned::Spanned as _,
};
use super::TypePath;
#[derive(Debug)]
pub struct TypeSubstitutes {
substitutes: HashMap<PathSegments, Substitute>,
}
#[derive(Debug)]
struct Substitute {
path: syn::Path,
param_mapping: TypeParamMapping,
}
#[derive(Debug)]
enum TypeParamMapping {
None,
Specified(Vec<u8>),
}
#[macro_export]
macro_rules! path_segments {
($($ident: ident)::*) => {
PathSegments(
[$(stringify!($ident)),*].into_iter().map(String::from).collect::<Vec<_>>()
)
}
}
impl TypeSubstitutes {
pub fn new(crate_path: &CratePath) -> Self {
// Some hardcoded default type substitutes, can be overridden by user
let defaults = [
(
path_segments!(bitvec::order::Lsb0),
parse_quote!(#crate_path::utils::bits::Lsb0),
),
(
path_segments!(bitvec::order::Msb0),
parse_quote!(#crate_path::utils::bits::Msb0),
),
(
path_segments!(sp_core::crypto::AccountId32),
parse_quote!(#crate_path::utils::AccountId32),
),
(
path_segments!(sp_runtime::multiaddress::MultiAddress),
parse_quote!(#crate_path::utils::MultiAddress),
),
(
path_segments!(primitive_types::H160),
parse_quote!(#crate_path::utils::H160),
),
(
path_segments!(primitive_types::H256),
parse_quote!(#crate_path::utils::H256),
),
(
path_segments!(primitive_types::H512),
parse_quote!(#crate_path::utils::H512),
),
(
path_segments!(frame_support::traits::misc::WrapperKeepOpaque),
parse_quote!(#crate_path::utils::WrapperKeepOpaque),
),
// BTreeMap and BTreeSet impose an `Ord` constraint on their key types. This
// can cause an issue with generated code that doesn't impl `Ord` by default.
// Decoding them to Vec by default (KeyedVec is just an alias for Vec with
// suitable type params) avoids these issues.
(
path_segments!(BTreeMap),
parse_quote!(#crate_path::utils::KeyedVec),
),
(path_segments!(BTreeSet), parse_quote!(::std::vec::Vec)),
];
let default_substitutes = defaults
.into_iter()
.map(|(k, v)| {
(
k,
Substitute {
path: v,
param_mapping: TypeParamMapping::None,
},
)
})
.collect();
Self {
substitutes: default_substitutes,
}
}
pub fn extend(&mut self, elems: impl IntoIterator<Item = (syn::Path, AbsolutePath)>) {
self.substitutes
.extend(elems.into_iter().map(|(path, AbsolutePath(mut with))| {
let Some(syn::PathSegment { arguments: src_path_args, ..}) = path.segments.last() else { abort!(path.span(), "Empty path") };
let Some(syn::PathSegment { arguments: target_path_args, ..}) = with.segments.last_mut() else { abort!(with.span(), "Empty path") };
let source_args: Vec<_> = type_args(src_path_args).collect();
let param_mapping = if source_args.is_empty() {
// If the type parameters on the source type are not specified, then this means that
// the type is either not generic or the user wants to pass through all the parameters
TypeParamMapping::None
} else {
// Describe the mapping in terms of "which source param idx is used for each target param".
// So, for each target param, find the matching source param index.
let mapping = type_args(target_path_args)
.filter_map(|arg|
source_args
.iter()
.position(|&src| src == arg)
.map(|src_idx|
u8::try_from(src_idx).expect("type arguments to be fewer than 256; qed"),
)
).collect();
TypeParamMapping::Specified(mapping)
};
// NOTE: Params are late bound and held separately, so clear them
// here to not mess pretty printing this path and params together
*target_path_args = syn::PathArguments::None;
(PathSegments::from(&path), Substitute { path: with, param_mapping })
}));
}
/// Given a source type path, return a substituted type path if a substitution is defined.
pub fn for_path(&self, path: impl Into<PathSegments>) -> Option<&syn::Path> {
self.substitutes.get(&path.into()).map(|s| &s.path)
}
/// Given a source type path and the resolved, supplied type parameters,
/// return a new path and optionally overwritten type parameters.
pub fn for_path_with_params<'a: 'b, 'b>(
&'a self,
path: impl Into<PathSegments>,
params: &'b [TypePath],
) -> Option<(&'a syn::Path, Cow<'b, [TypePath]>)> {
// For now, we only support:
// 1. Reordering the generics
// 2. Omitting certain generics
fn reorder_params<'a>(
params: &'a [TypePath],
mapping: &TypeParamMapping,
) -> Cow<'a, [TypePath]> {
match mapping {
TypeParamMapping::Specified(mapping) => {
Cow::Owned(
mapping
.iter()
.filter_map(|&idx| params.get(idx as usize))
.cloned()
.collect(),
)
}
_ => Cow::Borrowed(params),
}
}
let path = path.into();
self.substitutes
.get(&path)
.map(|sub| (&sub.path, reorder_params(params, &sub.param_mapping)))
}
}
/// Identifiers joined by the `::` separator.
///
/// We use this as a common denominator, since we need a consistent keys for both
/// `syn::TypePath` and `scale_info::ty::path::Path` types.
#[derive(Debug, Hash, PartialEq, Eq)]
pub struct PathSegments(Vec<String>);
impl From<&syn::Path> for PathSegments {
fn from(path: &syn::Path) -> Self {
PathSegments(path.segments.iter().map(|x| x.ident.to_string()).collect())
}
}
impl<T: scale_info::form::Form> From<&scale_info::Path<T>> for PathSegments {
fn from(path: &scale_info::Path<T>) -> Self {
PathSegments(
path.segments()
.iter()
.map(|x| x.as_ref().to_owned())
.collect(),
)
}
}
/// Returns an iterator over generic type parameters for `syn::PathArguments`.
/// For example:
/// - `<'a, T>` should only return T
/// - `(A, B) -> String` shouldn't return anything
fn type_args(path_args: &syn::PathArguments) -> impl Iterator<Item = &syn::Path> {
let args_opt = match path_args {
syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments {
ref args,
..
}) => Some(args),
_ => None,
};
args_opt.into_iter().flatten().filter_map(|arg| {
match arg {
syn::GenericArgument::Type(syn::Type::Path(type_path)) => {
Some(&type_path.path)
}
_ => None,
}
})
}
/// Whether a path is absolute - starts with `::` or `crate`.
fn is_absolute(path: &syn::Path) -> bool {
path.leading_colon.is_some()
|| path
.segments
.first()
.map_or(false, |segment| segment.ident == "crate")
}
pub struct AbsolutePath(syn::Path);
impl TryFrom<syn::Path> for AbsolutePath {
type Error = (syn::Path, String);
fn try_from(value: syn::Path) -> Result<Self, Self::Error> {
if is_absolute(&value) {
Ok(AbsolutePath(value))
} else {
Err(
(value, "The substitute path must be a global absolute path; try prefixing with `::` or `crate`".to_owned())
)
}
}
}
+82 -74
View File
@@ -39,12 +39,13 @@ fn generate_struct_with_primitives() {
registry.register_type(&meta_type::<S>());
let portable_types: PortableRegistry = registry.into();
let crate_path = "::subxt_path".into();
let type_gen = TypeGenerator::new(
&portable_types,
"root",
Default::default(),
DerivesRegistry::new(&"::subxt_path".into()),
"::subxt_path".into(),
TypeSubstitutes::new(&crate_path),
DerivesRegistry::new(&crate_path),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
@@ -86,12 +87,13 @@ fn generate_struct_with_a_struct_field() {
registry.register_type(&meta_type::<Parent>());
let portable_types: PortableRegistry = registry.into();
let crate_path = "::subxt_path".into();
let type_gen = TypeGenerator::new(
&portable_types,
"root",
Default::default(),
DerivesRegistry::new(&"::subxt_path".into()),
"::subxt_path".into(),
TypeSubstitutes::new(&crate_path),
DerivesRegistry::new(&crate_path),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
@@ -132,12 +134,13 @@ fn generate_tuple_struct() {
registry.register_type(&meta_type::<Parent>());
let portable_types: PortableRegistry = registry.into();
let crate_path = "::subxt_path".into();
let type_gen = TypeGenerator::new(
&portable_types,
"root",
Default::default(),
DerivesRegistry::new(&"::subxt_path".into()),
"::subxt_path".into(),
TypeSubstitutes::new(&crate_path),
DerivesRegistry::new(&crate_path),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
@@ -215,12 +218,13 @@ fn derive_compact_as_for_uint_wrapper_structs() {
registry.register_type(&meta_type::<TSu128>());
let portable_types: PortableRegistry = registry.into();
let crate_path = "::subxt_path".into();
let type_gen = TypeGenerator::new(
&portable_types,
"root",
Default::default(),
DerivesRegistry::new(&"::subxt_path".into()),
"::subxt_path".into(),
TypeSubstitutes::new(&crate_path),
DerivesRegistry::new(&crate_path),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
@@ -280,12 +284,13 @@ fn generate_enum() {
registry.register_type(&meta_type::<E>());
let portable_types: PortableRegistry = registry.into();
let crate_path = "::subxt_path".into();
let type_gen = TypeGenerator::new(
&portable_types,
"root",
Default::default(),
DerivesRegistry::new(&"::subxt_path".into()),
"::subxt_path".into(),
TypeSubstitutes::new(&crate_path),
DerivesRegistry::new(&crate_path),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
@@ -339,12 +344,13 @@ fn compact_fields() {
registry.register_type(&meta_type::<E>());
let portable_types: PortableRegistry = registry.into();
let crate_path = "::subxt_path".into();
let type_gen = TypeGenerator::new(
&portable_types,
"root",
Default::default(),
DerivesRegistry::new(&"::subxt_path".into()),
"::subxt_path".into(),
TypeSubstitutes::new(&crate_path),
DerivesRegistry::new(&crate_path),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
@@ -396,12 +402,13 @@ fn compact_generic_parameter() {
registry.register_type(&meta_type::<S>());
let portable_types: PortableRegistry = registry.into();
let crate_path = "::subxt_path".into();
let type_gen = TypeGenerator::new(
&portable_types,
"root",
Default::default(),
DerivesRegistry::new(&"::subxt_path".into()),
"::subxt_path".into(),
TypeSubstitutes::new(&crate_path),
DerivesRegistry::new(&crate_path),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
@@ -438,12 +445,13 @@ fn generate_array_field() {
registry.register_type(&meta_type::<S>());
let portable_types: PortableRegistry = registry.into();
let crate_path = "::subxt_path".into();
let type_gen = TypeGenerator::new(
&portable_types,
"root",
Default::default(),
DerivesRegistry::new(&"::subxt_path".into()),
"::subxt_path".into(),
TypeSubstitutes::new(&crate_path),
DerivesRegistry::new(&crate_path),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
@@ -476,12 +484,13 @@ fn option_fields() {
registry.register_type(&meta_type::<S>());
let portable_types: PortableRegistry = registry.into();
let crate_path = "::subxt_path".into();
let type_gen = TypeGenerator::new(
&portable_types,
"root",
Default::default(),
DerivesRegistry::new(&"::subxt_path".into()),
"::subxt_path".into(),
TypeSubstitutes::new(&crate_path),
DerivesRegistry::new(&crate_path),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
@@ -517,12 +526,13 @@ fn box_fields_struct() {
registry.register_type(&meta_type::<S>());
let portable_types: PortableRegistry = registry.into();
let crate_path = "::subxt_path".into();
let type_gen = TypeGenerator::new(
&portable_types,
"root",
Default::default(),
DerivesRegistry::new(&"::subxt_path".into()),
"::subxt_path".into(),
TypeSubstitutes::new(&crate_path),
DerivesRegistry::new(&crate_path),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
@@ -558,12 +568,13 @@ fn box_fields_enum() {
registry.register_type(&meta_type::<E>());
let portable_types: PortableRegistry = registry.into();
let crate_path = "::subxt_path".into();
let type_gen = TypeGenerator::new(
&portable_types,
"root",
Default::default(),
DerivesRegistry::new(&"::subxt_path".into()),
"::subxt_path".into(),
TypeSubstitutes::new(&crate_path),
DerivesRegistry::new(&crate_path),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
@@ -599,12 +610,13 @@ fn range_fields() {
registry.register_type(&meta_type::<S>());
let portable_types: PortableRegistry = registry.into();
let crate_path = "::subxt_path".into();
let type_gen = TypeGenerator::new(
&portable_types,
"root",
Default::default(),
DerivesRegistry::new(&"::subxt_path".into()),
"::subxt_path".into(),
TypeSubstitutes::new(&crate_path),
DerivesRegistry::new(&crate_path),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
@@ -644,12 +656,13 @@ fn generics() {
registry.register_type(&meta_type::<Bar>());
let portable_types: PortableRegistry = registry.into();
let crate_path = "::subxt_path".into();
let type_gen = TypeGenerator::new(
&portable_types,
"root",
Default::default(),
DerivesRegistry::new(&"::subxt_path".into()),
"::subxt_path".into(),
TypeSubstitutes::new(&crate_path),
DerivesRegistry::new(&crate_path),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
@@ -693,12 +706,13 @@ fn generics_nested() {
registry.register_type(&meta_type::<Bar<bool>>());
let portable_types: PortableRegistry = registry.into();
let crate_path = "::subxt_path".into();
let type_gen = TypeGenerator::new(
&portable_types,
"root",
Default::default(),
DerivesRegistry::new(&"::subxt_path".into()),
"::subxt_path".into(),
TypeSubstitutes::new(&crate_path),
DerivesRegistry::new(&crate_path),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
@@ -745,24 +759,13 @@ fn generate_bitvec() {
registry.register_type(&meta_type::<S>());
let portable_types: PortableRegistry = registry.into();
let substitutes = [
(
String::from("bitvec::order::Lsb0"),
parse_quote!(::subxt_path::utils::bits::Lsb0),
),
(
String::from("bitvec::order::Msb0"),
parse_quote!(::subxt_path::utils::bits::Msb0),
),
]
.into();
let crate_path = "::subxt_path".into();
let type_gen = TypeGenerator::new(
&portable_types,
"root",
substitutes,
DerivesRegistry::new(&"::subxt_path".into()),
"::subxt_path".into(),
TypeSubstitutes::new(&crate_path),
DerivesRegistry::new(&crate_path),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
@@ -811,12 +814,13 @@ fn generics_with_alias_adds_phantom_data_marker() {
registry.register_type(&meta_type::<UnnamedFields<bool, bool>>());
let portable_types: PortableRegistry = registry.into();
let crate_path = "::subxt_path".into();
let type_gen = TypeGenerator::new(
&portable_types,
"root",
Default::default(),
DerivesRegistry::new(&"::subxt_path".into()),
"::subxt_path".into(),
TypeSubstitutes::new(&crate_path),
DerivesRegistry::new(&crate_path),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
@@ -872,12 +876,13 @@ fn modules() {
registry.register_type(&meta_type::<m::c::Foo>());
let portable_types: PortableRegistry = registry.into();
let crate_path = "::subxt_path".into();
let type_gen = TypeGenerator::new(
&portable_types,
"root",
Default::default(),
DerivesRegistry::new(&"::subxt_path".into()),
"::subxt_path".into(),
TypeSubstitutes::new(&crate_path),
DerivesRegistry::new(&crate_path),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
@@ -930,12 +935,13 @@ fn dont_force_struct_names_camel_case() {
registry.register_type(&meta_type::<AB>());
let portable_types: PortableRegistry = registry.into();
let crate_path = "::subxt_path".into();
let type_gen = TypeGenerator::new(
&portable_types,
"root",
Default::default(),
DerivesRegistry::new(&"::subxt_path".into()),
"::subxt_path".into(),
TypeSubstitutes::new(&crate_path),
DerivesRegistry::new(&crate_path),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
@@ -968,16 +974,17 @@ fn apply_user_defined_derives_for_all_types() {
registry.register_type(&meta_type::<A>());
let portable_types: PortableRegistry = registry.into();
let crate_path = "::subxt_path".into();
// configure derives
let mut derives = DerivesRegistry::new(&"::subxt_path".into());
let mut derives = DerivesRegistry::new(&crate_path);
derives.extend_for_all(vec![parse_quote!(Clone), parse_quote!(Eq)]);
let type_gen = TypeGenerator::new(
&portable_types,
"root",
Default::default(),
TypeSubstitutes::new(&crate_path),
derives,
"::subxt_path".into(),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
@@ -1017,15 +1024,16 @@ fn apply_user_defined_derives_for_specific_types() {
registry.register_type(&meta_type::<A>());
let portable_types: PortableRegistry = registry.into();
let crate_path = "::subxt_path".into();
// configure derives
let mut derives = DerivesRegistry::new(&"::subxt_path".into());
let mut derives = DerivesRegistry::new(&crate_path);
// for all types
derives.extend_for_all(vec![parse_quote!(Eq)]);
// for specific types
derives.extend_for_type(
parse_quote!(subxt_codegen::types::tests::B),
vec![parse_quote!(Hash)],
&"::subxt_path".into(),
&crate_path,
);
// duplicates (in this case `Eq`) will be combined (i.e. a set union)
derives.extend_for_type(
@@ -1035,15 +1043,15 @@ fn apply_user_defined_derives_for_specific_types() {
parse_quote!(Ord),
parse_quote!(PartialOrd),
],
&"::subxt_path".into(),
&crate_path,
);
let type_gen = TypeGenerator::new(
&portable_types,
"root",
Default::default(),
TypeSubstitutes::new(&crate_path),
derives,
"::subxt_path".into(),
crate_path,
);
let types = type_gen.generate_types_mod();
let tests_mod = get_mod(&types, MOD_PATH).unwrap();
+3 -3
View File
@@ -42,11 +42,11 @@ pub struct TypeDefGen {
impl TypeDefGen {
/// Construct a type definition for codegen from the given [`scale_info::Type`].
pub fn from_type(
ty: Type<PortableForm>,
ty: &Type<PortableForm>,
type_gen: &TypeGenerator,
crate_path: &CratePath,
) -> Self {
let derives = type_gen.type_derives(&ty);
let derives = type_gen.type_derives(ty);
let type_params = ty
.type_params()
@@ -80,7 +80,7 @@ impl TypeDefGen {
);
type_params.update_unused(fields.field_types());
let composite_def = CompositeDef::struct_def(
&ty,
ty,
&type_name,
type_params.clone(),
fields,