Skip to content

Commit

Permalink
add no_default_substitutions to the macro and cli (#936)
Browse files Browse the repository at this point in the history
  • Loading branch information
tadeohepperle authored Apr 27, 2023
1 parent 464b443 commit 40339b3
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 61 deletions.
14 changes: 13 additions & 1 deletion cli/src/commands/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ pub struct Opts {
/// Defaults to `false` (default trait derivations are provided).
#[clap(long)]
no_default_derives: bool,
/// Do not provide default substitutions for the generated types.
///
/// Defaults to `false` (default substitutions are provided).
#[clap(long)]
no_default_substitutions: bool,
}

fn derive_for_type_parser(src: &str) -> Result<(String, String), String> {
Expand Down Expand Up @@ -96,6 +101,7 @@ pub async fn run(opts: Opts) -> color_eyre::Result<()> {
opts.no_docs,
opts.runtime_types_only,
opts.no_default_derives,
opts.no_default_substitutions,
)?;
Ok(())
}
Expand All @@ -121,6 +127,7 @@ fn codegen(
no_docs: bool,
runtime_types_only: bool,
no_default_derives: bool,
no_default_substitutions: bool,
) -> color_eyre::Result<()> {
let item_mod = syn::parse_quote!(
pub mod api {}
Expand Down Expand Up @@ -155,7 +162,12 @@ fn codegen(
derives.extend_for_type(ty, vec![], std::iter::once(attribute.0));
}

let mut type_substitutes = TypeSubstitutes::new(&crate_path);
let mut type_substitutes = if no_default_substitutions {
TypeSubstitutes::new()
} else {
TypeSubstitutes::with_default_substitutes(&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)?;
Expand Down
2 changes: 1 addition & 1 deletion codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
//! // Default module derivatives.
//! let mut derives = DerivesRegistry::with_default_derives(&CratePath::default());
//! // Default type substitutes.
//! let substs = TypeSubstitutes::new(&CratePath::default());
//! let substs = TypeSubstitutes::with_default_substitutes(&CratePath::default());
//! // Generate the Runtime API.
//! let generator = subxt_codegen::RuntimeGenerator::new(metadata);
//! // Include metadata documentation in the Runtime API.
Expand Down
40 changes: 28 additions & 12 deletions codegen/src/types/substitutes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,25 @@ macro_rules! path_segments {
}
}

impl Default for TypeSubstitutes {
fn default() -> Self {
Self::new()
}
}

impl TypeSubstitutes {
/// Create a new set of type substitutes with some default substitutions in place.
pub fn new(crate_path: &CratePath) -> Self {
/// Creates a new `TypeSubstitutes` with no default derives.
pub fn new() -> Self {
Self {
substitutes: HashMap::new(),
}
}

/// Creates a new `TypeSubstitutes` with some default substitutions in place.
///
/// The `crate_path` denotes the `subxt` crate access path in the
/// generated code.
pub fn with_default_substitutes(crate_path: &CratePath) -> Self {
// Some hardcoded default type substitutes, can be overridden by user
let defaults = [
(
Expand Down Expand Up @@ -163,11 +179,11 @@ impl TypeSubstitutes {
src_path: &syn::Path,
target_path: &syn::Path,
) -> Result<TypeParamMapping, TypeSubstitutionError> {
let Some(syn::PathSegment { arguments: src_path_args, ..}) = src_path.segments.last() else {
return Err(TypeSubstitutionError::EmptySubstitutePath(src_path.span()))
let Some(syn::PathSegment { arguments: src_path_args, .. }) = src_path.segments.last() else {
return Err(TypeSubstitutionError::EmptySubstitutePath(src_path.span()));
};
let Some(syn::PathSegment { arguments: target_path_args, ..}) = target_path.segments.last() else {
return Err(TypeSubstitutionError::EmptySubstitutePath(target_path.span()))
let Some(syn::PathSegment { arguments: target_path_args, .. }) = target_path.segments.last() else {
return Err(TypeSubstitutionError::EmptySubstitutePath(target_path.span()));
};

// Get hold of the generic args for the "from" type, erroring if they aren't valid.
Expand Down Expand Up @@ -331,14 +347,14 @@ fn replace_path_params_recursively<I: Borrow<syn::Ident>, P: Borrow<TypePath>>(
) {
for segment in &mut path.segments {
let syn::PathArguments::AngleBracketed(args) = &mut segment.arguments else {
continue
continue;
};
for arg in &mut args.args {
let syn::GenericArgument::Type(ty) = arg else {
continue
continue;
};
let syn::Type::Path(path) = ty else {
continue
continue;
};
if let Some(ident) = get_ident_from_type_path(path) {
if let Some((_, replacement)) = params.iter().find(|(i, _)| ident == i.borrow()) {
Expand All @@ -356,7 +372,7 @@ fn replace_path_params_recursively<I: Borrow<syn::Ident>, P: Borrow<TypePath>>(
fn get_valid_to_substitution_type(arg: &syn::GenericArgument) -> Option<&syn::TypePath> {
let syn::GenericArgument::Type(syn::Type::Path(type_path)) = arg else {
// We are looking for a type, not a lifetime or anything else
return None
return None;
};
Some(type_path)
}
Expand All @@ -366,7 +382,7 @@ fn get_valid_to_substitution_type(arg: &syn::GenericArgument) -> Option<&syn::Ty
fn get_valid_from_substitution_type(arg: &syn::GenericArgument) -> Option<&syn::Ident> {
let syn::GenericArgument::Type(syn::Type::Path(type_path)) = arg else {
// We are looking for a type, not a lifetime or anything else
return None
return None;
};
get_ident_from_type_path(type_path)
}
Expand All @@ -387,7 +403,7 @@ fn get_ident_from_type_path(type_path: &syn::TypePath) -> Option<&syn::Ident> {
}
let Some(segment) = type_path.path.segments.last() else {
// Get the single ident (should be infallible)
return None
return None;
};
if !segment.arguments.is_empty() {
// The ident shouldn't have any of it's own generic args like A<B, C>
Expand Down
Loading

0 comments on commit 40339b3

Please sign in to comment.