fluent_state_machine 0.4.0

A domain-specific language (DSL) for creating state machines in Rust
Documentation
# State Machine DSL

This is a Rust project that provides a domain-specific language (DSL) for creating state machines.

## Getting Started

These instructions will get you a copy of the project up and running on your local machine for development and testing purposes.

### Prerequisites

You need to have Rust and Cargo installed on your machine. If you don't have them installed, you can get them from [here](https://www.rust-lang.org/tools/install).

### Cloning the Repository

To clone the repository, run the following command:

```sh
git clone https://github.com/hansaskov1/state_machine_dsl.git
cd state_machine_dsl
```

### Running the Project
You can run one of the three available examples [cd_player](examples/cd_player.rs),  [turnstile_enum](examples/turnstile_enum.rs), [turnstile_str](examples/turnstile_str.rs). Here is how to run the cd_player example

```sh
cargo run --example cd_player
```

### Running the Tests

You can run the tests with:

```sh
cargo test
```

## Code Examples

### Creating a Turnstile State Machine with String Literals

```rs
fn main() {
    let mut turnstyle = StateMachineBuilder::new((), "Locked")
        .state("Locked")
            .on("Coin").go_to("Unlocked")
        .state("Unlocked")
            .on("Push").go_to("Locked")
        .build().unwrap();

    turnstyle.trigger("Coin");
    println!("State: {}", turnstyle.state);
}
```

This code will print out `State: UnLocked`

### Creating a Turnstile State Machine with Enums

```rs
#[derive(Debug, Clone, Copy, PartialEq)]
enum State {
    Locked,
    UnLocked
}

#[derive(PartialEq)]
enum Event {
    Coin,
    Push,
}

fn main() {
    
    let mut turnstyle = StateMachineBuilder::new((), State::Locked)
        .state(State::Locked)
            .on(Event::Coin).go_to(State::UnLocked)
        .state(State::UnLocked)
            .on(Event::Push).go_to(State::Locked)
        .build().unwrap();

    turnstyle.trigger(Event::Coin);
    println!("State: {:?}", turnstyle.state);
}
```
This will also print out "State: UnLocked"


And here is a more complex example for a Cd-Player

```Rust 
fn main() {

    // Create store for state machine. In this case it is an integer
    let track = 0;
    
    let mut cd_player = StateMachineBuilder::new( track, "Stopped")
        .state("Stopped")
            .on("Play").go_to("Playing").only_if(|track| *track > 0 )
            .on("Forward").update(|track| *track += 1 )
            .on("Backward").update(|track| *track -= 1)
        .state("Playing")
            .on("Stop").go_to("Stopped").then(|track| *track = 0)
            .on("Pause").go_to("Paused")
        .state("Paused")
            .on("Play").go_to("Playing")
            .on("Stop").go_to("Stopped").then(|track| *track = 0)
            .on("Forward").update(|track| *track += 1)
            .on("Backward").update(|track| *track -= 1)
        .build()
        .unwrap();

    println!("Track: {}, State: {}", cd_player.store, cd_player.state);

    cd_player.trigger("Forward");
    println!("Track: {}, State: {}", cd_player.store, cd_player.state);

    cd_player.trigger("Play");
    println!("Track: {}, State: {}", cd_player.store, cd_player.state);
}
```

Running this example gives us the following output: 
"
Track: 0, State: Stopped
Track: 1, State: Stopped
Track: 1, State: Playing
"