indexbus_core/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2#![deny(unreachable_pub, rust_2018_idioms)]
3#![deny(missing_docs)]
4
5//! Core IndexBus algorithms built on top of the v1 ABI layouts.
6//!
7//! This crate provides safe(ish) APIs for initializing and operating on the shared-memory
8//! layouts defined in `indexbus-abi`.
9//!
10//! - Layout structs live in `indexbus-abi` (Rust source of truth; C headers generated).
11//! - This crate provides algorithms and handles (SPSC/MPSC events, fanout router, state stream).
12//!
13//! ## Safety model
14//!
15//! Handles in this crate are thin wrappers around raw pointers to ABI layouts (typically
16//! memory-mapped shared memory). They are "safe" to call in the Rust sense only if you uphold
17//! the contracts documented on each type:
18//!
19//! - The mapped layout must outlive all handles derived from it.
20//! - You must not concurrently call APIs that require single-threaded access (most handles are
21//!   intentionally not `Sync`).
22//! - Mappings should be validated with [`validate_shared_layout`], [`validate_fanout_layout`],
23//!   [`validate_state_layout`], etc. before use (especially across process boundaries).
24//!
25//! ## Minimal SPSC example
26//!
27//! ```
28//! use indexbus_core::{init_shared_layout, split_spsc, SharedLayoutCell};
29//! use indexbus_abi::layouts::SharedLayout;
30//!
31//! // SharedLayout is large; allocate it on the heap to avoid huge stack frames.
32//! let mut shared: Box<SharedLayout> = Box::new(unsafe { core::mem::zeroed() });
33//! init_shared_layout(&mut shared);
34//! let cell = SharedLayoutCell::from_mut(&mut shared);
35//! let (tx, rx) = split_spsc(cell).unwrap();
36//!
37//! tx.publish(b"hi").unwrap();
38//! let mut out = [0u8; 256];
39//! let n = rx.try_recv_into(&mut out).unwrap().unwrap();
40//! assert_eq!(&out[..n], b"hi");
41//! ```
42
43#[cfg(feature = "std")]
44extern crate std;
45
46mod constants;
47mod errors;
48mod events;
49mod events_chain;
50mod fanout;
51/// State-stream publisher/reader algorithms.
52pub mod state;
53pub mod validate;
54mod wait;
55
56mod internal;
57
58pub use constants::*;
59pub use errors::{Error, PublishWithError, RecvWithError};
60pub use events::{
61    init_shared_layout, init_shared_layout_with_layout_bytes, split_mpsc, split_spsc, EventsSlot,
62    MpscConsumer, MpscProducer, PublishSlotError, SharedLayoutCell, SpscReceiver, SpscSender,
63};
64pub use events_chain::{
65    split_chain_mpsc, split_chain_spsc, ChainMpscConsumer, ChainMpscProducer, ChainSpscReceiver,
66    ChainSpscSender,
67};
68pub use fanout::{
69    fanout_handles, fanout_mpsc_producer, init_shared_fanout_layout,
70    init_shared_fanout_layout_with_layout_bytes, FanoutConsumer, FanoutMpscProducer,
71    FanoutProducer, FanoutRouter, RouteOnceResult, RouterMode, RouterSource,
72    SharedFanoutLayoutCell,
73};
74pub use state::{StateLayoutCell, StatePublisher, StateReader};
75pub use validate::{
76    validate_fanout_layout, validate_journal_layout4, validate_sequencer_layout,
77    validate_shared_layout, validate_state_layout,
78};
79pub use wait::{SpinWait, WaitStrategy};
80
81#[cfg(feature = "std")]
82pub use wait::{StdBackoff, YieldWait};
83
84/// Curated prelude for downstream users.
85pub mod prelude {
86    pub use crate::{
87        fanout_handles, fanout_mpsc_producer, init_shared_fanout_layout,
88        init_shared_fanout_layout_with_layout_bytes, init_shared_layout,
89        init_shared_layout_with_layout_bytes, split_chain_spsc, split_mpsc, split_spsc,
90        validate_fanout_layout, validate_shared_layout, validate_state_layout, ChainSpscReceiver,
91        ChainSpscSender, Error, EventsSlot, FanoutConsumer, FanoutMpscProducer, FanoutProducer,
92        FanoutRouter, MpscConsumer, MpscProducer, PublishSlotError, RouteOnceResult, RouterMode,
93        RouterSource, SharedFanoutLayoutCell, SharedLayoutCell, SpinWait, SpscReceiver, SpscSender,
94        StateLayoutCell, StatePublisher, StateReader, WaitStrategy,
95    };
96}