diff --git a/proc-macro/src/lib.rs b/proc-macro/src/lib.rs index ccbea7e2b4..cecdfe397f 100644 --- a/proc-macro/src/lib.rs +++ b/proc-macro/src/lib.rs @@ -30,6 +30,58 @@ use synstructure::{ Structure, }; +/// Register type sizes for [EventsDecoder](struct.EventsDecoder.html) and set the `MODULE`. +/// +/// The `module` macro registers the type sizes of the associated types of a trait so that [EventsDecoder](struct.EventsDecoder.html) +/// can decode events of that type when received from Substrate. It also sets the `MODULE` constant +/// to the name of the trait (must match the name of the Substrate pallet) that enables the [Call](), [Event]() and [Store]() macros to work. +/// +/// If you do not want an associated type to be registered, likely because you never expect it as part of a response payload to be decoded, use `#[module(ignore)]` on the type. +/// +/// Example: +/// +/// ```ignore +/// #[module] +/// pub trait Herd: Husbandry { +/// type Hooves: HoofCounter; +/// type Wool: WoollyAnimal; +/// #[module(ignore)] +/// type Digestion: EnergyProducer + std::fmt::Debug; +/// } +/// ``` +/// +/// The above will produce the following code: +/// +/// ```ignore +/// pub trait Herd: Husbandry { +/// type Hooves: HoofCounter; +/// type Wool: WoollyAnimal; +/// #[module(ignore)] +/// type Digestion: EnergyProducer + std::fmt::Debug; +/// } +/// +/// const MODULE: &str = "Herd"; +/// +/// // `EventsDecoder` extension trait. +/// pub trait HerdEventsDecoder { +/// // Registers this modules types. +/// fn with_herd(&mut self); +/// } +/// +/// impl HerdEventsDecoder for +/// substrate_subxt::EventsDecoder +/// { +/// fn with_herd(&mut self) { +/// self.with_husbandry(); +/// self.register_type_size::("Hooves"); +/// self.register_type_size::("Wool"); +/// } +/// } +/// ``` +/// +/// The following type sizes are registered by default: `bool, u8, u32, AccountId, AccountIndex, +/// AuthorityId, AuthorityIndex, AuthorityWeight, BlockNumber, DispatchInfo, Hash, Kind, +/// MemberCount, PhantomData, PropIndex, ProposalIndex, ReferendumIndex, SessionIndex, VoteThreshold` #[proc_macro_attribute] #[proc_macro_error] pub fn module(args: TokenStream, input: TokenStream) -> TokenStream { diff --git a/proc-macro/src/module.rs b/proc-macro/src/module.rs index 5dddfd5899..b1d989235b 100644 --- a/proc-macro/src/module.rs +++ b/proc-macro/src/module.rs @@ -69,7 +69,7 @@ fn events_decoder_trait_name(module: &syn::Ident) -> syn::Ident { fn with_module_ident(module: &syn::Ident) -> syn::Ident { format_ident!("with_{}", module.to_string().to_snake_case()) } - +/// Attribute macro that registers the type sizes used by the module; also sets the `MODULE` constant. pub fn module(_args: TokenStream, tokens: TokenStream) -> TokenStream { let input: Result = syn::parse2(tokens.clone()); let input = if let Ok(input) = input { @@ -187,4 +187,46 @@ mod tests { let result = module(attr, input); utils::assert_proc_macro(result, expected); } + + #[test] + fn test_herd() { + let attr = quote!(#[module]); + let input = quote! { + pub trait Herd: Husbandry { + type Hoves: u8; + type Wool: bool; + #[module(ignore)] + type Digestion: EnergyProducer + fmt::Debug; + } + }; + let expected = quote! { + pub trait Herd: Husbandry { + type Hoves: u8; + type Wool: bool; + #[module(ignore)] + type Digestion: EnergyProducer + fmt::Debug; + } + + const MODULE: &str = "Herd"; + + /// `EventsDecoder` extension trait. + pub trait HerdEventsDecoder { + /// Registers this modules types. + fn with_herd(&mut self); + } + + impl HerdEventsDecoder for + substrate_subxt::EventsDecoder + { + fn with_herd(&mut self) { + self.with_husbandry(); + self.register_type_size::("Hoves"); + self.register_type_size::("Wool"); + } + } + }; + + let result = module(attr, input); + utils::assert_proc_macro(result, expected); + } } diff --git a/src/events.rs b/src/events.rs index b226947e4a..d5f75c9b8c 100644 --- a/src/events.rs +++ b/src/events.rs @@ -59,7 +59,7 @@ pub struct RawEvent { pub data: Vec, } -/// Event decoder. +/// Events decoder. #[derive(Debug)] pub struct EventsDecoder { metadata: Metadata,