StateMachine is a lightweight, easy-to-use state machine library for Go. It allows you to define states and events to manage complex state transitions in a clean and organized way.
- Define states and an initial state
- Register events with transitions between states
- Execute before and after hooks for state transitions
- Validate state transitions
- Render state transition graph for visualization
To install StateMachine, use go get:
$ go get github.com/nejdetkadir/statemachine
Creating a new state machine is simple. Define your states and initial state:
package main
import (
"fmt"
"github.com/nejdetkadir/statemachine"
)
func main() {
states := []string{"A", "B"}
initialState := "A"
sm, err := statemachine.New(states, initialState)
if err != nil {
fmt.Println("Error creating state machine:", err)
return
}
fmt.Println("Initial State:", sm.CurrentState())
}
Register events that define transitions between states:
func main() {
states := []string{"A", "B"}
initialState := "A"
sm, err := statemachine.New(states, initialState)
if err != nil {
fmt.Println("Error creating state machine:", err)
return
}
event := statemachine.Event{
Name: "event1",
From: []string{"A"},
To: "B",
}
err = sm.RegisterEvent(event)
if err != nil {
fmt.Println("Error registering event:", err)
return
}
fmt.Println("Event registered successfully")
}
Fire events to transition between states:
func main() {
states := []string{"A", "B"}
initialState := "A"
sm, err := statemachine.New(states, initialState)
if err != nil {
fmt.Println("Error creating state machine:", err)
return
}
event := statemachine.Event{
Name: "event1",
From: []string{"A"},
To: "B",
}
err = sm.RegisterEvent(event)
if err != nil {
fmt.Println("Error registering event:", err)
return
}
err = sm.Fire("event1")
if err != nil {
fmt.Println("Error firing event:", err)
return
}
fmt.Println("Current State:", sm.CurrentState())
}
You can define before, after, and validate hooks for each event:
event := statemachine.Event{
Name: "event1",
From: []string{"A"},
To: "B",
Before: func() {
fmt.Println("Before transition")
},
After: func() {
fmt.Println("After transition")
},
Validate: func(from string, to string) error {
if from == "A" && to == "B" {
return nil
}
return fmt.Errorf("invalid transition from %s to %s", from, to)
},
}
Render the state transition graph to visualize events:
func main() {
states := []string{"A", "B"}
initialState := "A"
sm, err := statemachine.New(states, initialState)
if err != nil {
fmt.Println("Error creating state machine:", err)
return
}
event := statemachine.Event{
Name: "event1",
From: []string{"A"},
To: "B",
}
err = sm.RegisterEvent(event)
if err != nil {
fmt.Println("Error registering event:", err)
return
}
sm.RenderGraph()
}
Check out the examples directory for more usage examples.
To run the tests, use go test:
$ go test ./...
Bug reports and pull requests are welcome on GitHub at https://github.com/nejdetkadir/statemachine. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
This project is licensed under the MIT License. See the LICENSE file for details.