Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FSM

Typed finite-state machine (FSM) generator for Go.

It generates state types, transition helpers, and transition interfaces so illegal transitions fail at compile time.

Features

  • No runtime surprises - compile-time checked transitions via typed state unions (similar to sum types).
  • Easy to change – update the FSM config, generate, and fix compiler errors.

How It Works

  • Machine structure is defined in protobuf text format.
  • fsm-gen-fsm reads the machine definition and generates strongly typed Go code.
  • Transition implementations are regular Go functions provided by your app.

Schema: proto/fsm/v1/fsm.proto

Example machine: examples/simple/fsm.textproto

initial_state: "open"
states: { name: "open"  next: "read"  next: "write" }
states: { name: "read"  next: "close" }
states: { name: "write" next: "close" }
states: { name: "close" }

Diagram: examples/simple/graph.png

Example Transition Implementation

type Data struct {
	count int
}

data := &Data{}

transitions := Transitions[*Data]{
	OnOpen: func(_ context.Context, d *Data, s Open) (ReadWrite, error) {
		d.count += 1
		return s.ToRead(), nil
	},
	OnRead: func(_ context.Context, d *Data, _ Read) (Close, error) {
		d.count += 1
		return Close{}, nil
	},
	OnWrite: func(_ context.Context, d *Data, _ Write) (Close, error) {
		return Close{}, nil
	},
	OnClose: func(_ context.Context, d *Data, _ Close) error {
		d.count += 1
		return nil
	},
}

fsm, err := CreateFSM(data, transitions)
if err != nil {
	t.Fatalf("CreateFSM: %v", err)
}

final, err := fsm.Run(context.Background())
if err != nil {
	t.Fatalf("Run: %v", err)
}
if _, ok := final.(Close); !ok {
	t.Fatalf("expected Close, got %T", final)
}

Prerequisites

  • protoc and protoc-gen-go for protobuf generation

Quick Start

  1. Generate protobuf types:
go generate ./proto/fsm/v1
  1. Generate FSM code from a machine spec:
go run ./cmd/fsm-gen-fsm -in examples/simple/fsm.textproto -out examples/simple/fsm_gen.go -pkg simple
  1. Run tests:
go test ./...

You can also generate the example package directly:

cd examples/simple
go generate ./...

About

Go finite state machine (FSM) with compile-time-verifiable transitions

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages