Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Add weight_args helper attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
KiChjang committed Dec 29, 2021
1 parent 516b02d commit 3b7c47a
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 25 deletions.
2 changes: 1 addition & 1 deletion xcm/procedural/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub fn impl_conversion_functions_for_multilocation_v1(input: TokenStream) -> Tok
.into()
}

#[proc_macro_derive(XcmWeightInfoTrait)]
#[proc_macro_derive(XcmWeightInfoTrait, attributes(weight_args))]
pub fn derive_xcm_weight_info(item: TokenStream) -> TokenStream {
weight_info::derive(item)
}
60 changes: 42 additions & 18 deletions xcm/procedural/src/weight_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,32 @@ pub fn derive(item: proc_macro::TokenStream) -> proc_macro::TokenStream {

match data {
syn::Data::Enum(syn::DataEnum { variants, .. }) => {
let methods = variants.into_iter().map(|syn::Variant { ident, fields, .. }| {
let snake_cased_ident = format_ident!("{}", ident.to_string().to_snake_case());
let ref_fields =
fields.into_iter().enumerate().map(|(idx, syn::Field { ident, ty, .. })| {
let field_name = ident.unwrap_or_else(|| format_ident!("_{}", idx));
let field_ty = match ty {
syn::Type::Reference(r) => {
// If the type is already a reference, do nothing
quote::quote!(#r)
},
t => {
// Otherwise, make it a reference
quote::quote!(&#t)
},
};
let methods =
variants.into_iter().map(|syn::Variant { ident, fields, attrs, .. }| {
let snake_cased_ident = format_ident!("{}", ident.to_string().to_snake_case());
let ref_fields = parse_args_attr(attrs).unwrap_or_else(|| {
fields
.into_iter()
.enumerate()
.map(|(idx, syn::Field { ident, ty, .. })| {
let field_name = ident.unwrap_or_else(|| format_ident!("_{}", idx));
let field_ty = match ty {
syn::Type::Reference(r) => {
// If the type is already a reference, do nothing
quote::quote!(#r)
},
t => {
// Otherwise, make it a reference
quote::quote!(&#t)
},
};

quote::quote!(#field_name: #field_ty,)
quote::quote!(#field_name: #field_ty,)
})
.collect()
});
quote::quote!(fn #snake_cased_ident( #(#ref_fields)* ) -> Weight;)
});
quote::quote!(fn #snake_cased_ident( #ref_fields ) -> Weight;)
});

let res = quote::quote! {
pub trait XcmWeightInfo #generics {
Expand All @@ -65,3 +71,21 @@ pub fn derive(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
},
}
}

fn parse_args_attr(attrs: Vec<syn::Attribute>) -> Option<proc_macro2::TokenStream> {
attrs.into_iter().find_map(|attr| {
attr.path.get_ident().filter(|ident| *ident == "weight_args").and_then(|_| {
attr.parse_args_with(|stream: syn::parse::ParseStream| {
let mut fields = Vec::new();
while !stream.is_empty() {
let ident: syn::Ident = stream.parse()?;
let _colon: syn::Token![:] = stream.parse()?;
let ty: syn::Type = stream.parse()?;
fields.push(quote::quote!(#ident: #ty));
}
Ok(quote::quote!( #(#fields),* ))
})
.ok()
})
})
}
12 changes: 6 additions & 6 deletions xcm/src/v3/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,11 @@ pub use multiasset::{
AssetId, AssetInstance, Fungibility, MultiAsset, MultiAssetFilter, MultiAssets,
WildFungibility, WildMultiAsset,
};
pub use traits::{
Error, ExecuteXcm, Outcome, Result, SendError, SendResult, SendXcm, Weight, XcmWeightInfo,
};
pub use traits::{Error, ExecuteXcm, Outcome, Result, SendError, SendResult, SendXcm};
// These parts of XCM v2 are unchanged in XCM v3, and are re-imported here.
pub use super::v2::{
Ancestor, AncestorThen, BodyId, BodyPart, InteriorMultiLocation, Junction, Junctions,
MultiLocation, NetworkId, OriginKind, Parent, ParentThen, WeightLimit,
MultiLocation, NetworkId, OriginKind, Parent, ParentThen, Weight, WeightLimit,
};

/// This module's XCM version.
Expand Down Expand Up @@ -218,7 +216,7 @@ pub struct QueryResponseInfo {
///
/// This is the inner XCM format and is version-sensitive. Messages are typically passed using the outer
/// XCM format, known as `VersionedXcm`.
#[derive(Derivative, Encode, Decode, TypeInfo)]
#[derive(Derivative, Encode, Decode, TypeInfo, xcm_procedural::XcmWeightInfoTrait)]
#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))]
#[codec(encode_bound())]
#[codec(decode_bound())]
Expand Down Expand Up @@ -662,6 +660,7 @@ pub enum Instruction<Call> {
/// Kind: *Instruction*
///
/// Errors: *Fallible*.
#[weight_args()]
QueryPallet { module_name: Vec<u8>, response_info: QueryResponseInfo },

/// Ensure that a particular pallet with a particular version exists.
Expand All @@ -678,6 +677,7 @@ pub enum Instruction<Call> {
///
/// Errors:
/// - `ExpectationFalse`: In case any of the expectations are broken.
#[weight_args(index: &u32)]
ExpectPallet {
#[codec(compact)]
index: u32,
Expand Down Expand Up @@ -771,7 +771,7 @@ impl<Call> Instruction<Call> {
QueryPallet { module_name, response_info },
ExpectPallet { index, name, module_name, crate_major, min_crate_minor } =>
ExpectPallet { index, name, module_name, crate_major, min_crate_minor },
ReportTransactStatus(repsonse_info) => ReportTransactStatus(repsonse_info),
ReportTransactStatus(response_info) => ReportTransactStatus(response_info),
ClearTransactStatus => ClearTransactStatus,
}
}
Expand Down

0 comments on commit 3b7c47a

Please sign in to comment.