Packages
reactor
1.0.1
1.0.2
1.0.1
1.0.0
0.17.0
0.16.0
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.0
0.10.3
0.10.2
0.10.1
0.10.0
0.9.1
0.9.0
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.0
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
An asynchronous, graph-based execution engine
Current section
Files
Jump to
Current section
Files
lib/reactor/step/switch/mermaid.ex
# SPDX-FileCopyrightText: 2023 James Harton, Zach Daniel, Alembic Pty and contributors
# SPDX-FileCopyrightText: 2023 reactor contributors <https://github.com/ash-project/reactor/graphs/contributors>
#
# SPDX-License-Identifier: MIT
defmodule Reactor.Step.Switch.Mermaid do
@moduledoc """
Mermaid rendering for `switch` steps.
"""
import Reactor.Utils
alias Reactor.Mermaid.{Node, Step, Utils}
import Utils
@doc false
def to_mermaid(%{impl: {_module, opts}} = step, options) do
branches =
opts
|> Keyword.get(:matches, [])
|> Enum.concat([{:default, opts[:default]}])
|> Enum.reject(fn {_, steps} -> is_nil(steps) || steps == [] end)
with {:ok, node} <- describe_step(step, options),
{:ok, branches} <- describe_branches(step, branches, options) do
decision_id = "#{node.id}_decision"
decision = [
decision_id,
"@{shape: diamond, label: \"Decision for ",
name(step.name),
"\"}\n",
node.id,
"-->",
decision_id,
"\n"
]
links =
Enum.map(branches, fn branch ->
[decision_id, "-->", branch.id, "\n"]
end)
{:ok, %{node | post: [node.post, decision, links, branches]}}
end
end
defp describe_step(%{impl: {module, _opts}} = step, options) do
id = mermaid_id({options[:reactor_id], step.name}, :step)
content =
if options[:describe?] do
[
id,
"[\"`**",
name(step.name),
" \\(",
inspect(module),
"\\)**",
if(step.description, do: ["\n", md_escape(step.description)], else: []),
"`\"]\n"
]
else
[
id,
"[\"",
name(step.name),
"(",
inspect(module),
")\"]\n"
]
end
{:ok, %Node{id: id, pre: content}}
end
defp describe_branches(step, branches, options) do
map_while_ok(branches, &describe_branch(step, &1, options))
end
defp describe_branch(step, {:default, steps}, options) do
id = mermaid_id({options[:reactor_id], step.name, :default}, :step)
with {:ok, steps} <- generate_steps(steps, options) do
{:ok,
%Node{
id: id,
pre: [
"subgraph ",
id,
"[\"default branch of ",
name(step.name),
"\"]"
],
children: [
"\n",
steps,
"direction ",
direction(options[:direction])
],
post: [
"\n",
"end\n"
]
}}
end
end
defp describe_branch(step, {predicate, steps}, options) do
id = mermaid_id({options[:reactor_id], step.name, predicate}, :step)
with {:ok, steps} <- generate_steps(steps, options) do
content =
if options[:describe?] do
[
"subgraph ",
id,
"[\"`match branch of ",
name(step.name),
"\n_",
md_escape(inspect(predicate)),
"_",
"`\"]"
]
else
[
"subgraph ",
id,
"[\"match branch of ",
name(step.name),
"\"]"
]
end
{:ok,
%Node{
id: id,
pre: content,
children: [
"\n",
steps,
"direction ",
direction(options[:direction])
],
post: [
"\n",
"end\n"
]
}}
end
end
defp generate_steps(steps, options) do
map_while_ok(steps, &Step.to_mermaid(&1, options))
end
end