yasm 0.5.0

A simple Rust state machine library focused on usability and visualization
Documentation
# YASM (Yet Another State Machine)

[![CI](https://github.com/kookyleo/yasm/workflows/CI/badge.svg)](https://github.com/kookyleo/yasm/actions)
[![codecov](https://codecov.io/github/kookyleo/yasm/graph/badge.svg?token=mtxTMfIqih)](https://codecov.io/github/kookyleo/yasm)
[![Crates.io](https://img.shields.io/crates/v/yasm.svg)](https://crates.io/crates/yasm)
[![Documentation](https://docs.rs/yasm/badge.svg)](https://docs.rs/yasm)
[![License](https://img.shields.io/crates/l/yasm.svg)](https://github.com/kookyleo/yasm#license)

A modern, efficient **deterministic** finite state machine library for Rust 2024 edition.

## โœจ Key Features

- **โšก Deterministic**: One state + input = one next state (guaranteed)
- **๐Ÿ”’ Type Safe**: Compile-time prevention of invalid transitions
- **๐Ÿš€ Callback System**: React to state changes with flexible event hooks
- **๐Ÿ”ง Macro-Driven**: Clean declarative syntax for state machine definition
- **๐Ÿ“Š Visualization**: Auto-generate Mermaid diagrams and documentation
- **๐Ÿ” Analysis Tools**: Pathfinding, reachability, and connectivity analysis
- **๐Ÿ“ˆ Memory Efficient**: Ring buffer with configurable history (default: 512)
- **๐Ÿ“ฆ Optional Serde**: Serialization support with `serde` feature

## ๐Ÿ“ฆ Installation

```toml
[dependencies]
yasm = "0.4.1"

# With serialization support
yasm = { version = "0.4.1", features = ["serde"] }
```

## ๐Ÿš€ Quick Start

### Define a State Machine

```rust
use yasm::*;

define_state_machine! {
    name: DoorStateMachine,
    states: { Closed, Open, Locked },
    inputs: { OpenDoor, CloseDoor, Lock, Unlock },
    initial: Closed,
    transitions: {
        Closed + OpenDoor => Open,
        Open + CloseDoor => Closed,
        Closed + Lock => Locked,
        Locked + Unlock => Closed
    }
}
```

### Basic Usage

```rust
fn main() {
    let mut door = StateMachineInstance::<DoorStateMachine>::new();
    
    println!("Current: {:?}", door.current_state()); // Closed
    
    door.transition(Input::OpenDoor).unwrap();
    println!("After opening: {:?}", door.current_state()); // Open
    
    // Check what's possible next
    println!("Valid inputs: {:?}", door.valid_inputs()); // [CloseDoor]
}
```

## ๐Ÿ”ฅ Core Features

### 1. Callback System

React to state machine events with flexible callback hooks:

```rust
let mut door = StateMachineInstance::<DoorStateMachine>::new();

// React to specific state entries
door.on_state_entry(State::Open, |state| {
    println!("Door opened! Turning on lights...");
});

// React to specific transitions
door.on_transition(State::Closed, Input::Lock, |from, input, to| {
    println!("Security system activated: {from:?} --{input:?}--> {to:?}");
});

// Global monitoring
door.on_any_transition(|from, input, to| {
    println!("State change: {from:?} โ†’ {to:?}");
});

// Now all transitions will trigger callbacks
door.transition(Input::OpenDoor).unwrap(); // Triggers callbacks
```

### 2. Query & Analysis

Analyze your state machine structure:

```rust
// Find reachable states
let reachable = StateMachineQuery::<DoorStateMachine>::reachable_states(&State::Closed);
println!("From Closed, can reach: {reachable:?}");

// Check connectivity
let has_path = StateMachineQuery::<DoorStateMachine>::has_path(
    &State::Open, 
    &State::Locked
);
println!("Open can reach Locked: {has_path}");

// Find shortest path
if let Some(path) = StateMachineQuery::<DoorStateMachine>::shortest_path(
    &State::Open, 
    &State::Locked
) {
    println!("Shortest path: {path:?}");
}
```

### 3. Documentation Generation

Generate visual documentation automatically:

```rust
// Mermaid state diagram
let diagram = StateMachineDoc::<DoorStateMachine>::generate_mermaid();
println!("{diagram}");

// Transition table
let table = StateMachineDoc::<DoorStateMachine>::generate_transition_table();
println!("{table}");
```

### 4. History Management

Track transitions with efficient ring buffer:

```rust
// Custom history size
let mut door = StateMachineInstance::<DoorStateMachine>::with_max_history(100);

// Make some transitions
door.transition(Input::OpenDoor).unwrap();
door.transition(Input::CloseDoor).unwrap();

// View history
println!("History: {:?}", door.history());
println!("History length: {}", door.history_len());
```

## ๐Ÿ› ๏ธ Advanced Features

### Hidden Operations

Use underscore-prefixed inputs for internal operations that won't appear in documentation:

```rust
define_state_machine! {
    name: ServerStateMachine,
    states: { Active, Maintenance },
    inputs: { Maintain, Restore, _Debug, _AdminReset }, // Hidden inputs
    initial: Active,
    transitions: {
        Active + Maintain => Maintenance,
        Maintenance + Restore => Active,
        // Hidden transitions (functional but not documented)
        Active + _Debug => Active,
        Maintenance + _AdminReset => Active
    }
}
```

### Multiple Callback Types

The callback system supports various event types:

```rust
let mut workflow = StateMachineInstance::<WorkflowStateMachine>::new();

// State-specific callbacks
workflow.on_state_entry(State::Review, |state| { /* ... */ });
workflow.on_state_exit(State::Draft, |state| { /* ... */ });

// Transition-specific callbacks  
workflow.on_transition(State::Draft, Input::Submit, |from, input, to| { /* ... */ });

// Global callbacks
workflow.on_any_state_entry(|state| { /* ... */ });
workflow.on_any_state_exit(|state| { /* ... */ });
workflow.on_any_transition(|from, input, to| { /* ... */ });

// Callback management
println!("Total callbacks: {}", workflow.callback_count());
workflow.clear_callbacks();
```

### Feature Flags

#### Serde Support

Enable with the `serde` feature for serialization:

```toml
[dependencies]
yasm = { version = "0.4.1", features = ["serde"] }
```

```rust
#[cfg(feature = "serde")]
{
    let state = State::Open;
    let json = serde_json::to_string(&state).unwrap();
    let restored: State = serde_json::from_str(&json).unwrap();
}
```

## ๐Ÿ“š Examples

Run comprehensive examples:

```bash
# Basic usage patterns
cargo run --example basic_demo

# Advanced features and analysis
cargo run --example advanced_usage

# Callback system demonstration  
cargo run --example callback_demo

# Simple callback examples
cargo run --example simple_callback_demo

# Documentation generation
cargo run --example generate_docs
```

## ๐Ÿ—๏ธ Architecture

```
src/
โ”œโ”€โ”€ lib.rs          # Public API and comprehensive tests
โ”œโ”€โ”€ core.rs         # StateMachine trait definition
โ”œโ”€โ”€ instance.rs     # StateMachineInstance with history & callbacks
โ”œโ”€โ”€ callbacks.rs    # Callback registry and event system
โ”œโ”€โ”€ query.rs        # Analysis algorithms (paths, reachability)
โ”œโ”€โ”€ doc.rs          # Documentation generation utilities
โ””โ”€โ”€ macros.rs       # define_state_machine! macro implementation
```

## ๐Ÿ”ง API Overview

### Core Types

- **`StateMachine`** - Core trait defining state machine behavior
- **`StateMachineInstance<SM>`** - Runtime instance with state and history
- **`CallbackRegistry<SM>`** - Event callback management system
- **`StateMachineQuery<SM>`** - Analysis and pathfinding utilities
- **`StateMachineDoc<SM>`** - Documentation generation tools

### Key Methods

```rust
// Instance management
let mut sm = StateMachineInstance::<MyStateMachine>::new();
let mut sm = StateMachineInstance::<MyStateMachine>::with_max_history(256);

// State operations
sm.transition(input)?;           // Execute transition
sm.current_state();              // Get current state
sm.valid_inputs();               // Get valid inputs
sm.can_accept(&input);           // Check if input is valid

// Callback registration  
sm.on_state_entry(state, callback);
sm.on_transition(from, input, callback);
sm.on_any_transition(callback);

// History access
sm.history();                    // Get transition history
sm.history_len();                // History length
sm.reset();                      // Reset to initial state

// Analysis
StateMachineQuery::<SM>::reachable_states(&from);
StateMachineQuery::<SM>::shortest_path(&from, &to);
StateMachineQuery::<SM>::has_path(&from, &to);

// Documentation
StateMachineDoc::<SM>::generate_mermaid();
StateMachineDoc::<SM>::generate_transition_table();
```

## ๐Ÿงช Testing

```bash
# Run all tests
cargo test

# Test with features
cargo test --features serde

# Test specific functionality
cargo test callbacks
```

## ๐Ÿ“„ License

MIT License. See [LICENSE](LICENSE) for details.

---

Built with โค๏ธ for the Rust community