Skip to main content

Crate nexus_rt

Crate nexus_rt 

Source
Expand description

§nexus-rt

Runtime primitives for single-threaded, event-driven systems.

nexus-rt provides the building blocks for constructing runtimes where user code runs as handlers dispatched over shared state. It is not an async runtime — there is no task scheduler, no work stealing, no Future polling. Instead, it provides:

  • WorldWorld is a unified type-erased singleton store. Each registered type gets a direct pointer (ResourceId) — dispatch-time access is a single pointer deref with zero framework overhead.

  • ResourcesRes and ResMut are what users see in handler function signatures. They deref to the inner value transparently.

  • Handlers — The Param trait resolves state at build time and produces references at dispatch time. IntoHandler converts plain functions into Handler trait objects for type-erased dispatch.

  • PipelinePipelineBuilder begins a typed per-event composition chain. Steps transform data using Option and Result for flow control. Pipeline implements Handler for direct or boxed dispatch. BatchPipeline owns a pre-allocated input buffer and runs each item through the same chain independently — errors on one item don’t affect subsequent items.

  • DAG PipelineDagBuilder builds a monomorphized data-flow graph with fan-out and merge. Topology is encoded in the type system — no vtable dispatch, no arena allocation. Dag implements Handler for direct or boxed dispatch. BatchDag owns a pre-allocated input buffer and runs each item through the same DAG independently.

  • InstallerInstaller is the install-time trait for event sources. install() registers resources into WorldBuilder and returns a concrete poller whose poll() method drives the event lifecycle.

  • TemplatesHandlerTemplate and CallbackTemplate resolve parameters once, then stamp out handlers via generate() by copying pre-resolved state (a single memcpy). Use when handlers are created repeatedly on the hot path (IO re-registration, timer rescheduling).

  • PluginPlugin is a composable unit of resource registration. WorldBuilder::install_plugin consumes a plugin to configure state. Closures FnOnce(&mut WorldBuilder) implement Plugin automatically.

  • Reactors (feature: reactors) — Interest-based per-instance dispatch. Event handlers call ReactorNotify::mark to signal data changes. Subscribed reactors wake with O(1) dedup — per-instrument, per-strategy granularity. Replaces per-resource change detection with explicit, fine-grained notification. SourceRegistry maps domain keys to data sources for runtime routing.

  • Derive macros#[derive(Resource)] marks types for World storage. #[derive(Param)] bundles multiple resources into a single handler parameter (sidesteps the 8-param arity limit). #[derive(Deref, DerefMut)] provides newtype ergonomics. new_resource! is a shorthand for newtype + Resource + Deref + From.

§Quick Start

use nexus_rt::{WorldBuilder, ResMut, IntoHandler, Handler, Resource};

#[derive(Resource)]
struct Counter(u64);

let mut builder = WorldBuilder::new();
builder.register(Counter(0));
let mut world = builder.build();

fn tick(mut counter: ResMut<Counter>, event: u32) {
    counter.0 += event as u64;
}

let mut handler = tick.into_handler(world.registry());

handler.run(&mut world, 10u32);

assert_eq!(world.resource::<Counter>().0, 10);

§Safety

The low-level get / get_mut methods on World are unsafe and intended for framework internals. The caller must ensure:

  1. The ID was obtained from the same builder that produced the container.
  2. The type parameter matches the type registered at that ID.
  3. No mutable aliasing — at most one &mut T exists per value at any time.

User-facing APIs (resource, resource_mut, Handler::run) are fully safe.

§Returning impl Handler from functions (Rust 2024)

In Rust 2024, impl Trait in return position captures all in-scope lifetimes by default. If a function takes &Registry and returns impl Handler<E>, the returned type captures the registry borrow — blocking subsequent WorldBuilder calls.

Add + use<...> to list only the type parameters the return type holds. The &Registry is consumed during build — it is not retained:

use nexus_rt::{Handler, PipelineBuilder, Res, ResMut};
use nexus_rt::world::Registry;

fn on_order<C: Config>(
    reg: &Registry,
) -> impl Handler<Order> + use<C> {
    PipelineBuilder::<Order>::new()
        .then(validate::<C>, reg)
        .dispatch(submit::<C>.into_handler(reg))
        .build()
}

Without + use<C>, the compiler assumes the return type borrows reg, and subsequent wb.install_driver(...) / wb.build() calls fail with a borrow conflict.

This applies to any factory function pattern — pipelines, DAGs, handlers, callbacks, and templates. List every type parameter the return type captures; omit the &Registry lifetime.

§Bevy Analogies

nexus-rt borrows heavily from Bevy ECS’s system model. If you know Bevy, these mappings may help:

nexus-rtBevyNotes
ParamSystemParamTwo-phase init/fetch
Res<T>Res<T>Shared resource read
ResMut<T>ResMut<T>Exclusive resource write
Local<T>Local<T>Per-handler state
Handler<E>System traitObject-safe dispatch
IntoHandlerIntoSystemfn → handler conversion
PluginPluginComposable registration
WorldWorldSingletons only (no ECS)
HandlerTemplate(no equivalent)Resolve-once, stamp-many
ReactorNotifyObserver (partial)Interest-based per-instance dispatch

Re-exports§

pub use dag::BatchDag;
pub use dag::Dag;
pub use dag::DagBuilder;
pub use dag::resolve_arm;
pub use reactor::DataSource;
pub use reactor::DeferredRemovals;
pub use reactor::IntoReactor;
pub use reactor::PipelineReactor;
pub use reactor::Reactor;
pub use reactor::ReactorFn;
pub use reactor::ReactorNotify;
pub use reactor::ReactorRegistration;
pub use reactor::ReactorSystem;
pub use reactor::SourceRegistry;
pub use ctx_dag::CtxDag;
pub use ctx_dag::CtxDagArm;
pub use ctx_dag::CtxDagArmFork;
pub use ctx_dag::CtxDagArmSeed;
pub use ctx_dag::CtxDagBuilder;
pub use ctx_dag::CtxDagChain;
pub use ctx_dag::CtxDagChainFork;
pub use ctx_pipeline::CtxPipeline;
pub use ctx_pipeline::CtxPipelineBuilder;
pub use ctx_pipeline::CtxPipelineChain;
pub use ctx_pipeline::IntoCtxProducer;
pub use ctx_pipeline::IntoCtxRefStep;
pub use ctx_pipeline::IntoCtxStep;
pub use ctx_pipeline::resolve_ctx_step;
pub use pipeline::BatchPipeline;
pub use pipeline::IntoProducer;
pub use pipeline::IntoRefScanStep;
pub use pipeline::IntoRefStep;
pub use pipeline::IntoScanStep;
pub use pipeline::Pipeline;
pub use pipeline::PipelineBuilder;
pub use pipeline::PipelineChain;
pub use pipeline::PipelineOutput;
pub use pipeline::resolve_producer;
pub use pipeline::resolve_ref_scan_step;
pub use pipeline::resolve_ref_step;
pub use pipeline::resolve_scan_step;
pub use pipeline::resolve_step;
pub use scheduler::MAX_SYSTEMS;
pub use scheduler::SchedulerInstaller;
pub use scheduler::SystemId;
pub use scheduler::SystemScheduler;
pub use shutdown::Shutdown;
pub use shutdown::ShutdownHandle;
pub use system::IntoSystem;
pub use system::System;
pub use system::SystemFn;
pub use template::Blueprint;
pub use template::CallbackBlueprint;
pub use template::CallbackTemplate;
pub use template::HandlerTemplate;
pub use template::TemplatedCallback;
pub use template::TemplatedHandler;
pub use self::mio::BoxedMio;
pub use self::mio::MioConfig;
pub use self::mio::MioDriver;
pub use self::mio::MioInstaller;
pub use self::mio::MioPoller;
pub use self::mio::FlexMio;
pub use self::mio::InlineMio;
pub use timer::BoundedTimerInstaller;
pub use timer::BoundedTimerPoller;
pub use timer::BoundedTimerWheel;
pub use timer::BoxedTimers;
pub use timer::Periodic;
pub use timer::TimerConfig;
pub use timer::TimerInstaller;
pub use timer::TimerPoller;
pub use timer::TimerWheel;
pub use timer::BoundedFlexTimerWheel;
pub use timer::BoundedInlineTimerWheel;
pub use timer::FlexTimerWheel;
pub use timer::FlexTimers;
pub use timer::InlineTimerWheel;
pub use timer::InlineTimers;

Modules§

clock
Clock abstractions for event-driven runtimes. Clock abstractions for event-driven runtimes.
codegen_audit
Assembly audit harness for verifying codegen quality.
ctx_dag
Context-aware DAG dispatch.
ctx_pipeline
Context-aware pipeline dispatch.
dag
DAG pipeline — monomorphized data-flow graphs with fan-out and merge.
mio
Mio IO driver for nexus-rt.
pipeline
Pre-resolved pipeline dispatch using Param steps.
reactor
Reactor dispatch system with interest-based notification.
scheduler
DAG scheduler with boolean propagation.
shutdown
Cooperative shutdown for event loops.
system
Reconciliation systems with boolean propagation.
template
Resolve-once, stamp-many handler templates.
testing
Testing utilities for nexus-rt handlers and timer drivers.
timer
Timer driver for nexus-rt.

Macros§

callback_blueprint
Declares a callback CallbackBlueprint key struct.
fan_out
Constructs a FanOut combinator from 2-8 handlers.
handler_blueprint
Declares a handler Blueprint key struct.
new_resource
Declare a newtype resource with Deref/DerefMut to the inner type.
select
Compile-time dispatch table for pipeline/DAG steps — the nexus-rt analogue of tokio’s select!.

Structs§

Adapt
Lightweight adapter that decodes a wire-format event into a domain type before dispatching to an inner handler.
BoundedWheelBuilder
Terminal builder for a bounded timer wheel.
Broadcast
Dynamic fan-out combinator. Takes ownership of an event, borrows it, and dispatches &E to N handlers, where N is determined at runtime.
ByRef
Owned-to-reference adapter. Wraps a Handler<&E> and implements Handler<E> — the event is borrowed before dispatch.
Callback
Unified dispatch type. Stores per-callback context alongside pre-resolved resource access.
CatchAssertUnwindSafe
Panic-catching wrapper for Handler implementations.
Cloned
Reference-to-owned adapter. Wraps a Handler<E> and implements Handler<&E> — the event is cloned before dispatch.
FanOut
Static fan-out combinator. Takes ownership of an event, borrows it, and dispatches &E to N handlers.
Full
Error returned when a bounded allocator is full.
Local
Per-handler local state. Stored inside the dispatch wrapper (e.g. Callback or pipeline step), not in World.
Opaque
Marker occupying the Params position in step and handler traits to indicate that a closure manages its own resource access via world.resource::<T>() rather than through Param resolution.
OpaqueHandler
Wrapper for closures that receive &mut World directly as a Handler.
Owned
Reference-to-owned adapter via ToOwned. Wraps a Handler<E::Owned> and implements Handler<&E> — the event is converted via to_owned() before dispatch.
Registry
Type-to-pointer mapping shared between WorldBuilder and World.
RegistryRef
Read-only access to the Registry during handler dispatch.
Res
Shared reference to a resource in World.
ResMut
Mutable reference to a resource in World.
Resolved
Marker type for handlers whose parameters are already resolved.
ResourceId
Direct pointer identifying a resource within a World container.
Seq
Read-only access to the world’s current sequence number.
SeqMut
Mutable access to the world’s current sequence number.
Sequence
Monotonic event sequence number for event ordering.
TimerHandle
Handle to a scheduled timer.
UnboundedWheelBuilder
Terminal builder for an unbounded timer wheel.
ViewScope
Builder for steps inside a .view::<V>() scope.
WheelBuilder
Builder for configuring a timer wheel.
WheelEntry
Timer wheel entry stored inside a slab slot.
World
Frozen singleton resource storage.
WorldBuilder
Builder for registering resources before freezing into a World container.

Traits§

Handler
Object-safe dispatch trait for event handlers.
Installer
Install-time trait for event sources.
IntoCallback
Converts a named function into a Callback.
IntoHandler
Converts a plain function into a Handler.
Param
Trait for types that can be resolved from a Registry at build time and fetched from World at dispatch time.
Plugin
Composable unit of resource registration.
Resource
Marker trait for types that can be stored in a World.
View
Associates a source type with a projected view via a marker.

Type Aliases§

BoundedWheel
A timer wheel backed by a fixed-capacity slab.
FlatVirtual
Type alias for an inline Handler using nexus_smartptr::Flat.
FlexVirtual
Type alias for an inline Handler with heap fallback using nexus_smartptr::Flex.
HandlerFn
Type alias for context-free handlers (no owned context).
Virtual
Type alias for a boxed, type-erased Handler.
Wheel
A timer wheel backed by a growable slab.

Derive Macros§

Deref
Derive Deref for newtype wrappers.
DerefMut
Derive DerefMut for newtype wrappers.
Param
Derive the Param trait for a struct, enabling it to be used as a grouped handler parameter.
Resource
Derive the Resource marker trait, allowing this type to be stored in a World.
View
Derive a View projection for use with pipeline .view() scopes.