handler

Macro handler 

Source
handler!() { /* proc-macro */ }
Expand description

Define a handler for an effect or group of effects.

§Usage

Handling a group of effects at once:

let mut state = 0i32;
handle_group(
    g,
    handler! {
        State<i32> {
            get() => state,
            put(v) => state = v,
        }
    }
)

Handling a single effect at once:

handle(g, handler!(Cancel => break))

The value that a handler arm’s expression evaluates to (for example state and () in the State<i32> example) is used as the injection for that effect. It is also possible to use the break keyword to cause the computation that is being handled to return. In this case, the type of the value passed to break must match the return type of a computation that the handler is used on. See effing_mad::map for a way to change the return value of a computation.

The handler can capture state from its environment, and/or be asynchronous. The keywords async and move can both optionally appear (in that order) at the very beginning of the macro input to control these behaviours, in a similar way to how they would affect a closure. These keywords apply to all arms of the handler. handle_async or handle_group_async must be used when applying an async handler.

Note that the put arm in this example mutably borrows the state variable, while the get arm also borrows it. This is the advantage of handling effects together. Internally, handler! expands to a single closure with a match expression in it, so the arms can all borrow the same content, even mutably.