fsm

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 5, 2023 License: MIT Imports: 9 Imported by: 0

README

fsm

Finite State Machine

Go.Dev reference codecov Tests Go Report Card Licence Tag

Features

Usage

Installation

Use go get.

    go get github.com/things-go/fsm

Then import the package into your own code.

    import "github.com/things-go/fsm"
Example
package main

import (
	"fmt"

	"github.com/things-go/fsm"
)

type MyEvent int

const (
	Close MyEvent = 1
	Open  MyEvent = 2
)

func (c MyEvent) String() string {
	switch c {
	case 1:
		return "close"
	case 2:
		return "open"
	default:
		return "none"
	}
}

type MyState int

func (c MyState) String() string {
	switch c {
	case 1:
		return "closed"
	case 2:
		return "opened"
	default:
		return "none"
	}
}

const (
	IsClosed MyState = 1
	IsOpen   MyState = 2
)

func main() {
	f := fsm.NewSafeFsm[MyEvent, MyState](
		IsClosed,
		fsm.NewTransition([]fsm.Transform[MyEvent, MyState]{
			{Event: Open, Src: []MyState{IsClosed}, Dst: IsOpen},
			{Event: Close, Src: []MyState{IsOpen}, Dst: IsClosed},
		}),
	)
	fmt.Println(f.Current())
	err := f.Trigger(Open)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(f.Current())
	err = f.Trigger(Close)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(f.Current())
	// Output:
	// closed
	// opened
	// closed
	fmt.Println(fsm.VisualizeGraphviz[MyEvent, MyState](f))
	// digraph fsm {
	//    "closed" -> "opened" [ label = "open" ];
	//    "opened" -> "closed" [ label = "close" ];
	//
	//    "closed";
	//    "opened";
	// }
}

License

This project is under MIT License. See the LICENSE file for the full license text.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInappropriateEvent = errors.New("fsm: event inappropriate in the state")
	ErrNonExistEvent      = errors.New("fsm: event does not exist")
)

Functions

func Visualize

func Visualize[E constraints.Ordered, S constraints.Ordered](t VisualizeType, fsm Visualizer[E, S]) (string, error)

Visualize outputs a visualization of a Fsm in the desired format. If the type is not given it defaults to Graphviz

func VisualizeGraphviz added in v0.1.0

func VisualizeGraphviz[E constraints.Ordered, S constraints.Ordered](fsm Visualizer[E, S]) (string, error)

VisualizeGraphviz outputs a visualization of a Fsm in Graphviz format.

func VisualizeMermaid added in v0.1.0

func VisualizeMermaid[E constraints.Ordered, S constraints.Ordered](t MermaidType, fsm Visualizer[E, S]) (string, error)

VisualizeMermaid outputs a visualization of a Fsm in Mermaid format as specified by the graphType.

Types

type Diagram added in v0.1.1

type Diagram interface {
	// Visualize outputs a visualization of a Fsm in the desired format.
	// If the type is not given it defaults to Graphviz
	Visualize(t VisualizeType) (string, error)
}

type ErrorTranslator added in v0.1.0

type ErrorTranslator interface {
	Translate(err error) error
}

type Fsm added in v0.1.0

type Fsm[E constraints.Ordered, S constraints.Ordered] struct {
	// Transition contain events and source states to destination states.
	// This is immutable
	ITransition[E, S]
	// contains filtered or unexported fields
}

Fsm is the state machine that holds the current state. E is the event S is the state

func (*Fsm[E, S]) Clone added in v0.1.0

func (f *Fsm[E, S]) Clone() IFsm[E, S]

func (*Fsm[E, S]) CloneNewState added in v0.1.0

func (f *Fsm[E, S]) CloneNewState(newState S) IFsm[E, S]

func (*Fsm[E, S]) Current added in v0.1.0

func (f *Fsm[E, S]) Current() S

func (*Fsm[E, S]) CurrentAvailEvents added in v0.1.0

func (f *Fsm[E, S]) CurrentAvailEvents() []E

func (*Fsm[E, S]) Is added in v0.1.0

func (f *Fsm[E, S]) Is(state S) bool

func (*Fsm[E, S]) MatchCurrentAllOccur added in v0.1.0

func (f *Fsm[E, S]) MatchCurrentAllOccur(event ...E) bool

func (*Fsm[E, S]) MatchCurrentOccur added in v0.1.0

func (f *Fsm[E, S]) MatchCurrentOccur(event E) bool

func (*Fsm[E, S]) SetCurrent added in v0.1.0

func (f *Fsm[E, S]) SetCurrent(state S)

func (*Fsm[E, S]) Trigger added in v0.1.0

func (f *Fsm[E, S]) Trigger(event E) error

func (*Fsm[E, S]) Visualize added in v0.1.1

func (f *Fsm[E, S]) Visualize(t VisualizeType) (string, error)

type IFsm added in v0.0.7

type IFsm[E constraints.Ordered, S constraints.Ordered] interface {
	// Clone the Fsm.
	Clone() IFsm[E, S]
	// CloneNewState clone the Fsm with new state.
	CloneNewState(newState S) IFsm[E, S]
	// Current returns the current state.
	Current() S
	// Is returns true if state match the current state.
	Is(state S) bool
	// SetCurrent allows the user to move to the given state from current state.
	SetCurrent(state S)
	// Trigger call a state transition with the named event and src state if success will change the current state.
	// It will return nil if src state change to dst state success or one of these errors:
	//
	// - ErrInappropriateEvent: event inappropriate in the src state.
	// - ErrNonExistEvent: event does not exist
	Trigger(event E) error
	// MatchOccur returns true if event can occur in the current state.
	MatchCurrentOccur(event E) bool
	// MatchAllOccur returns true if all the events can occur in current state.
	MatchCurrentAllOccur(event ...E) bool
	// AvailEvents returns a list of available transform event in current state.
	CurrentAvailEvents() []E

	ITransition[E, S]
	Diagram
}

func NewFsm added in v0.1.0

func NewFsm[E constraints.Ordered, S constraints.Ordered](initState S, ts ITransition[E, S]) IFsm[E, S]

NewFsm constructs a generic Fsm with an initial state S and a transition. E is the event type S is the state type.

func NewSafeFsm added in v0.1.0

func NewSafeFsm[E constraints.Ordered, S constraints.Ordered](initState S, ts ITransition[E, S]) IFsm[E, S]

NewSafeFsm constructs a generic Fsm with an initial state S and a transition. E is the event type S is the state type.

type ITransition added in v0.2.0

type ITransition[E constraints.Ordered, S constraints.Ordered] interface {
	// Name return the name of the transition.
	Name() string
	// Transform return the dst state transition with the named event and src state.
	// It will return nil if src state change to dst state success or one of these errors:
	//
	// - ErrInappropriateEvent: event inappropriate in the src state.
	// - ErrNonExistEvent: event does not exist
	Transform(srcState S, event E) (dstState S, err error)
	// Match reports whether it can be transform to dst state with the named event and src state.
	Match(srcState, dstState S, event E) (bool, error)
	// MatchOccur returns true if event can occur in src state.
	MatchOccur(srcState S, event E) bool
	// MatchAllOccur returns true if all the events can occur in src state.
	MatchAllOccur(srcState S, events ...E) bool
	// ContainsEvent returns true if support the event.
	ContainsEvent(event E) bool
	// ContainsAllEvent returns true if support all event.
	ContainsAllEvent(events ...E) bool
	// AvailEvents returns a list of available transform event in src state.
	AvailEvents(srcState S) []E
	// AvailSourceStates returns a list of available source state in the event.
	AvailSourceStates(event ...E) []S
	// SortedTriggerSource return a list of sorted trigger source
	SortedTriggerSource() []TriggerSource[E, S]
	// SortedStates return a list of sorted states.
	SortedStates() []S
	// SortedEvents return a list of sorted events.
	SortedEvents() []E
	// StateName returns a event name.
	EventName(event E) string
	// StateName returns a state name.
	StateName(state S) string
}

type MermaidType added in v0.1.0

type MermaidType string

MermaidType the type of the mermaid diagram type

const (
	// FlowChart the diagram type for output in flowchart style (https://mermaid-js.github.io/mermaid/#/flowchart) (including current state)
	FlowChart MermaidType = "flowChart"
	// StateDiagram the diagram type for output in stateDiagram style (https://mermaid-js.github.io/mermaid/#/stateDiagram)
	StateDiagram MermaidType = "stateDiagram"
)

type SafeFsm added in v0.1.0

type SafeFsm[E constraints.Ordered, S constraints.Ordered] struct {
	// Transition contain events and source states to destination states.
	// This is immutable
	ITransition[E, S]
	// contains filtered or unexported fields
}

SafeFsm is the state machine that holds the current state and mutex. E is the event S is the state

func (*SafeFsm[E, S]) Clone added in v0.1.0

func (f *SafeFsm[E, S]) Clone() IFsm[E, S]

func (*SafeFsm[E, S]) CloneNewState added in v0.1.0

func (f *SafeFsm[E, S]) CloneNewState(newState S) IFsm[E, S]

func (*SafeFsm[E, S]) Current added in v0.1.0

func (f *SafeFsm[E, S]) Current() S

func (*SafeFsm[E, S]) CurrentAvailEvents added in v0.1.0

func (f *SafeFsm[E, S]) CurrentAvailEvents() []E

func (*SafeFsm[E, S]) Is added in v0.1.0

func (f *SafeFsm[E, S]) Is(state S) bool

func (*SafeFsm[E, S]) MatchCurrentAllOccur added in v0.1.0

func (f *SafeFsm[E, S]) MatchCurrentAllOccur(event ...E) bool

func (*SafeFsm[E, S]) MatchCurrentOccur added in v0.1.0

func (f *SafeFsm[E, S]) MatchCurrentOccur(event E) bool

func (*SafeFsm[E, S]) SetCurrent added in v0.1.0

func (f *SafeFsm[E, S]) SetCurrent(newState S)

func (*SafeFsm[E, S]) Trigger added in v0.1.0

func (f *SafeFsm[E, S]) Trigger(event E) error

func (*SafeFsm[E, S]) Visualize added in v0.1.1

func (f *SafeFsm[E, S]) Visualize(t VisualizeType) (string, error)

type Transform

type Transform[E constraints.Ordered, S constraints.Ordered] struct {
	// Name the event.
	Name string
	// Event is the event used when calling for the transform.
	Event E
	// Src is a slice of source states that the Fsm must be in to perform a
	// state transform.
	Src []S
	// Dst is the destination state that the Fsm will be in if the transform
	// succeeds.
	Dst S
}

Transform represents an event when initializing the Fsm.

The event can have one or more source states that is valid for performing the transition. If the Fsm is in one of the source states it will end up in the specified destination state.

type Transition added in v0.1.0

type Transition[E constraints.Ordered, S constraints.Ordered] struct {
	// contains filtered or unexported fields
}

Transition contain events and source states to destination states. NOTE: This is immutable

func NewTransition added in v0.1.0

func NewTransition[E constraints.Ordered, S constraints.Ordered](transforms []Transform[E, S]) *Transition[E, S]

NewTransition new a transition instance.

func (*Transition[E, S]) AvailEvents added in v0.1.0

func (t *Transition[E, S]) AvailEvents(srcState S) []E

AvailEvents returns a list of available transform event in src state.

func (*Transition[E, S]) AvailSourceStates added in v0.1.1

func (t *Transition[E, S]) AvailSourceStates(events ...E) []S

AvailSourceStates returns a list of available source state in this event.

func (*Transition[E, S]) ContainsAllEvent added in v0.1.0

func (t *Transition[E, S]) ContainsAllEvent(events ...E) bool

ContainsAllEvent returns true if support all event.

func (*Transition[E, S]) ContainsEvent added in v0.1.0

func (t *Transition[E, S]) ContainsEvent(event E) bool

ContainsEvent returns true if support the event.

func (*Transition[E, S]) EventName added in v0.1.0

func (t *Transition[E, S]) EventName(event E) string

StateName returns a event name.

func (*Transition[E, S]) Match added in v0.1.0

func (t *Transition[E, S]) Match(srcState, dstState S, event E) (bool, error)

Match reports whether it can be transform to dst state with the named event and src state.

func (*Transition[E, S]) MatchAllOccur added in v0.1.0

func (t *Transition[E, S]) MatchAllOccur(srcState S, events ...E) bool

MatchAllOccur returns true if all the events can occur in src state.

func (*Transition[E, S]) MatchOccur added in v0.1.0

func (t *Transition[E, S]) MatchOccur(srcState S, event E) bool

MatchOccur returns true if event can occur in src state.

func (*Transition[E, S]) Name added in v0.1.0

func (t *Transition[E, S]) Name() string

Name return the name of the transition.

func (*Transition[E, S]) SortedEvents added in v0.1.0

func (t *Transition[E, S]) SortedEvents() []E

SortedEvents return a list of sorted events.

func (*Transition[E, S]) SortedStates added in v0.1.0

func (t *Transition[E, S]) SortedStates() []S

SortedStates return a list of sorted states.

func (*Transition[E, S]) SortedTriggerSource added in v0.1.0

func (t *Transition[E, S]) SortedTriggerSource() []TriggerSource[E, S]

SortedTriggerSource return a list of sorted trigger source

func (*Transition[E, S]) StateName added in v0.1.0

func (t *Transition[E, S]) StateName(state S) string

StateName returns a state name.

func (*Transition[E, S]) Transform added in v0.1.0

func (t *Transition[E, S]) Transform(srcState S, event E) (dstState S, err error)

Transform return the dst state transition with the named event and src state. It will return nil if src state change to dst state success or one of these errors:

- ErrInappropriateEvent: event inappropriate in the src state. - ErrNonExistEvent: event does not exist

type TransitionBuilder added in v0.1.0

type TransitionBuilder[E constraints.Ordered, S constraints.Ordered] struct {
	// contains filtered or unexported fields
}

func NewTransitionBuilder added in v0.1.0

func NewTransitionBuilder[E constraints.Ordered, S constraints.Ordered](transforms []Transform[E, S]) *TransitionBuilder[E, S]

func (*TransitionBuilder[E, S]) Build added in v0.1.0

func (b *TransitionBuilder[E, S]) Build() *Transition[E, S]

func (*TransitionBuilder[E, S]) Name added in v0.1.0

func (b *TransitionBuilder[E, S]) Name(name string) *TransitionBuilder[E, S]

func (*TransitionBuilder[E, S]) StateNames added in v0.1.0

func (b *TransitionBuilder[E, S]) StateNames(states map[S]string) *TransitionBuilder[E, S]

func (*TransitionBuilder[E, S]) TranslatorError added in v0.1.0

func (b *TransitionBuilder[E, S]) TranslatorError(translate ErrorTranslator) *TransitionBuilder[E, S]

type TriggerSource added in v0.1.0

type TriggerSource[E constraints.Ordered, S constraints.Ordered] struct {
	// contains filtered or unexported fields
}

TriggerSource is storing the trigger source.

func (*TriggerSource[E, S]) Event added in v0.1.0

func (e *TriggerSource[E, S]) Event() E

Event the trigger source event.

func (*TriggerSource[E, S]) State added in v0.1.0

func (e *TriggerSource[E, S]) State() S

State the trigger source state.

type VisualizeType

type VisualizeType string

VisualizeType the type of the visualization

const (
	// Graphviz the type for graphviz output (https://www.graphviz.org/)
	Graphviz VisualizeType = "graphviz"
	// Mermaid the type for mermaid output (https://mermaid-js.github.io/mermaid/#/stateDiagram) in the stateDiagram form
	Mermaid VisualizeType = "mermaid"
	// MermaidStateDiagram the type for mermaid output (https://mermaid-js.github.io/mermaid/#/stateDiagram) in the stateDiagram form
	MermaidStateDiagram VisualizeType = "mermaid-state-diagram"
	// MermaidFlowChart the type for mermaid output (https://mermaid-js.github.io/mermaid/#/flowchart) in the flow chart form
	MermaidFlowChart VisualizeType = "mermaid-flow-chart"
)

type Visualizer added in v0.0.6

type Visualizer[E constraints.Ordered, S constraints.Ordered] interface {
	Current() S
	Name() string
	Transform(srcState S, event E) (dstState S, err error)
	SortedTriggerSource() []TriggerSource[E, S]
	SortedStates() []S
	SortedEvents() []E
	EventName(event E) string
	StateName(state S) string
}

Visualize outputs a visualization of a Fsm in the desired format.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL