nexus_rt/lib.rs
1//! # nexus-rt
2//!
3//! Runtime primitives for single-threaded, event-driven systems.
4//!
5//! `nexus-rt` provides the building blocks for constructing runtimes where
6//! user code runs as handlers dispatched over shared state. It is **not** an
7//! async runtime — there is no task scheduler, no work stealing, no `Future`
8//! polling. Instead, it provides:
9//!
10//! - **World** — [`World`] is a unified type-erased singleton store. Each
11//! registered type gets a dense index ([`ResourceId`]) for ~3-cycle
12//! dispatch-time access.
13//!
14//! - **Resources** — [`Res`] and [`ResMut`] are what users see in handler
15//! function signatures. They deref to the inner value transparently.
16//!
17//! - **Handlers** — The [`SystemParam`] trait resolves state at build time
18//! and produces references at dispatch time. [`IntoHandler`] converts
19//! plain functions into [`Handler`] trait objects for type-erased dispatch.
20//!
21//! - **Pipeline** — [`PipelineStart`] begins a typed per-event composition
22//! chain. Stages transform data using `Option` and `Result` for flow
23//! control. [`Pipeline`] implements [`Handler`] for direct or boxed dispatch.
24//! [`BatchPipeline`] owns a pre-allocated input buffer and runs each item
25//! through the same chain independently — errors on one item don't affect
26//! subsequent items.
27//!
28//! - **Driver** — [`Driver`] is the install-time trait for event sources.
29//! `install()` registers resources into [`WorldBuilder`] and returns a
30//! concrete handle whose `poll()` method drives the event lifecycle.
31//!
32//! - **Plugin** — [`Plugin`] is a composable unit of resource registration.
33//! [`WorldBuilder::install_plugin`] consumes a plugin to configure state.
34//!
35//! # Quick Start
36//!
37//! ```
38//! use nexus_rt::{WorldBuilder, ResMut, IntoHandler, Handler};
39//!
40//! let mut builder = WorldBuilder::new();
41//! builder.register::<u64>(0);
42//! let mut world = builder.build();
43//!
44//! fn tick(mut counter: ResMut<u64>, event: u32) {
45//! *counter += event as u64;
46//! }
47//!
48//! let mut handler = tick.into_handler(world.registry_mut());
49//!
50//! handler.run(&mut world, 10u32);
51//!
52//! assert_eq!(*world.resource::<u64>(), 10);
53//! ```
54//!
55//! # Safety
56//!
57//! The low-level `get` / `get_mut` methods on [`World`] are `unsafe` and
58//! intended for framework internals. The caller must ensure:
59//!
60//! 1. The ID was obtained from the same builder that produced the container.
61//! 2. The type parameter matches the type registered at that ID.
62//! 3. No mutable aliasing — at most one `&mut T` exists per value at any time.
63//!
64//! User-facing APIs (`resource`, `resource_mut`, `Handler::run`) are fully safe.
65
66#![warn(missing_docs)]
67
68mod callback;
69mod driver;
70pub mod pipeline;
71mod plugin;
72mod resource;
73mod system;
74mod world;
75
76pub use callback::{Callback, IntoCallback};
77pub use driver::Driver;
78pub use pipeline::{
79 BatchPipeline, IntoStage, Pipeline, PipelineBuilder, PipelineOutput, PipelineStart,
80};
81pub use plugin::Plugin;
82pub use resource::{Res, ResMut};
83pub use system::{CtxFree, Handler, HandlerFn, IntoHandler, Local, SystemParam};
84pub use world::{Registry, ResourceId, Sequence, World, WorldBuilder};
85
86/// Type alias for a boxed, type-erased [`Handler`].
87pub type Virtual<E> = Box<dyn Handler<E>>;
88
89/// Type alias for an inline [`Handler`] using [`nexus_smartptr::Flat`].
90///
91/// Stores the handler inline (no heap allocation). Panics if the concrete
92/// handler doesn't fit in the buffer.
93#[cfg(feature = "smartptr")]
94pub type FlatVirtual<E, B = nexus_smartptr::B64> = nexus_smartptr::Flat<dyn Handler<E>, B>;
95
96/// Type alias for an inline [`Handler`] with heap fallback using [`nexus_smartptr::Flex`].
97///
98/// Stores inline if the handler fits, otherwise heap-allocates.
99#[cfg(feature = "smartptr")]
100pub type FlexVirtual<E, B = nexus_smartptr::B64> = nexus_smartptr::Flex<dyn Handler<E>, B>;