Mindset
A zero-cost, effect-based state machine library for Rust.
Overview
Mindset provides a flexible and type-safe state machine implementation that separates pure guard logic from effectful actions. Built on Stillwater 0.11.0's effect system, it enables you to write state machines that are:
- Zero-cost by default: No runtime overhead when effects aren't needed
- Explicitly effectful: Side effects are opt-in and clearly marked
- Highly testable: Pure guards and dependency injection via environment traits
- Type-safe: Compile-time guarantees about state transitions
Features
- Pure Guard Functions: Deterministic state validation with no side effects
- Effectful Actions: Explicit I/O and side effects when needed
- Environment Pattern: Clean dependency injection for testing
- Zero-Cost Abstractions: Pay only for what you use
- Composable Effects: Build complex behavior from simple trait combinations
Quick Start
Simple State Machine (Zero Cost)
use ;
Effectful State Machine
use ;
// Define environment capabilities as traits
// Pure guard - no side effects
// Effectful action - explicit environment usage
Architecture
Core Design Principles
-
Pure Guards, Effectful Actions
- Guards are pure functions that validate state transitions
- Actions perform side effects and state changes
- Clear separation enables testing and reasoning
-
Zero-Cost by Default
- No effects means no runtime overhead
- Effects are opt-in via explicit environment parameters
- Compiler optimizes away unused abstractions
-
Environment Pattern
- Dependencies expressed as trait bounds
- Compose environments from multiple traits
- Easy mocking for tests
-
Explicit Over Implicit
- Side effects are visible in function signatures
- No hidden global state or implicit context
- Clear data flow
State Machine Model
A state machine in Mindset consists of:
- States: Enum variants representing discrete system states
- Transitions: Allowed moves between states
- Guards: Pure functions determining if transition is allowed
- Actions: Effectful functions executed during transition
- Environment: External dependencies and services
Effect-Based Transition Model
Transitions come in two flavors:
Pure Transitions (Zero Cost)
machine.transition;
Compiles to direct state updates with no runtime overhead.
Effectful Transitions
machine.transition_with_effect;
Effects are explicit via environment parameter. Only pay for what you use.
Examples
Run any example with cargo run --example <name>:
| Example | Demonstrates |
|---|---|
| basic_state_machine | Zero-cost state machine with pure transitions |
| effectful_state_machine | Environment pattern and effectful actions |
| testing_patterns | Testing with mock environments |
| traffic_light | Simple cyclic state machine |
| document_workflow | Multi-stage approval workflow |
| order_processing | E-commerce order lifecycle |
| account_management | Account states with validation |
| checkpoint_resume | Checkpoint and resume patterns |
| mapreduce_workflow | MapReduce workflow implementation |
| resource_management | Resource lifecycle management |
See examples/ directory for full code and examples/README.md for detailed explanations.
Usage Examples
Example 1: Traffic Light
use state_enum;
use ;
state_enum!
let machine = new
.initial
.transitions
.build
.unwrap;
Example 2: Document Workflow with Logging
use state_enum;
use ;
state_enum!
let machine = new
.initial
.add_transition
.add_transition
.build
.unwrap;
Example 3: State Machine with Validation
Testing
The environment pattern makes testing straightforward:
Performance
Zero-Cost Pure Transitions
Pure transitions have zero runtime overhead. This code:
machine.transition;
Compiles to the same assembly as:
state = B;
Effect Cost Model
Effects only cost what you use:
- No effects: Zero overhead (direct state update)
- Single trait: Monomorphized static dispatch (zero-cost abstraction)
- Multiple traits: One vtable lookup per trait (if using trait objects)
- Environment mutation: Direct field access
Benchmarks
On a typical modern CPU:
- Pure transition: ~0.5ns (equivalent to direct assignment)
- Single-effect transition: ~2-3ns (includes function call overhead)
- Multi-effect transition: ~5-10ns (depends on effect complexity)
Checkpoint and Resume
Mindset includes built-in checkpoint and resume functionality for long-running MapReduce workflows. This allows workflows to be paused and resumed without losing progress, making the system resilient to interruptions.
Key Features
- Automatic Checkpointing: Workflows automatically save progress at key phases (map completion, reduce rounds)
- Serialization Formats: Support for both JSON (human-readable) and binary (compact) formats
- Atomic Writes: Checkpoint writes use atomic file operations to prevent corruption
- Resume from Interruption: Seamlessly continue workflows after crashes, stops, or planned maintenance
Use Cases
Long-running workflows benefit from checkpointing when:
- Processing large datasets that take hours or days
- Running on infrastructure that may experience interruptions
- Needing to pause workflows during high-demand periods
- Debugging or inspecting intermediate workflow state
- Optimizing costs by pausing during expensive compute periods
Quick Example
# Start a workflow
# Workflow saves checkpoints automatically...
# Interrupt with Ctrl+C or system failure
# Resume from checkpoint
# Workflow continues from where it left off
Learn More
For detailed documentation on checkpoint structure, resume behavior, best practices, and atomic write patterns, see the Checkpointing Guide.
Documentation
- Builder Guide: Comprehensive guide to the builder API with examples and patterns
- Checkpointing Guide: Checkpoint and resume for long-running workflows
- Effects Guide: Comprehensive guide to effect patterns
- API Documentation: Generated API docs
Design Philosophy
Functional Core, Imperative Shell
- Pure core: Business logic and guards are pure functions
- Effectful shell: I/O and side effects at the boundaries
- Clear separation enables testing and reasoning
Pay Only for What You Use
- Zero-cost when effects aren't needed
- Explicit opt-in for effects
- No hidden overhead or runtime costs
Explicit Over Implicit
- Side effects visible in function signatures
- Environment dependencies declared as trait bounds
- No magic or hidden behavior
Testability First
- Pure functions are trivial to test
- Mock environments for integration testing
- Clear dependency injection
Project Status
This library implements the effect-based state machine foundation as specified in:
- Spec 001: Core state machine with pure guards
- Spec 002: Effect-based transitions with environment pattern
- Spec 004: Checkpoint and resume for persistence
- Spec 005: Builder API for ergonomic construction
Contributing
Contributions are welcome! Please ensure:
- All tests pass
- Code follows project conventions
- Documentation is updated
- Commit messages are clear and descriptive
License
[License information to be added]