Packages
reactor
1.0.2
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/mermaid/node.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.Mermaid.Node do
@moduledoc """
A node in the mermaid graph
"""
defstruct children: [], id: nil, post: [], pre: []
@type node_data :: node_list | binary | byte | t
@type node_list :: [node_data] | node_data
@type t :: %__MODULE__{
children: node_list,
id: nil | String.t(),
post: node_list,
pre: node_list
}
@indent " "
@doc """
Render the node at the provided indent level.
"""
@spec render(t, non_neg_integer()) :: iodata
def render(node, indent) do
indent =
[@indent]
|> Stream.cycle()
|> Enum.take(indent)
do_render([node], [], indent)
end
defguardp is_byte(byte) when is_integer(byte) and byte >= 0 and byte <= 255
defp do_render([], result, _indent), do: result
defp do_render([[] | tail], result, indent), do: do_render(tail, result, indent)
defp do_render([head | tail], result, indent) when is_list(head) do
head = do_render(head, [], indent)
do_render(tail, [result, head], indent)
end
defp do_render([head | tail], result, indent) when is_struct(head, __MODULE__) do
pre = do_render(head.pre, [], indent)
children = do_render(head.children, [], [indent, @indent])
post = do_render(head.post, [], indent)
do_render(tail, [result, pre, children, post], indent)
end
defp do_render([head | tail], result, indent) when is_binary(head),
do: do_render(tail, [result, indent(head, indent)], indent)
defp do_render([head | tail], result, indent)
when is_integer(head) and head >= 0 and head <= 255,
do: do_render(tail, [result, indent(head, indent)], indent)
defp do_render(bin, result, indent) when is_binary(bin),
do: do_render([], [result, indent(bin, indent)], indent)
defp do_render(int, result, indent) when is_byte(int),
do: do_render([], [result, indent(int, indent)], indent)
defp indent("", _indent), do: ""
defp indent(input, []), do: input
defp indent(bin, indent) when is_binary(bin) do
bin
|> String.split("\n")
|> Enum.intersperse(["\n", indent])
end
defp indent(?\n, indent) do
[?\n, indent]
end
defp indent(int, _indent) when is_byte(int), do: IO.chardata_to_string([int])
end