pub enum Effect<M, I> {
Send {
to: NodeId,
msg: M,
},
Indicate(I),
SetTimer {
after: Duration,
id: TimerId,
},
}Expand description
Everything a protocol is able to do.
A protocol expresses every outward action as one of these. It does not transmit, deliver, or schedule by any other means — which is what allows the same protocol to run under a simulator and under a real driver without knowing the difference.
The two type parameters are the protocol’s own message and indication types. A timer needs
none: it is named by an opaque TimerId, and the driver hands the expiry back to whoever
registered it rather than deducing the owner from the token’s type.
Storage is not here: an effect is deferred, and a write must be durable before it returns.
See crate::store.
Variants§
Send
Transmit msg to to. Best-effort: the layer below may lose it.
Indicate(I)
Raise an indication to the layer above — the protocol delivering on its guarantee.
SetTimer
Request that id be handed back after after has elapsed.
Implementations§
Source§impl<M, I> Effect<M, I>
impl<M, I> Effect<M, I>
Sourcepub fn map<M2, I2>(
self,
msg: impl FnOnce(M) -> M2,
ind: impl FnOnce(I) -> I2,
) -> Effect<M2, I2>
pub fn map<M2, I2>( self, msg: impl FnOnce(M) -> M2, ind: impl FnOnce(I) -> I2, ) -> Effect<M2, I2>
Rewrite this effect’s parts, for a parent translating a child’s effect into its own terms.
This is the composition primitive: a parent re-wraps rather than re-encodes, so a message crossing layers accumulates type structure but is never serialised twice. A timer passes through untouched, having nothing in it that belongs to one layer.