ExGram.FSM.States behaviour (ExGram FSM v0.1.0)

Copy Markdown View Source

Behaviour for declaring FSM states and allowed transitions.

Implement this behaviour to enable transition validation (both compile-time warnings and runtime enforcement via the on_invalid_transition policy).

Use defstates/1 for a concise declaration:

defmodule MyBot.States do
  use ExGram.FSM.States

  defstates do
    state :idle, to: [:get_name]
    state :get_name, to: [:get_email, :idle]
    state :get_email, to: [:confirm, :get_name]
    state :confirm, to: [:idle]
  end
end

Direct behaviour implementation (escape hatch)

For dynamic or programmatic state/transition definitions:

defmodule MyBot.States do
  @behaviour ExGram.FSM.States

  @impl true
  def states, do: [:idle, :get_name, :get_email, :confirm]

  @impl true
  def transitions do
    %{
      idle: [:get_name],
      get_name: [:get_email, :idle],
      get_email: [:confirm, :get_name],
      confirm: [:idle]
    }
  end
end

No-transition-restriction mode

To declare states without restricting transitions (useful for documentation purposes only), omit :to from all states:

defstates do
  state :idle
  state :working
  state :done
end
# transitions/0 returns :any - all transitions allowed

Summary

Callbacks

Returns the list of all valid state atoms.

Returns the allowed transitions map, or :any if all transitions are allowed.

Functions

Declares all FSM states and their allowed transitions.

Declares a state inside a defstates/1 block.

Callbacks

states()

@callback states() :: [atom()]

Returns the list of all valid state atoms.

transitions()

@callback transitions() :: %{required(atom()) => [atom()]} | :any

Returns the allowed transitions map, or :any if all transitions are allowed.

When returning a map, keys are source states and values are lists of allowed target states. Transitions not listed in the map are considered invalid.

Functions

defstates(list)

(macro)

Declares all FSM states and their allowed transitions.

Example

defstates do
  state :idle, to: [:working]
  state :working, to: [:done, :idle]
  state :done, to: [:idle]
end

state(name, opts \\ [])

(macro)

Declares a state inside a defstates/1 block.

Options

  • :to - list of allowed target states from this state

Examples

state :idle, to: [:get_name]      # can only go to :get_name
state :idle                         # no transition restriction (when mixed, :any is NOT used)