Murray

The murray crate provides a actor macro that helps defining erlang inspired actors. The actor is targeted at async and tokio but can be adapted by useing other mpsc channels.

Use

``` actor! { Foo, Messages: { Msg1, Msg2, Msg3 { ch: mpsc::Receiver } } }

impl FooActor { fn handle(&self, state: &mut FooActorState, msg: FooActorMessages) -> () { () }

}

actor! { Bar, Options: { sup: Foo, id: String, }, Messages: { A, B { x: bool, }, }, State: { foo: TypeC, } }

impl FooActor { async fn handlemsg1(&self, state: &mut FooActorState) { ... } async fn handlemsg2(&self, state: &mut FooActorState) { ... } async fn handle_msg3(&self, state: &mut FooActorState, msg: FooActorMessagesMsg3) { ... } }

impl BarActor { async fn handlea(&self, state: &mut BarActorState) { ... } async fn handleb(&self, state: &mut BarActorState, msg: BarActorMessagesB) { ... } }

let sup = FooActor{}.start(); let id = String::from("abar"); let abar = BarActor{}.start(sup, &id);

abar.send(BarActorMessages::B(true));

```

This will produce struct FooActor, enum FooActorMessages and a struct FooActorState (and similar for Bar). If you include Options they may include a sup naming the agent's supervisor and a id naming the type of actors id. The type must be Clone.

The State struct includes a tx Sender channel so that your handlers can send messages back to the actor. If the actor has a supervisor it will also include a sup_ch and an id field if it's included in options. The actor definition includes a State with extra properties they will be included in the state struct as Option initialized to None.

The macro expands message variants with propreties into corresponding struct with the propreties for easier handling in handler functions. So for Foo the macro generates a struct FooActorMessagesMsg3 but no struct FooActorMessagesMsg1 or 2 and expects you to provide FooActor::handle_msg1, FooActor::handle_msg2 and FooActor::handle_msg3. The handler functions are async and return (). All communication with the actor is done via state.tx.