12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- package fsm
- import (
- "errors"
- "fmt"
- "io"
- "log"
- )
- type (
- // ErrorString is a specific error type used to recognize FSM errors.
- ErrorString string
- // OnError is the type of FSM optional error handlers.
- OnError[SK, EK comparable] func(SK, EK, error) error
- )
- const (
- ErrUnavailableEvent ErrorString = "unavailable event"
- ErrGuardFailure ErrorString = "guard failure"
- ErrActionFailure ErrorString = "action failure"
- ErrEnterFailure ErrorString = "enter failure"
- ErrLeaveFailure ErrorString = "leave failure"
- )
- func (e ErrorString) Error() string {
- return string(e)
- }
- func MakeFailureError[SK, EK comparable](sk SK, ek EK, err error) error {
- var es ErrorString
- if ok := errors.As(err, &es); !ok {
- return fmt.Errorf("generic error at state %s / event %s: %w", sk, ek, err)
- }
- var format string
- switch es {
- case ErrUnavailableEvent:
- format = "unavailable event %s received on state %s: %w"
- case ErrGuardFailure:
- format = "guard failed for event %s received on state %s: %w"
- case ErrActionFailure:
- format = "action failed after event %s received on state %s: %w"
- case ErrEnterFailure:
- format = "enter failed entering state %s after event %s: %w"
- case ErrLeaveFailure:
- format = "leave failed leaving state %s on event %s: %w"
- default:
- format = "custom error at state %s / event %s: %w"
- }
- return fmt.Errorf(format, sk, ek, es)
- }
- // OnErrorIgnore silently ignores errors. Usually not recommended: mostly useful in tests.
- func OnErrorIgnore[SK, EK comparable](_ SK, _ EK, _ error) error { return nil }
- // OnErrorReturn returns the received error and, allowing the FSM to act on it.
- func OnErrorReturn[SK, EK comparable](sk SK, ek EK, err error) error {
- return MakeFailureError(sk, ek, err)
- }
- // OnErrorPanic panics when receiving an error. Not recommended.
- func OnErrorPanic[SK, EK comparable](sk SK, ek EK, err error) error {
- panic(MakeFailureError(sk, ek, err))
- }
- // MakeOnErrorWrite logs the error to the specified writer and returns success.
- func MakeOnErrorWrite[SK, EK comparable](w io.Writer) OnError[SK, EK] {
- return func(sk SK, ek EK, err error) error {
- fmt.Fprintln(w, MakeFailureError(sk, ek, err))
- return nil
- }
- }
- // _ is a compile-time verification of the type conformity for OnError handlers
- func _() {
- var fsm FSM[string, string, string]
- fsm.SetOnUnavailable(OnErrorIgnore[string, string])
- fsm.SetOnUnavailable(OnErrorReturn[string, string])
- fsm.SetOnUnavailable(OnErrorPanic[string, string])
- fsm.SetOnUnavailable(MakeOnErrorWrite[string, string](log.Default().Writer()))
- }
|