Skip to content

Instantly share code, notes, and snippets.

@denispeplin
Created September 2, 2018 16:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save denispeplin/a3aca39698a2b1732003341e1dd41146 to your computer and use it in GitHub Desktop.
Save denispeplin/a3aca39698a2b1732003341e1dd41146 to your computer and use it in GitHub Desktop.
primitive fsm with hardcoded rules

Usage

den@den-vb:~/projects$ iex fsm.ex
Erlang/OTP 20 [erts-9.3.1] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:10] [hipe] [kernel-poll:false]

Interactive Elixir (1.7.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Fsm.transition!(%{status: "draft", data: "payload"}, :rejected)  
%{data: "payload", status: "rejected"}
iex(2)> Fsm.transition!(%{status: "rejected", data: "payload"}, :signed)  
** (RuntimeError) Transition from 'rejected' to 'signed' is not allowed
    fsm.ex:13: Fsm.transition!/2
defmodule Fsm do
@rules %{
draft: [:signed, :rejected],
rejected: [:draft],
signed: []
}
def transition!(%{status: status} = struct, transition) when is_atom(transition) do
transitions = Map.fetch!(@rules, String.to_existing_atom(status))
if transition in transitions do
%{struct | status: Atom.to_string(transition)}
else
raise "Transition from '#{status}' to '#{transition}' is not allowed"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment