1[![Build Status](https://travis-ci.com/looplab/fsm.svg?branch=master)](https://travis-ci.com/looplab/fsm)
2[![Coverage Status](https://img.shields.io/coveralls/looplab/fsm.svg)](https://coveralls.io/r/looplab/fsm)
3[![GoDoc](https://godoc.org/github.com/looplab/fsm?status.svg)](https://godoc.org/github.com/looplab/fsm)
4[![Go Report Card](https://goreportcard.com/badge/looplab/fsm)](https://goreportcard.com/report/looplab/fsm)
5
6# FSM for Go
7
8FSM is a finite state machine for Go.
9
10It is heavily based on two FSM implementations:
11
12- Javascript Finite State Machine, https://github.com/jakesgordon/javascript-state-machine
13
14- Fysom for Python, https://github.com/oxplot/fysom (forked at https://github.com/mriehl/fysom)
15
16For API docs and examples see http://godoc.org/github.com/looplab/fsm
17
18# Basic Example
19
20From examples/simple.go:
21
22```go
23package main
24
25import (
26    "fmt"
27    "github.com/looplab/fsm"
28)
29
30func main() {
31    fsm := fsm.NewFSM(
32        "closed",
33        fsm.Events{
34            {Name: "open", Src: []string{"closed"}, Dst: "open"},
35            {Name: "close", Src: []string{"open"}, Dst: "closed"},
36        },
37        fsm.Callbacks{},
38    )
39
40    fmt.Println(fsm.Current())
41
42    err := fsm.Event("open")
43    if err != nil {
44        fmt.Println(err)
45    }
46
47    fmt.Println(fsm.Current())
48
49    err = fsm.Event("close")
50    if err != nil {
51        fmt.Println(err)
52    }
53
54    fmt.Println(fsm.Current())
55}
56```
57
58# Usage as a struct field
59
60From examples/struct.go:
61
62```go
63package main
64
65import (
66    "fmt"
67    "github.com/looplab/fsm"
68)
69
70type Door struct {
71    To  string
72    FSM *fsm.FSM
73}
74
75func NewDoor(to string) *Door {
76    d := &Door{
77        To: to,
78    }
79
80    d.FSM = fsm.NewFSM(
81        "closed",
82        fsm.Events{
83            {Name: "open", Src: []string{"closed"}, Dst: "open"},
84            {Name: "close", Src: []string{"open"}, Dst: "closed"},
85        },
86        fsm.Callbacks{
87            "enter_state": func(e *fsm.Event) { d.enterState(e) },
88        },
89    )
90
91    return d
92}
93
94func (d *Door) enterState(e *fsm.Event) {
95    fmt.Printf("The door to %s is %s\n", d.To, e.Dst)
96}
97
98func main() {
99    door := NewDoor("heaven")
100
101    err := door.FSM.Event("open")
102    if err != nil {
103        fmt.Println(err)
104    }
105
106    err = door.FSM.Event("close")
107    if err != nil {
108        fmt.Println(err)
109    }
110}
111```
112
113# License
114
115FSM is licensed under Apache License 2.0
116
117http://www.apache.org/licenses/LICENSE-2.0
118