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.