Documentation ¶
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrStateNotMatch = fmt.Errorf("state not match") ErrEventNotExist = fmt.Errorf("event not exist") )
Functions ¶
func MermaidGraphByTopDown ¶
func MermaidGraphByTopDown[E, S constraints.Ordered](fsm *FSM[E, S], transform TextTransformFunc) string
MermaidGraphByTopDown generates a Mermaid graph representation of the FSM. It takes an FSM object and a TextTransformFunc as input. The TextTransformFunc is an optional function that can be used to transform the text representation of states and events before including them in the graph.
The function returns a string containing the Mermaid graph definition.
The Mermaid graph is generated in the Top-Down (TD) style, where each transition from a source state to a destination state is represented with an arrow labeled by the corresponding event.
Example Usage:
fsm := NewFSM(StateA) fsm.AddTransition(StateA, EventX, StateB) fsm.AddTransition(StateB, EventY, StateC) graph := MermaidGraphByTopDown(fsm, nil) fmt.Println(graph)
Output:
graph TD StateA --> |EventX| StateB StateB --> |EventY| StateC
Types ¶
type FSM ¶
type FSM[E, S constraints.Ordered] struct { // contains filtered or unexported fields }
func NewFSM ¶
func NewFSM[E, S constraints.Ordered](startState S) *FSM[E, S]
func (*FSM[E, S]) DefineTransition ¶
DefineTransition adds a new transition to the Finite State Machine (FSM). It defines that when a specific event occurs in a particular source state, the FSM will transition to the destination state. If the same event and source state combination already exists in the FSM, it will panic with an error indicating that a duplicated transition is being added.
src -->|event| dest
Parameters: - event: The event triggering the transition. - src: The source state from which the transition is allowed. - dest: The destination state to which the FSM will transition when the event occurs in the source state.
Note: 1. The FSM should be placed in the global scope. 2. When importing the package, transitions should be added using the DefineTransition function during the initialization step.
func (*FSM[E, S]) OnAction ¶
OnAction triggers the transition in the Finite State Machine (FSM) when a specific event occurs. It first calls the internal doTransition function to determine the destination state after the event. If the transition is successful, it calls the provided action function with the destination state as a parameter. The action function is responsible for performing any necessary actions or operations associated with the state transition.
Parameters: - event: The event that triggers the transition. - action: A function that takes the destination state as a parameter and returns an error if any.
Example ¶
package main import ( "context" "fmt" ) func main() { repo := MemoryOrderRepository{} ctx := context.Background() // UseCaseSuccess: // ReturnRequest success!! fmt.Printf("UseCaseSuccess:\n") err := OrderUseCaseSuccess(repo, ctx) if err != nil { fmt.Println(err) } // UseCaseFail: // key = {event: Order.ReturnRequested, requiredState: Delivered}, but currentState = Cancelled: state not match fmt.Printf("\nUseCaseFail:\n") err = OrderUseCaseFail(repo, ctx) if err != nil { fmt.Println(err) } } func OrderUseCaseSuccess(repo OrderRepository, ctx context.Context) error { order, err := repo.LockOrderById(ctx, "action_success") if err != nil { return fmt.Errorf("get obj from db: %w", err) } return order.ReturnRequest() } func OrderUseCaseFail(repo OrderRepository, ctx context.Context) error { order, err := repo.LockOrderById(ctx, "action_fail") if err != nil { return err } return order.ReturnRequest() } type OrderRepository interface { LockOrderById(ctx context.Context, oId string) (Order, error) } type MemoryOrderRepository struct{} func (MemoryOrderRepository) LockOrderById(_ context.Context, oId string) (Order, error) { store := map[string]Order{ "action_success": { Id: "action_success", State: OrderStateDelivered, }, "action_fail": { Id: "action_fail", State: OrderStateCancelled, }, } return store[oId], nil } type Order struct { Id string // ... other field State OrderState } func (o *Order) ReturnRequest() error { fsm := OrderStateFSM.CopyFSM(o.State) return fsm.OnAction(OrderEventTopicReturnRequested, func(nextState OrderState) error { o.State = nextState fmt.Println("ReturnRequest success!!") return nil }) }
Output: