Current section

Files

Jump to
ides src ides_printer.erl
Raw

src/ides_printer.erl

-module(ides_printer).
-doc "Formatting and rendering for ides supervision trees.".
-export([format/2, print/2]).
-doc #{
f => format,
a => 2,
d =>
"Render the supervision tree as indented ASCII text.\n"
"The target process is marked with `*`. Indentation is 4 spaces\n"
"per level.\n"
"\n"
"Rendering rules:\n"
"- Root supervisor: `name (strategy)`\n"
"- Supervisor child: `name (strategy, restart_type)`\n"
"- Worker child: `name (restart_type)`\n"
"- Target process: prefixed with `* `"
}.
-spec format(TargetPid :: pid(), Tree :: ides_family:process()) -> iolist().
format(TargetPid, Tree) ->
format_node(TargetPid, Tree, 0).
-spec format_node(TargetPid :: pid(), Node :: ides_family:process(), Depth :: non_neg_integer()) ->
iolist().
format_node(
TargetPid,
#{
name := Name,
pid := Pid,
type := supervisor,
strategy := Strategy,
restart_type := RestartType,
children := Children
},
Depth
) ->
Prefix = prefix(TargetPid, Pid, Depth),
Anno = [" (", atom_to_list(Strategy), ", ", atom_to_list(RestartType), ")"],
[
Prefix,
Name,
Anno,
"\n"
| [format_node(TargetPid, Child, Depth + 1) || Child <- Children]
];
format_node(
TargetPid,
#{
name := Name,
pid := Pid,
type := supervisor,
strategy := Strategy,
children := Children
},
Depth
) ->
Prefix = prefix(TargetPid, Pid, Depth),
Anno = [" (", atom_to_list(Strategy), ")"],
[
Prefix,
Name,
Anno,
"\n"
| [format_node(TargetPid, Child, Depth + 1) || Child <- Children]
];
format_node(
TargetPid,
#{
name := Name,
pid := Pid,
type := worker,
restart_type := RestartType
},
Depth
) ->
Prefix = prefix(TargetPid, Pid, Depth),
Anno = [" (", atom_to_list(RestartType), ")"],
[Prefix, Name, Anno, "\n"].
-spec prefix(TargetPid :: pid(), Pid :: pid(), Depth :: non_neg_integer()) -> [string()].
prefix(_TargetPid, _Pid, 0) ->
[""];
prefix(TargetPid, Pid, Depth) ->
Indent = spaces(Depth * 4 - 2),
[Indent, marker(TargetPid, Pid)].
-spec spaces(non_neg_integer()) -> string().
spaces(0) -> "";
spaces(N) -> [$\s | spaces(N - 1)].
-spec marker(TargetPid :: pid(), Pid :: pid()) -> string().
marker(TargetPid, TargetPid) -> "* ";
marker(_TargetPid, _Pid) -> " ".
-doc #{
f => print,
a => 2,
d => "Like `format/2` but writes the rendered tree to stdout."
}.
-spec print(TargetPid :: pid(), Tree :: ides_family:process()) -> ok.
print(TargetPid, Tree) ->
io:put_chars(format(TargetPid, Tree)).