mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 09:57:56 +00:00
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:
+43
-53
@@ -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(), ¶ms)
|
||||
{
|
||||
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(
|
||||
|
||||
@@ -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
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user