Crate hibana
Expand description
Hibana is a Rust 2024 no_std / no-alloc-oriented runtime for affine
multiparty session types.
The crate intentionally has two faces:
- app authors use
gandEndpoint; - protocol implementors use
integrationandintegration::program.
Everything starts from one global choreography and ends in a small localside endpoint:
g choreography -> project role program -> attach endpoint -> drive localside§App path
Application code writes choreography with g and drives an endpoint that a
protocol crate has already attached.
use hibana::g;
let app = g::seq(
g::send::<g::Role<0>, g::Role<1>, g::Msg<1, u32>, 0>(),
g::send::<g::Role<1>, g::Role<0>, g::Msg<2, u32>, 0>(),
);
endpoint.flow::<g::Msg<1, u32>>()?.send(&7).await?;
let reply = endpoint.recv::<g::Msg<2, u32>>().await?;The localside API is deliberately small:
Endpoint::flowpreviews the next send, and.send(...)consumes it;Endpoint::recvreceives a deterministic message;Endpoint::offerobserves a route branch;RouteBranch::labelreports the selected choreography label;RouteBranch::decodereceives the first payload in a selected receive arm.
A route branch whose selected arm begins with a send is handled by dropping
the preview branch and then calling Endpoint::flow for that arm’s first
message.
let branch = endpoint.offer().await?;
match branch.label() {
10 => {
let value = branch.decode::<g::Msg<10, [u8; 4]>>().await?;
}
11 => {
drop(branch);
endpoint.flow::<g::Msg<11, ()>>()?.send(&()).await?;
}
_ => unreachable!(),
}§Protocol path
Protocol crates compose prefixes around an app choreography, project a role-local witness, bind transport state, and return an attached endpoint.
use hibana::{g, integration};
use hibana::integration::program::{RoleProgram, project};
let program = g::seq(transport_prefix, g::seq(appkit_prefix, app));
let role0: RoleProgram<0> = project(&program);
let mut tap_buf = [integration::runtime::TapEvent::zero(); 64];
let mut slab = [0u8; 4096];
let clock = integration::runtime::CounterClock::new();
let config = integration::runtime::Config::from_resources(
(&mut tap_buf, &mut slab),
integration::runtime::CounterClock::new(),
);
let kit = integration::SessionKit::new(&clock);
let rv = kit.add_rendezvous_from_config(config, transport)?;
let endpoint = kit
.rendezvous(rv)
.session(sid)
.role(&role0)
.enter(integration::binding::NoBinding)?;Config carries storage and clock only. Lane domain and endpoint slots are
derived from Hibana’s wire/domain limits and projected descriptors, not
chosen by callers. Operational wait fuses belong to the transport/substrate
owner and are reported by the transport instance, not passed as protocol API
or attach config.
integration::transport::Transport owns I/O readiness and wire buffers.
integration::binding owns optional demux evidence. integration::policy
owns dynamic resolver input. None of those layers become app concepts.
§Payloads and control
Payload types implement integration::wire::WireEncode for sends and
integration::wire::WirePayload for receives. Decoded values may borrow from
the received frame. Built-in exact codecs cover (), integers, bool,
byte slices, and fixed byte arrays.
Control messages are ordinary g::Msg values with a control kind. Their
shot, path, and atomic op are baked into descriptor metadata. Route, loop,
capability, and protocol-owned control messages lower into
descriptor-first control facts, and the runtime executes descriptor-baked
ControlOp values fail-closed.
§Guarantees
Hibana keeps the public API small because the projection boundary carries the proof work:
- route shape, duplicate branch labels, and controller mismatch are rejected before runtime;
- parallel composition rejects empty arms and overlapping
(role, lane)ownership; - labels are choreography identities, while transport frame labels are descriptor facts;
- endpoint progress is affine: successful
send()anddecode()consume their preview, while dropped previews restore the endpoint; EndpointErrorfails closed, carries the endpoint operation callsite, and never authorizes hidden progress.
§Features
The default feature set is empty. The optional std feature enables host
diagnostics and tests; it does not switch the core localside path to heap
ownership or change runtime semantics.
Modules§
- g
- Choreography language used by app authors.
- integration
- Protocol-neutral integration surface for protocol implementors. Protocol-neutral integration surface for protocol implementors.
Structs§
- Endpoint
- App-facing affine executor for a projected role.
- Endpoint
Error - Domain error for endpoint progress.
- Route
Branch - Preview of a selected route branch returned by
Endpoint::offer.
Type Aliases§
- Endpoint
Result - Canonical endpoint result returned by public endpoint operations.