-module(scamper@visualization). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/scamper/visualization.gleam"). -export([to_mermaid/4, to_dot/4, machine_to_string/2]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " Visualization utilities for scamper FSMs.\n" "\n" " Generate Mermaid diagrams, DOT graphs, and string representations.\n" ). -file("src/scamper/visualization.gleam", 13). ?DOC(" Generate a Mermaid stateDiagram-v2 string from the config.\n"). -spec to_mermaid( scamper@config:config(JAO, any(), JAQ), JAO, fun((JAO) -> binary()), fun((JAQ) -> binary()) ) -> binary(). to_mermaid(Config, Initial_state, State_to_string, Event_to_string) -> Transitions = scamper@config:get_transitions(Config), Final_states = scamper@config:get_final_states(Config), Header = <<"stateDiagram-v2"/utf8>>, Initial_arrow = <<" [*] --> "/utf8, (State_to_string(Initial_state))/binary>>, Transition_lines = begin _pipe = Transitions, gleam@list:map( _pipe, fun(Rule) -> Label = Event_to_string(erlang:element(3, Rule)), Guard_suffix = case gleam@option:is_some( erlang:element(5, Rule) ) of true -> <<" [guarded]"/utf8>>; false -> <<""/utf8>> end, <<<<<<<<<<<<" "/utf8, (State_to_string( erlang:element(2, Rule) ))/binary>>/binary, " --> "/utf8>>/binary, (State_to_string(erlang:element(4, Rule)))/binary>>/binary, " : "/utf8>>/binary, Label/binary>>/binary, Guard_suffix/binary>> end ) end, Final_lines = begin _pipe@1 = Final_states, gleam@list:map( _pipe@1, fun(S) -> <<<<" "/utf8, (State_to_string(S))/binary>>/binary, " --> [*]"/utf8>> end ) end, _pipe@2 = [Header, Initial_arrow], _pipe@3 = lists:append(_pipe@2, Transition_lines), _pipe@4 = lists:append(_pipe@3, Final_lines), gleam@string:join(_pipe@4, <<"\n"/utf8>>). -file("src/scamper/visualization.gleam", 57). ?DOC(" Generate a DOT (Graphviz) graph string from the config.\n"). -spec to_dot( scamper@config:config(JAU, any(), JAW), JAU, fun((JAU) -> binary()), fun((JAW) -> binary()) ) -> binary(). to_dot(Config, Initial_state, State_to_string, Event_to_string) -> Transitions = scamper@config:get_transitions(Config), Final_states = scamper@config:get_final_states(Config), Header_lines = [<<"digraph FSM {"/utf8>>, <<" rankdir=LR;"/utf8>>, <<" node [shape=circle];"/utf8>>, <<" __start__ [shape=point];"/utf8>>], Final_node_lines = begin _pipe = Final_states, gleam@list:map( _pipe, fun(S) -> <<<<" "/utf8, (State_to_string(S))/binary>>/binary, " [shape=doublecircle];"/utf8>> end ) end, Initial_edge = <<<<" __start__ -> "/utf8, (State_to_string(Initial_state))/binary>>/binary, ";"/utf8>>, Transition_lines = begin _pipe@1 = Transitions, gleam@list:map( _pipe@1, fun(Rule) -> Label = Event_to_string(erlang:element(3, Rule)), Guard_suffix = case gleam@option:is_some( erlang:element(5, Rule) ) of true -> <<" [guarded]"/utf8>>; false -> <<""/utf8>> end, <<<<<<<<<<<<<<" "/utf8, (State_to_string( erlang:element(2, Rule) ))/binary>>/binary, " -> "/utf8>>/binary, (State_to_string(erlang:element(4, Rule)))/binary>>/binary, " [label=\""/utf8>>/binary, Label/binary>>/binary, Guard_suffix/binary>>/binary, "\"];"/utf8>> end ) end, Footer = <<"}"/utf8>>, _pipe@2 = Header_lines, _pipe@3 = lists:append(_pipe@2, Final_node_lines), _pipe@4 = lists:append(_pipe@3, [Initial_edge]), _pipe@5 = lists:append(_pipe@4, Transition_lines), _pipe@6 = lists:append(_pipe@5, [Footer]), gleam@string:join(_pipe@6, <<"\n"/utf8>>). -file("src/scamper/visualization.gleam", 114). ?DOC(" Generate a one-line summary of a machine's current state.\n"). -spec machine_to_string( scamper:machine(JBA, any(), any()), fun((JBA) -> binary()) ) -> binary(). machine_to_string(Machine, State_to_string) -> State_str = State_to_string(scamper:current_state(Machine)), History_count = erlang:length(scamper:history(Machine)), <<<<<<<<"Machine(state: "/utf8, State_str/binary>>/binary, ", history: "/utf8>>/binary, (erlang:integer_to_binary(History_count))/binary>>/binary, ")"/utf8>>.