rings_node/extension/ext/interpret.rs
1//! The imperative shell of an extension: [`Interpret`] runs a protocol's **own** effects.
2//!
3//! Each extension registers a `(Protocol, Interpret)` pair. The interpreter is the only
4//! place IO happens for that extension; it is handed a **namespace-scoped** capability
5//! ([`EffectScope`](super::EffectScope)) — overlay `send` and `did`, confined to the
6//! interpreter's own namespace. An extension that owns OS resources (e.g. the relay's sockets)
7//! receives a lifecycle scope explicitly for its long-lived tasks, so the core never depends on
8//! transport internals.
9
10use bytes::Bytes;
11
12use super::EffectScope;
13use crate::error::Result;
14
15/// Runs the effects produced by a protocol's pure `step`. `run` returns the payloads to
16/// re-inject into the router; each is re-delivered to **this** protocol's own namespace with
17/// `from = this node` — the router sets the provenance, so a shell can forge neither a
18/// namespace nor a remote `from`. A hard failure is an `Err`. Defined per-effect outcomes (e.g.
19/// "addressed no live session") are the extension's own concern and surfaced however it likes
20/// (its own return shapes / tests), not a core enum.
21#[cfg_attr(rings_browser, async_trait::async_trait(?Send))]
22#[cfg_attr(rings_native, async_trait::async_trait)]
23pub trait Interpret {
24 /// The effect algebra this shell interprets — the same as its protocol's `Effect`.
25 type Effect;
26
27 /// Run one effect against the scoped capability, returning self-injected payloads (each
28 /// re-decoded by this same protocol).
29 ///
30 /// The state transition is committed before this method starts. Effects are attempted in
31 /// their transition order; an `Err` stops the current transition's remaining effects and
32 /// does not roll state back. A protocol that needs retry or compensation therefore models it
33 /// as a later typed event/transition, rather than relying on an interpreter retry.
34 async fn run(&self, scope: &EffectScope, effect: Self::Effect) -> Result<Vec<Bytes>>;
35}