tinystate 0.1.1

Fast and tiny finite state machine
Documentation
use tinystate::Events;
use tinystate::StateMachineBuilder;
use tinystate::States;

#[derive(Debug, PartialEq, States)]
enum VendingState {
    Idle,
    Has25Cents,
    Has50Cents,
    Has75Cents,
    ReadyToDispense,
    Dispensing,
}

#[derive(Debug, Events)]
enum VendingEvent {
    Insert25Cents,
    Insert50Cents,
    SelectItem,
    Cancel,
    DispenseComplete,
}

fn main() {
    let mut machine = StateMachineBuilder::<VendingState, VendingEvent, 6, 5>::new()
        .initial(VendingState::Idle)
        .transition(
            VendingState::Idle,
            VendingEvent::Insert25Cents,
            VendingState::Has25Cents,
        )
        .transition(
            VendingState::Idle,
            VendingEvent::Insert50Cents,
            VendingState::Has50Cents,
        )
        .self_loop(VendingState::Idle, VendingEvent::SelectItem)
        .self_loop(VendingState::Idle, VendingEvent::Cancel)
        .self_loop(VendingState::Idle, VendingEvent::DispenseComplete)
        .transition(
            VendingState::Has25Cents,
            VendingEvent::Insert25Cents,
            VendingState::Has50Cents,
        )
        .transition(
            VendingState::Has25Cents,
            VendingEvent::Insert50Cents,
            VendingState::Has75Cents,
        )
        .self_loop(VendingState::Has25Cents, VendingEvent::SelectItem)
        .transition(
            VendingState::Has25Cents,
            VendingEvent::Cancel,
            VendingState::Idle,
        )
        .self_loop(VendingState::Has25Cents, VendingEvent::DispenseComplete)
        .transition(
            VendingState::Has50Cents,
            VendingEvent::Insert25Cents,
            VendingState::Has75Cents,
        )
        .transition(
            VendingState::Has50Cents,
            VendingEvent::Insert50Cents,
            VendingState::ReadyToDispense,
        )
        .self_loop(VendingState::Has50Cents, VendingEvent::SelectItem)
        .transition(
            VendingState::Has50Cents,
            VendingEvent::Cancel,
            VendingState::Idle,
        )
        .self_loop(VendingState::Has50Cents, VendingEvent::DispenseComplete)
        .transition(
            VendingState::Has75Cents,
            VendingEvent::Insert25Cents,
            VendingState::ReadyToDispense,
        )
        .self_loop(VendingState::Has75Cents, VendingEvent::Insert50Cents)
        .self_loop(VendingState::Has75Cents, VendingEvent::SelectItem)
        .transition(
            VendingState::Has75Cents,
            VendingEvent::Cancel,
            VendingState::Idle,
        )
        .self_loop(VendingState::Has75Cents, VendingEvent::DispenseComplete)
        .self_loop(VendingState::ReadyToDispense, VendingEvent::Insert25Cents)
        .self_loop(VendingState::ReadyToDispense, VendingEvent::Insert50Cents)
        .transition(
            VendingState::ReadyToDispense,
            VendingEvent::SelectItem,
            VendingState::Dispensing,
        )
        .transition(
            VendingState::ReadyToDispense,
            VendingEvent::Cancel,
            VendingState::Idle,
        )
        .self_loop(
            VendingState::ReadyToDispense,
            VendingEvent::DispenseComplete,
        )
        .self_loop(VendingState::Dispensing, VendingEvent::Insert25Cents)
        .self_loop(VendingState::Dispensing, VendingEvent::Insert50Cents)
        .self_loop(VendingState::Dispensing, VendingEvent::SelectItem)
        .self_loop(VendingState::Dispensing, VendingEvent::Cancel)
        .transition(
            VendingState::Dispensing,
            VendingEvent::DispenseComplete,
            VendingState::Idle,
        )
        .build()
        .unwrap();

    println!("Vending Machine Simulator");
    println!("Item cost: $1.00\n");

    println!("State: {:?}", machine.current());

    machine.trigger(VendingEvent::Insert25Cents);
    println!("Inserted 25 cents -> State: {:?}", machine.current());

    machine.trigger(VendingEvent::Insert25Cents);
    println!("Inserted 25 cents -> State: {:?}", machine.current());

    machine.trigger(VendingEvent::Insert25Cents);
    println!("Inserted 25 cents -> State: {:?}", machine.current());

    machine.trigger(VendingEvent::Insert25Cents);
    println!("Inserted 25 cents -> State: {:?}", machine.current());

    machine.trigger(VendingEvent::SelectItem);
    println!("Selected item -> State: {:?}", machine.current());

    machine.trigger(VendingEvent::DispenseComplete);
    println!("Dispensed item -> State: {:?}", machine.current());

    println!("\nStarting new transaction...");
    machine.trigger(VendingEvent::Insert50Cents);
    println!("Inserted 50 cents -> State: {:?}", machine.current());

    machine.trigger(VendingEvent::Cancel);
    println!("Cancelled (refund) -> State: {:?}", machine.current());
}