mirror of
https://github.com/ash-project/ash_state_machine.git
synced 2024-09-20 13:23:52 +12:00
bd66b9236f
docs: docs improvements
72 lines
2.1 KiB
Elixir
72 lines
2.1 KiB
Elixir
defmodule AshStateMachine.Charts do
|
|
@moduledoc """
|
|
Returns a mermaid flow chart of a given state machine resource.
|
|
"""
|
|
|
|
@spec mermaid_state_diagram(Ash.Resource.t()) :: String.t()
|
|
def mermaid_state_diagram(resource) do
|
|
resource
|
|
|> AshStateMachine.Info.state_machine_initial_states!()
|
|
|> Enum.reduce({["stateDiagram-v2"], MapSet.new()}, fn state, {lines, checked} ->
|
|
add_to_chart(resource, state, lines ++ [], checked, :state_diagram)
|
|
end)
|
|
|> elem(0)
|
|
|> Enum.join("\n")
|
|
end
|
|
|
|
@spec mermaid_flowchart(Ash.Resource.t()) :: String.t()
|
|
def mermaid_flowchart(resource) do
|
|
resource
|
|
|> AshStateMachine.Info.state_machine_initial_states!()
|
|
|> Enum.reduce({["flowchart TD"], MapSet.new()}, fn state, {lines, checked} ->
|
|
add_to_chart(resource, state, lines ++ [], checked, :flow_chart)
|
|
end)
|
|
|> elem(0)
|
|
|> Enum.join("\n")
|
|
end
|
|
|
|
defp add_to_chart(resource, state, lines, checked, type) do
|
|
if state in checked do
|
|
{lines, checked}
|
|
else
|
|
checked = MapSet.put(checked, state)
|
|
|
|
state
|
|
|> transitions_from(resource)
|
|
|> Enum.reduce({lines, checked}, fn event, {lines, checked} ->
|
|
Enum.reduce(List.wrap(event.to), {lines, checked}, fn to, {lines, checked} ->
|
|
lines =
|
|
case type do
|
|
:flow_chart ->
|
|
name =
|
|
case event.action do
|
|
:* -> ""
|
|
action -> "|#{action}|"
|
|
end
|
|
|
|
lines ++ ["#{state} --> #{name} #{to}"]
|
|
|
|
:state_diagram ->
|
|
name =
|
|
case event.action do
|
|
:* -> ""
|
|
action -> ": #{action}"
|
|
end
|
|
|
|
lines ++ ["#{state} --> #{to}#{name}"]
|
|
end
|
|
|
|
add_to_chart(resource, to, lines, checked, type)
|
|
end)
|
|
end)
|
|
end
|
|
end
|
|
|
|
defp transitions_from(state, resource) do
|
|
resource
|
|
|> AshStateMachine.Info.state_machine_transitions()
|
|
|> Enum.filter(fn event ->
|
|
state in List.wrap(event.from)
|
|
end)
|
|
end
|
|
end
|