Rust State Machine Library

Generate type-safe Rust state machines from W3C SCXML with AOT code generation. Full 202/202 W3C conformance tests passing.

State Machines in Rust

Rust's type system makes it an excellent language for implementing state machines. Enums with pattern matching provide compile-time exhaustiveness checks, and the ownership model prevents invalid state transitions at the type level. However, hand-writing complex state machines with hierarchical states, parallel regions, and history states is tedious and error-prone, even in Rust.

Existing approaches compared

Approach Pros Cons
enum + match Pure Rust, exhaustive checking Manual, no hierarchy, no parallel states
rust-fsm Derive macro, compile-time Flat states only, no standard compliance
statig Typestate pattern, zero-cost No hierarchical states, limited expressiveness
sfsm Procedural macro Simple transitions only, no parallel or history
SCE W3C standard, full hierarchy, AOT generated SCXML definition required, external code generation step

SCE takes a unique approach in the Rust ecosystem: instead of a proc macro or DSL, you define state machines in W3C SCXML (the international standard for statecharts), and SCE's code generator produces idiomatic Rust code at build time. This gives you the full power of the W3C specification -- hierarchical states, parallel regions, history, invoke, delayed events -- with type-safe generated code.

How It Works

Step 1: Define your state machine in SCXML

<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0"
       name="traffic_light" initial="red">
  <state id="red">
    <transition event="timer" target="green"/>
  </state>
  <state id="green">
    <transition event="timer" target="yellow"/>
  </state>
  <state id="yellow">
    <transition event="timer" target="red"/>
  </state>
</scxml>

Step 2: Generate Rust code

# Generate Rust state machine (-l rust or --lang rust)
sce-codegen generate traffic_light.scxml -o ./src/generated/ -l rust

The generator produces a Rust module containing a State enum, an Event enum, and a Policy struct that implements the StatePolicy trait. The Engine<P> type from sce-rust-runtime drives execution.

Step 3: Use in your Rust code

use sce_rust_runtime::Engine;
use generated::traffic_light::{TrafficLightPolicy, TrafficLightEvent, TrafficLightState};

fn main() {
    // Create the policy (generated from SCXML) and engine
    let policy = TrafficLightPolicy::new();
    let mut engine = Engine::new(policy);

    engine.initialize();                            // Enters "red" state
    engine.process_event(TrafficLightEvent::Timer);  // red -> green
    engine.process_event(TrafficLightEvent::Timer);  // green -> yellow
    engine.process_event(TrafficLightEvent::Timer);  // yellow -> red

    assert_eq!(engine.get_current_state(), TrafficLightState::Red);
}

process_event() is a convenience method that combines raise_external() + step(). For fine-grained control, use them separately:

// Low-level API: queue event, then process explicitly
engine.raise_external(TrafficLightEvent::Timer, "", "");
engine.step();

W3C SCXML Features in Rust

SCE's Rust backend passes all 202 mandatory W3C SCXML conformance tests, supporting the full specification:

Feature W3C Section Status
Compound (hierarchical) states 3.3 Supported
Parallel states 3.4 Supported
History states (shallow + deep) 3.10 Supported
ECMAScript datamodel B.2 Supported
Invoke (parent-child) 6.4 Supported
Delayed send 6.2 Supported

Why SCXML for Rust?

Using W3C SCXML instead of a Rust-specific DSL provides several advantages for Rust projects:

Comparison with Rust State Machine Crates

Feature enum+match rust-fsm statig SCE
Hierarchical states Manual No No Yes
Parallel states Manual No No Yes
History states Manual No No Yes
Guarded transitions Manual No Yes Yes
Delayed events Manual No No Yes
Standard compliance None None None W3C SCXML 1.0
Cross-language No No No C++, Kotlin, Rust, Go
Visual tooling No No No Browser visualizer

Getting Started

# Clone the repository
git clone --recursive https://github.com/newmassrael/scxml-core-engine.git
cd scxml-core-engine

# Generate Rust state machine from SCXML
sce-codegen generate your_machine.scxml -o ./src/generated/ -l rust

# Run the Rust W3C test suite
cargo test -p sce-rust-tests

The Rust runtime (sce-rust-runtime/) provides the Engine<P> type and StatePolicy trait. Test infrastructure is in sce-rust-tests/. The code generator produces standalone Rust modules that depend only on the runtime crate.