Expand description
§DETCORE — Deterministic Logic Core
Minimal no_std deterministic state machine engine for Rust.
Single dependency (heapless).
DETCORE is a generic state machine engine where Logic::step is a
pure function: same state + same event = same output, always. All
arithmetic is integer-only (i64 fixed-point), time is injected
externally, and the command buffer is stack-allocated with a fixed
capacity.
Intended for embedded controllers, deterministic simulations, and systems where reproducibility matters.
Not a scheduler, async runtime, event bus, or distributed system.
§Architecture
The engine processes events through a pure transition function and produces bounded command output:
Event(seq, ts, payload)
│
▼
Engine::process
├── validate seq > last_seq (monotonic ordering)
├── Logic::step(state, event, commands) (pure transition)
└── check_invariants() (post-condition)
│
▼
Vec<Command<C>, 16> (bounded, stack-allocated)- Deterministic: no system clock, no randomness, no heap
- Fixed-point arithmetic:
Decimal = i64,SCALE = 1_000_000 - Monotonic sequencing: events rejected if
seqis not strictly increasing - Invariant checking:
State::check_invariants()runs after every transition - Bounded output:
heapless::Vec<_, 16>— no allocation, no overflow panic
§Quick Start
use detcore::{Engine, Logic, Event, Command, State, Seq, Timestamp, Vec, SCALE};
#[derive(Clone)]
struct PumpState { pressure: i64, last_seq: Seq }
impl State for PumpState {
fn check_invariants(&self) -> bool { self.pressure >= 0 }
fn last_seq(&self) -> Seq { self.last_seq }
fn set_last_seq(&mut self, seq: Seq) { self.last_seq = seq }
}
#[derive(Clone, Copy)]
enum PumpEvent { PressureUpdate(i64) }
#[derive(Clone, PartialEq, Eq)]
enum PumpCommand { StopPump }
struct PumpLogic;
impl Logic<PumpState, PumpEvent, PumpCommand> for PumpLogic {
fn step(state: &mut PumpState, event: Event<PumpEvent>, commands: &mut Vec<Command<PumpCommand>, 16>) {
match event.payload {
PumpEvent::PressureUpdate(p) => {
state.pressure = p;
if p > 100 * SCALE {
let _ = commands.push(Command::Emit(PumpCommand::StopPump));
}
}
}
}
}
let mut engine = Engine::<PumpState, PumpLogic, PumpEvent, PumpCommand>::new(
PumpState { pressure: 0, last_seq: Seq(0) },
);
let commands = engine.process(Event {
seq: Seq(1), ts: Timestamp(0),
payload: PumpEvent::PressureUpdate(120 * SCALE),
});
assert_eq!(commands.len(), 1);§Safety Modes
| Mode | Behavior |
|---|---|
| Default (debug) | debug_assert! on seq violation and invariant failure |
--features strict | assert! in release builds — panics on any violation |