Commit 47cf6f5e authored by Michael Müller's avatar Michael Müller Committed by Hero Bird

Support multi-line comments in messages! macro (#215)

parent d218509f
Pipeline #54881 failed with stages
in 2 minutes and 44 seconds
...@@ -40,21 +40,19 @@ pub trait Message { ...@@ -40,21 +40,19 @@ pub trait Message {
/// Defines messages for contracts with less boilerplate code. /// Defines messages for contracts with less boilerplate code.
#[macro_export] #[macro_export]
macro_rules! messages { macro_rules! messages {
// When parsing the macro with a doc comment Rust cannot decide // There are three macros to handle the different cases of
// unambiguously if it should match the doc comment to `meta` or // `$prefix => Foo(maybe_args, …) -> maybe_return_type;`
// `expr`. Hence we introduce a `@delimiter` between the two of them. // where `$prefix` can be either `[a, b, c, d]` or `[a; 4]`.
// The first two rules match for macro invocations containing this
// delimiter, the subsequent ones add the delimiter if it's missing.
// With delimiter and a metavariable (typically a doc comment). // Matches `[a, b, c, d] => Foo(maybe_args, …) -> return type;`.
( (
$( #[$msg_meta:meta] )+ $( #[$msg_meta:meta] )*
@delimiter $msg_id:expr => $msg_name:ident ( [ $a:literal, $b:literal, $c:literal, $d:literal $(,)? ] => $msg_name:ident (
$( $param_name:ident : $param_ty:ty ),* $( $param_name:ident : $param_ty:ty ),*
) -> $ret_ty:ty ; ) -> $ret_ty:ty ;
$($rest:tt)* $($rest:tt)*
) => { ) => {
$( #[$msg_meta] )+ $( #[$msg_meta] )*
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub(crate) struct $msg_name; pub(crate) struct $msg_name;
...@@ -62,97 +60,46 @@ macro_rules! messages { ...@@ -62,97 +60,46 @@ macro_rules! messages {
type Input = ($($param_ty),*); type Input = ($($param_ty),*);
type Output = $ret_ty; type Output = $ret_ty;
const ID: $crate::MessageHandlerSelector = $crate::MessageHandlerSelector::new($msg_id); const ID: $crate::MessageHandlerSelector =
$crate::MessageHandlerSelector::new([$a, $b, $c, $d]);
const NAME: &'static str = stringify!($msg_name); const NAME: &'static str = stringify!($msg_name);
} }
messages!($($rest)*); messages!($($rest)*);
}; };
// With delimiter and no metavariable. // Matches `[a, b, c, d] => Foo(maybe_args, …);` (no return type).
( (
@delimiter $msg_id:expr => $msg_name:ident ( $( #[$msg_meta:meta] )*
$( $param_name:ident : $param_ty:ty ),* [ $a:literal, $b:literal, $c:literal, $d:literal $(,)? ] => $msg_name:ident (
) -> $ret_ty:ty ;
$($rest:tt)*
) => {
#[derive(Copy, Clone)]
pub(crate) struct $msg_name;
impl $crate::Message for $msg_name {
type Input = ($($param_ty),*);
type Output = $ret_ty;
const ID: $crate::MessageHandlerSelector = $crate::MessageHandlerSelector::new($msg_id);
const NAME: &'static str = stringify!($msg_name);
}
messages!($($rest)*);
};
// Without delimiter, with a metavariable and a return type.
(
$( #[$msg_meta:meta] )+
$msg_id:expr => $msg_name:ident (
$( $param_name:ident : $param_ty:ty ),*
) -> $ret_ty:ty ;
$($rest:tt)*
) => {
messages!(
$( #[$msg_meta] )+
@delimiter $msg_id => $msg_name (
$( $param_name : $param_ty ),*
) -> $ret_ty;
$($rest)*
);
};
// Without delimiter, with a metavariable but no return type.
(
$( #[$msg_meta:meta] )+
$msg_id:expr => $msg_name:ident (
$( $param_name:ident : $param_ty:ty ),* $( $param_name:ident : $param_ty:ty ),*
) ; ) ;
$($rest:tt)* $($rest:tt)*
) => { ) => {
messages!( messages!(
$( #[$msg_meta] )+ $( #[$msg_meta] )*
@delimiter $msg_id => $msg_name ( [$a, $b, $c, $d] => $msg_name (
$( $param_name : $param_ty ),* $( $param_name : $param_ty ),*
) -> (); ) -> ();
$($rest)* $($rest)*
); );
}; };
// Without delimiter, no metavariable but a return type. // Matches
( // * `[a; 4] => Foo(maybe_args, …) -> return type;` and
$msg_id:expr => $msg_name:ident ( // * `[a; 4] => Foo(maybe_args, …);`
$( $param_name:ident : $param_ty:ty ),*
) -> $ret_ty:ty ;
$($rest:tt)*
) => {
messages!(
@delimiter $msg_id => $msg_name (
$( $param_name : $param_ty ),*
) -> $ret_ty;
$($rest)*
);
};
// Without delimiter, no metavariable and no return type.
( (
$msg_id:expr => $msg_name:ident ( $( #[$msg_meta:meta] )*
[ $a:literal; 4 $(,)? ] => $msg_name:ident (
$( $param_name:ident : $param_ty:ty ),* $( $param_name:ident : $param_ty:ty ),*
) ; ) $(-> $maybe_ret:tt)*;
$($rest:tt)* $($rest:tt)*
) => { ) => {
messages!( messages!(
@delimiter $msg_id => $msg_name ( $( #[$msg_meta] )*
[$a, $a, $a, $a] => $msg_name (
$( $param_name : $param_ty ),* $( $param_name : $param_ty ),*
) -> (); ) $(-> $maybe_ret)* ;
$($rest)* $($rest)*
); );
}; };
......
...@@ -34,6 +34,9 @@ state! { ...@@ -34,6 +34,9 @@ state! {
} }
messages! { messages! {
/// Multiline comment
/// for a function
/// which does nothing.
[0u8; 4] => DoNothing(); [0u8; 4] => DoNothing();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment