Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Propagate documentation to runtime API #511

Merged
merged 12 commits into from
Apr 21, 2022
9 changes: 7 additions & 2 deletions codegen/src/api/calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ pub fn generate_calls(
call: &PalletCallMetadata<PortableForm>,
types_mod_ident: &syn::Ident,
) -> TokenStream2 {
let struct_defs = super::generate_structs_from_variants(
let mut struct_defs = super::generate_structs_from_variants(
type_gen,
call.ty.id(),
|name| name.to_upper_camel_case().into(),
"Call",
);
let (call_structs, call_fns): (Vec<_>, Vec<_>) = struct_defs
.iter()
.iter_mut()
.map(|struct_def| {
let (call_fn_args, call_args): (Vec<_>, Vec<_>) =
match struct_def.fields {
Expand Down Expand Up @@ -78,6 +78,10 @@ pub fn generate_calls(
let function_name = struct_def.name.to_string().to_snake_case();
let fn_name = format_ident!("{}", function_name);

// Propagate the documentation just to `TransactionApi` methods, while
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you explain the why the docs for the inner call structures are "drained" and generated for the wrappers only?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My initial intuition was to keep the documentation on both the calling methods and inner structures.
The user should call the exposed API and not necessarily care about the inner structures used to construct the call.

  pub struct Transfer {
   ...
      pub value: ::core::primitive::u128,
  }

  /// Doc goes here
  pub fn transfer( ... ) {
      let call = Transfer { dest, value };
      ::subxt::SubmittableExtrinsic::new(self.client, call)
  }

Although someone could potentially submit a manually constructed extrinsic (as the pub fn transfer implementation), I think this is quite uncommon.

Would you think having documentation on both would also satisfy those manually constructed cases? 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I agree the outer docs should be sufficient then.

I think someone constructs their own extrinsics I guess they are on their own anyway.

// draining the documentation of inner call structures.
let docs = struct_def.docs.take();
// The call structure's documentation was stripped above.
let call_struct = quote! {
#struct_def

Expand All @@ -87,6 +91,7 @@ pub fn generate_calls(
}
};
let client_fn = quote! {
#docs
pub fn #fn_name(
&self,
#( #call_fn_args, )*
Expand Down
2 changes: 2 additions & 0 deletions codegen/src/api/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ pub fn generate_constants(
let pallet_name = &pallet.name;
let constant_name = &constant.name;
let return_ty = type_gen.resolve_type_path(constant.ty.id(), &[]);
let docs = &constant.docs;

quote! {
#( #[doc = #docs ] )*
pub fn #fn_name(&self) -> ::core::result::Result<#return_ty, ::subxt::BasicError> {
let pallet = self.client.metadata().pallet(#pallet_name)?;
let constant = pallet.constant(#constant_name)?;
Expand Down
1 change: 1 addition & 0 deletions codegen/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,7 @@ where
fields,
Some(parse_quote!(pub)),
type_gen,
var.docs(),
)
})
.collect()
Expand Down
5 changes: 5 additions & 0 deletions codegen/src/api/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,11 @@ fn generate_storage_entry_fns(
}
};

let docs = &storage_entry.docs;
let docs_token = quote! { #( #[doc = #docs ] )* };
let client_iter_fn = if matches!(storage_entry.ty, StorageEntryType::Map { .. }) {
quote! (
#docs_token
pub async fn #fn_name_iter(
&self,
hash: ::core::option::Option<T::Hash>,
Expand All @@ -271,7 +274,9 @@ fn generate_storage_entry_fns(
};
quote!( #field_name: #reference #field_ty )
});

let client_fns = quote! {
#docs_token
pub async fn #fn_name(
&self,
#( #key_args, )*
Expand Down
16 changes: 15 additions & 1 deletion codegen/src/types/composite_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ pub struct CompositeDef {
pub kind: CompositeDefKind,
/// The fields of the type, which are either all named or all unnamed.
pub fields: CompositeDefFields,
/// Documentation of the composite type as presented in metadata.
pub docs: Option<TokenStream>,
}

impl CompositeDef {
Expand All @@ -55,6 +57,7 @@ impl CompositeDef {
fields_def: CompositeDefFields,
field_visibility: Option<syn::Visibility>,
type_gen: &TypeGenerator,
docs: &[String],
) -> Self {
let mut derives = type_gen.derives().clone();
let fields: Vec<_> = fields_def.field_types().collect();
Expand Down Expand Up @@ -85,6 +88,7 @@ impl CompositeDef {
}

let name = format_ident!("{}", ident);
let docs_token = Some(quote! { #( #[doc = #docs ] )* });

Self {
name,
Expand All @@ -94,23 +98,31 @@ impl CompositeDef {
field_visibility,
},
fields: fields_def,
docs: docs_token,
}
}

/// Construct a definition which will generate code for an `enum` variant.
pub fn enum_variant_def(ident: &str, fields: CompositeDefFields) -> Self {
pub fn enum_variant_def(
ident: &str,
fields: CompositeDefFields,
docs: &[String],
) -> Self {
let name = format_ident!("{}", ident);
let docs_token = Some(quote! { #( #[doc = #docs ] )* });
Self {
name,
kind: CompositeDefKind::EnumVariant,
fields,
docs: docs_token,
}
}
}

impl quote::ToTokens for CompositeDef {
fn to_tokens(&self, tokens: &mut TokenStream) {
let name = &self.name;
let docs = &self.docs;

let decl = match &self.kind {
CompositeDefKind::Struct {
Expand All @@ -130,13 +142,15 @@ impl quote::ToTokens for CompositeDef {

quote! {
#derives
#docs
pub struct #name #type_params #fields #trailing_semicolon
}
}
CompositeDefKind::EnumVariant => {
let fields = self.fields.to_enum_variant_field_tokens();

quote! {
#docs
#name #fields
}
}
Expand Down
3 changes: 2 additions & 1 deletion codegen/src/types/type_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ impl<'a> TypeDefGen<'a> {
fields,
Some(parse_quote!(pub)),
type_gen,
ty.docs(),
);
TypeDefGenKind::Struct(composite_def)
}
Expand All @@ -107,7 +108,7 @@ impl<'a> TypeDefGen<'a> {
);
type_params.update_unused(fields.field_types());
let variant_def =
CompositeDef::enum_variant_def(v.name(), fields);
CompositeDef::enum_variant_def(v.name(), fields, v.docs());
(v.index(), variant_def)
})
.collect();
Expand Down
Loading