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

Commit

Permalink
Make decl_event! more flexible with the automatic naming of generic…
Browse files Browse the repository at this point in the history
… parameters

The macro will now automatically derive the name of a generic parameter
from the trait type name, if no explicit name is given.

`where Balance = <T as Trait>::Balance` can be simplified to
`where <T as Trait>::Balance`.
  • Loading branch information
bkchr committed Sep 12, 2018
1 parent 510287c commit 5c056ce
Show file tree
Hide file tree
Showing 10 changed files with 205 additions and 47 deletions.
217 changes: 193 additions & 24 deletions substrate/runtime-support/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,60 +14,217 @@
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.

/// Implement an `Event`/`RawEvent` for a module.
/// Implement the `Event` for a module.
///
/// # Simple Event Example:
///
/// ```rust
/// #[macro_use]
/// extern crate substrate_runtime_support;
/// extern crate substrate_codec as codec;
/// #[macro_use]
/// extern crate substrate_codec_derive;
/// #[macro_use]
/// extern crate serde_derive;
///
/// decl_event!(
/// pub enum Event {
/// Success,
/// Failure(String),
/// }
/// );
///# fn main() {}
/// ```
///
/// # Generic Event Example:
///
/// ```rust
/// #[macro_use]
/// extern crate substrate_runtime_support;
/// extern crate substrate_codec as codec;
/// #[macro_use]
/// extern crate substrate_codec_derive;
/// #[macro_use]
/// extern crate serde_derive;
///
/// trait Trait {
/// type Balance;
/// type Token;
/// }
///
/// mod event1 {
/// // Event that specifies the generic parameter explicitly (`Balance`).
/// decl_event!(
/// pub enum Event<T> where Balance = <T as super::Trait>::Balance {
/// Message(Balance),
/// }
/// );
/// }
///
/// mod event2 {
/// // Event that uses the generic parameter `Balance`.
/// // If no name for the generic parameter is speciefied explicitly,
/// // the name will be taken from the type name of the trait.
/// decl_event!(
/// pub enum Event<T> where <T as super::Trait>::Balance {
/// Message(Balance),
/// }
/// );
/// }
///
/// mod event3 {
/// // And we even support declaring multiple generic parameters!
/// decl_event!(
/// pub enum Event<T> where <T as super::Trait>::Balance, <T as super::Trait>::Token {
/// Message(Balance, Token),
/// }
/// );
/// }
///# fn main() {}
/// ```
///
/// The syntax for generic events requires the `where`.
#[macro_export]
macro_rules! decl_event {
(
$(#[$attr:meta])*
pub enum Event<$evt_generic_param:ident>
where $($generic_param:ident = <$generic:ident as $trait:path>::$trait_type:ident),*
pub enum Event<$evt_generic_param:ident> where
$( $( $generic_rename:ident = )* <$generic:ident as $trait:path>::$trait_type:ident ),*
{
$(
$events:tt
)*
}
) => {
pub type Event<$evt_generic_param> = RawEvent<$( <$generic as $trait>::$trait_type ),*>;
__decl_generic_event!(
$( #[ $attr ] )*;
$evt_generic_param;
$( $( $generic_rename = )* <$generic as $trait>::$trait_type ),*;
Events { $( $events )* };
);
};
(
$(#[$attr:meta])*
pub enum Event {
$(
$events:tt
)*
}
) => {
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
$(#[$attr])*
pub enum RawEvent<$( $generic_param ),*> {
pub enum Event {
$(
$events
)*
}
impl<$( $generic_param ),*> From<RawEvent<$( $generic_param ),*>> for () {
fn from(_: RawEvent<$( $generic_param ),*>) -> () { () }
impl From<Event> for () {
fn from(_: Event) -> () { () }
}
impl<$( $generic_param ),*> RawEvent<$( $generic_param ),*> {
impl Event {
#[allow(dead_code)]
pub fn event_json_metadata() -> &'static str {
concat!("{", __events_to_json!(""; $( $events )* ), " }")
}
}
}
}

#[macro_export]
#[doc(hidden)]
macro_rules! __decl_generic_event {
(
$(#[$attr:meta])*;
$event_generic_param:ident;
$generic_rename:ident = <$generic:ident as $trait:path>::$trait_type:ident
$(, $( $rest_gen_rename:ident = )* <$rest_gen:ident as $rest_trait:path>::$rest_trait_type:ident )*;
Events { $( $events:tt )* };
) => {
__decl_generic_event!(
$( #[ $attr ] )*;
$event_generic_param;
$( $( $rest_gen_rename = )* <$rest_gen as $rest_trait>::$rest_trait_type ),*;
Events { $( $events )* };
$generic_rename;
<$generic as $trait>::$trait_type;
);
};
(
$(#[$attr:meta])*
pub enum Event {
$(
$events:tt
)*
}
$(#[$attr:meta])*;
$event_generic_param:ident;
$generic_rename:ident = <$generic:ident as $trait:path>::$trait_type:ident
$(, $( $rest_gen_rename:ident = )* <$rest_gen:ident as $rest_trait:path>::$rest_trait_type:ident )*;
Events { $( $events:tt )* };
$( $parsed_generic_params:ident ),*;
$( <$parsed_generic:ident as $parsed_trait:path>::$parsed_trait_type:ident ),*;
) => {
__decl_generic_event!(
$( #[ $attr ] )*;
$event_generic_param;
$( $( $rest_gen_rename = )* <$rest_gen as $rest_trait>::$rest_trait_type ),*;
Events { $( $events )* };
$( $parsed_generic_params ),*, $generic_rename;
$( <$parsed_generic as $parsed_trait>::$parsed_trait_type ),*, <$generic as $trait>::$trait_type;
);
};
(
$(#[$attr:meta])*;
$event_generic_param:ident;
<$generic:ident as $trait:path>::$trait_type:ident
$(, $( $rest_gen_rename:ident = )* <$rest_gen:ident as $rest_trait:path>::$rest_trait_type:ident )*;
Events { $( $events:tt )* };
) => {
__decl_generic_event!(
$( #[ $attr ] )*;
$event_generic_param;
$( $( $rest_gen_rename = )* <$rest_gen as $rest_trait>::$rest_trait_type ),*;
Events { $( $events )* };
$trait_type;
<$generic as $trait>::$trait_type;
);
};
(
$(#[$attr:meta])*;
$event_generic_param:ident;
<$generic:ident as $trait:path>::$trait_type:ident
$(, $( $rest_gen_rename:ident = )* <$rest_gen:ident as $rest_trait:path>::$rest_trait_type:ident )*;
Events { $( $events:tt )* };
$( $parsed_generic_params:ident ),*;
$( <$parsed_generic:ident as $parsed_trait:path>::$parsed_trait_type:ident ),*;
) => {
__decl_generic_event!(
$( #[ $attr ] )*;
$event_generic_param;
$( $( $rest_gen_rename = )* <$rest_gen as $rest_trait>::$rest_trait_type ),*;
Events { $( $events )* };
$( $parsed_generic_params ),*, $trait_type;
$( <$parsed_generic as $parsed_trait>::$parsed_trait_type ),*, <$generic as $trait>::$trait_type;
);
};
(
$(#[$attr:meta])*;
$event_generic_param:ident;
;
Events { $( $events:tt )* };
$( $generic_param:ident ),*;
$( <$generic:ident as $trait:path>::$trait_type:ident ),*;
) => {
pub type Event<$event_generic_param> = RawEvent<$( <$generic as $trait>::$trait_type ),*>;
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
$(#[$attr])*
pub enum Event {
pub enum RawEvent<$( $generic_param ),*> {
$(
$events
)*
}
impl From<Event> for () {
fn from(_: Event) -> () { () }
impl<$( $generic_param ),*> From<RawEvent<$( $generic_param ),*>> for () {
fn from(_: RawEvent<$( $generic_param ),*>) -> () { () }
}
impl Event {
impl<$( $generic_param ),*> RawEvent<$( $generic_param ),*> {
#[allow(dead_code)]
pub fn event_json_metadata() -> &'static str {
concat!("{", __events_to_json!(""; $( $events )* ), " }")
Expand Down Expand Up @@ -203,10 +360,11 @@ mod tests {
}

decl_event!(
pub enum Event<T> where Balance = <T as Trait>::Balance
/// Event without renaming the generic parameter `Balance` and `Origin`.
pub enum Event<T> where <T as Trait>::Balance, <T as Trait>::Origin
{
/// Hi, I am a comment.
TestEvent(Balance),
TestEvent(Balance, Origin),
/// Dog
EventWithoutParams,
}
Expand All @@ -224,9 +382,13 @@ mod tests {
}

decl_event!(
pub enum Event<T> where Balance = <T as Trait>::Balance
/// Event with renamed generic parameter
pub enum Event<T> where
BalanceRenamed = <T as Trait>::Balance,
OriginRenamed = <T as Trait>::Origin
{
TestEvent(Balance),
TestEvent(BalanceRenamed),
TestOrigin(OriginRenamed),
}
);
}
Expand Down Expand Up @@ -260,12 +422,19 @@ mod tests {
("event_module",
concat!(
"{",
r#" "TestEvent": { "params": [ "Balance" ], "description": [ " Hi, I am a comment." ] },"#,
r#" "TestEvent": { "params": [ "Balance", "Origin" ], "description": [ " Hi, I am a comment." ] },"#,
r#" "EventWithoutParams": { "params": null, "description": [ " Dog" ] }"#,
" }"
)
),
("event_module2", r#"{ "TestEvent": { "params": [ "Balance" ], "description": [ ] } }"#),
("event_module2",
concat!(
"{",
r#" "TestEvent": { "params": [ "BalanceRenamed" ], "description": [ ] },"#,
r#" "TestOrigin": { "params": [ "OriginRenamed" ], "description": [ ] }"#,
" }"
)
),
]
);

Expand Down
4 changes: 2 additions & 2 deletions substrate/runtime-support/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ mod tests {
}

decl_event!(
pub enum Event<T> where Balance = <T as Trait>::Balance
pub enum Event<T> where <T as Trait>::Balance
{
/// Hi, I am a comment.
TestEvent(Balance),
Expand All @@ -339,7 +339,7 @@ mod tests {
}

decl_event!(
pub enum Event<T> where Balance = <T as Trait>::Balance
pub enum Event<T> where <T as Trait>::Balance
{
TestEvent(Balance),
}
Expand Down
6 changes: 3 additions & 3 deletions substrate/runtime/balances/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,9 @@ decl_module! {

decl_event!(
pub enum Event<T> where
AccountId = <T as system::Trait>::AccountId,
AccountIndex = <T as Trait>::AccountIndex,
Balance = <T as Trait>::Balance
<T as system::Trait>::AccountId,
<T as Trait>::AccountIndex,
<T as Trait>::Balance
{
/// A new account was created.
NewAccount(AccountId, AccountIndex, NewAccountOutcome),
Expand Down
4 changes: 1 addition & 3 deletions substrate/runtime/council/src/motions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@ pub enum Origin {

/// Event for this module.
decl_event!(
pub enum Event<T>
where Hash = <T as system::Trait>::Hash, AccountId = <T as system::Trait>::AccountId
{
pub enum Event<T> where <T as system::Trait>::Hash, <T as system::Trait>::AccountId {
/// A motion (given hash) has been proposed (by given account) with a threshold (given u32).
Proposed(AccountId, ProposalIndex, Hash, u32),
/// A motion (given hash) has been voted on by given account, leaving
Expand Down
2 changes: 1 addition & 1 deletion substrate/runtime/council/src/seats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ decl_storage! {

decl_event!(
/// An event in this module.
pub enum Event<T> where AccountId = <T as system::Trait>::AccountId {
pub enum Event<T> where <T as system::Trait>::AccountId {
/// reaped voter, reaper
VoterReaped(AccountId, AccountId),
/// slashed reaper
Expand Down
2 changes: 1 addition & 1 deletion substrate/runtime/council/src/voting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ decl_storage! {

/// An event in this module.
decl_event!(
pub enum Event<T> where Hash = <T as system::Trait>::Hash {
pub enum Event<T> where <T as system::Trait>::Hash {
/// A voting tally has happened for a referendum cancelation vote.
/// Last three are yes, no, abstain counts.
TallyCancelation(Hash, u32, u32, u32),
Expand Down
5 changes: 1 addition & 4 deletions substrate/runtime/democracy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,7 @@ decl_storage! {

decl_event!(
/// An event in this module.
pub enum Event<T> where
Balance = <T as balances::Trait>::Balance,
AccountId = <T as system::Trait>::AccountId
{
pub enum Event<T> where <T as balances::Trait>::Balance, <T as system::Trait>::AccountId {
Tabled(PropIndex, Balance, Vec<AccountId>),
Started(ReferendumIndex, VoteThreshold),
Passed(ReferendumIndex),
Expand Down
2 changes: 1 addition & 1 deletion substrate/runtime/session/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ decl_module! {

/// An event in this module.
decl_event!(
pub enum Event<T> where BlockNumber = <T as system::Trait>::BlockNumber {
pub enum Event<T> where <T as system::Trait>::BlockNumber {
/// New session has happened. Note that the argument is the session index, not the block
/// number as the type might suggest.
NewSession(BlockNumber),
Expand Down
5 changes: 1 addition & 4 deletions substrate/runtime/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,7 @@ decl_module! {

/// An event in this module.
decl_event!(
pub enum Event<T> where
Balance = <T as balances::Trait>::Balance,
AccountId = <T as system::Trait>::AccountId
{
pub enum Event<T> where <T as balances::Trait>::Balance, <T as system::Trait>::AccountId {
/// All validators have been rewarded by the given balance.
Reward(Balance),
/// One validator (and their nominators) has been given a offline-warning (they're still
Expand Down
5 changes: 1 addition & 4 deletions substrate/runtime/treasury/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,7 @@ decl_storage! {

/// An event in this module.
decl_event!(
pub enum Event<T> where
Balance = <T as balances::Trait>::Balance,
AccountId = <T as system::Trait>::AccountId
{
pub enum Event<T> where <T as balances::Trait>::Balance, <T as system::Trait>::AccountId {
/// New proposal.
Proposed(ProposalIndex),
/// We have ended a spend period and will now allocate funds.
Expand Down

0 comments on commit 5c056ce

Please sign in to comment.