[][src]Macro bastion::msg

macro_rules! msg {
    ($msg:expr, $($tokens:tt)+) => { ... };
    (@internal
        $msg:expr,
        ($($bvar:ident, $bty:ty, $bhandle:expr,)*),
        ($($tvar:ident, $tty:ty, $thandle:expr,)*),
        ($($avar:ident, $aty:ty, $ahandle:expr,)*),
        ref $var:ident: $ty:ty => $handle:expr;
        $($rest:tt)+
    ) => { ... };
    (@internal
        $msg:expr,
        ($($bvar:ident, $bty:ty, $bhandle:expr,)*),
        ($($tvar:ident, $tty:ty, $thandle:expr,)*),
        ($($avar:ident, $aty:ty, $ahandle:expr,)*),
        $var:ident: $ty:ty => $handle:expr;
        $($rest:tt)+
    ) => { ... };
    (@internal
        $msg:expr,
        ($($bvar:ident, $bty:ty, $bhandle:expr,)*),
        ($($tvar:ident, $tty:ty, $thandle:expr,)*),
        ($($avar:ident, $aty:ty, $ahandle:expr,)*),
        $var:ident: $ty:ty =!> $handle:expr;
        $($rest:tt)+
    ) => { ... };
    (@internal
        $msg:expr,
        ($($bvar:ident, $bty:ty, $bhandle:expr,)*),
        ($($tvar:ident, $tty:ty, $thandle:expr,)*),
        ($($avar:ident, $aty:ty, $ahandle:expr,)*),
        _: _ => $handle:expr;
    ) => { ... };
    (@internal
        $msg:expr,
        ($($bvar:ident, $bty:ty, $bhandle:expr,)*),
        ($($tvar:ident, $tty:ty, $thandle:expr,)*),
        ($($avar:ident, $aty:ty, $ahandle:expr,)*),
        $var:ident: _ => $handle:expr;
    ) => { ... };
}

Matches a Msg (as returned by BastionContext::recv or BastionContext::try_recv) with different types.

Each case is defined as:

  • an optional ref which will make the case only match if the message was broadcasted
  • a variable name for the message if it matched this case
  • a colon
  • a type that the message must be of to match this case (note that if the message was broadcasted, the actual type of the variable will be a reference to this type)
  • an arrow (=>) with an optional bang (!) between the equal and greater-than signs which will make the case only match if the message can be answered
  • code that will be executed if the case matches

If the message can be answered (when using =!> instead of => as said above), an answer can be sent by passing it to the answer! macro that will be generated for this use.

A default case is required, which is defined in the same way as any other case but with its type set as _ (note that it doesn't has the optional ref or =!>).

Example

// The message that will be broadcasted...
const BCAST_MSG: &'static str = "A message containing data (broadcast).";
// The message that will be "told" to the child...
const TELL_MSG: &'static str = "A message containing data (tell).";
// The message that will be "asked" to the child...
const ASK_MSG: &'static str = "A message containing data (ask).";

Bastion::children(|children| {
    children.with_exec(|ctx: BastionContext| {
        async move {
            loop {
                msg! { ctx.recv().await?,
                    // We match broadcasted `&'static str`s...
                    ref msg: &'static str => {
                        // Note that `msg` will actually be a `&&'static str`.
                        assert_eq!(msg, &BCAST_MSG);
                        // Handle the message...
                    };
                    // We match `&'static str`s "told" to this child...
                    msg: &'static str => {
                        assert_eq!(msg, TELL_MSG);
                        // Handle the message...
                    };
                    // We match `&'static str`'s "asked" to this child...
                    msg: &'static str =!> {
                        assert_eq!(msg, ASK_MSG);
                        // Handle the message...

                        // ...and eventually answer to it...
                        answer!(ctx, "An answer to the message.");
                    };
                    // We are only broadcasting, "telling" and "asking" a
                    // `&'static str` in this example, so we know that this won't
                    // happen...
                    _: _ => ();
                }
            }
        }
    })
}).expect("Couldn't start the children group.");