Packages
caffeine_lang
5.3.0
6.3.1
6.3.0
6.2.2
6.2.1
6.2.0
6.1.2
6.1.1
6.1.0
6.0.0
5.6.0
5.5.0
5.4.4
5.4.3
5.4.2
5.4.1
5.4.0
5.3.0
5.2.0
5.1.1
5.1.0
5.0.12
5.0.11
5.0.10
5.0.8
5.0.7
5.0.6
5.0.5
5.0.4
5.0.1
5.0.0
4.10.0
4.9.0
4.8.3
4.8.2
4.8.1
4.8.0
4.7.9
4.7.8
4.7.7
4.7.6
4.7.5
4.6.7
4.6.6
4.6.5
4.6.4
4.6.3
4.6.2
4.6.0
4.5.1
4.5.0
4.4.4
4.4.3
4.4.1
4.4.0
4.3.7
4.3.6
3.0.6
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
3.0.0
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
1.0.2
1.0.1
0.1.0
0.0.24
0.0.23
0.0.22
0.0.21
0.0.20
0.0.19
0.0.18
0.0.17
0.0.16
0.0.15
0.0.14
0.0.13
0.0.12
0.0.11
0.0.10
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.2
0.0.1
A compiler for generating reliability artifacts from service expectation definitions.
Current section
Files
Jump to
Current section
Files
src/caffeine_lang@codegen@dependency_graph.erl
-module(caffeine_lang@codegen@dependency_graph).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/caffeine_lang/codegen/dependency_graph.gleam").
-export([generate/1]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-file("src/caffeine_lang/codegen/dependency_graph.gleam", 119).
-spec is_id_char(binary()) -> boolean().
is_id_char(G) ->
case G of
<<"_"/utf8>> ->
true;
_ ->
case gleam@string:to_utf_codepoints(G) of
[Cp] ->
Code = gleam_stdlib:identity(Cp),
(((Code >= 65) andalso (Code =< 90)) orelse ((Code >= 97)
andalso (Code =< 122)))
orelse ((Code >= 48) andalso (Code =< 57));
_ ->
false
end
end.
-file("src/caffeine_lang/codegen/dependency_graph.gleam", 102).
?DOC(" Strips all non-alphanumeric characters (except underscores) for Mermaid-safe node IDs.\n").
-spec sanitize_id(binary()) -> binary().
sanitize_id(Path) ->
_pipe = Path,
_pipe@1 = gleam@string:to_graphemes(_pipe),
_pipe@2 = gleam@list:map(_pipe@1, fun(G) -> case G of
<<"."/utf8>> ->
<<"_"/utf8>>;
<<" "/utf8>> ->
<<"_"/utf8>>;
<<"-"/utf8>> ->
<<"_"/utf8>>;
_ ->
case is_id_char(G) of
true ->
G;
false ->
<<""/utf8>>
end
end end),
erlang:list_to_binary(_pipe@2).
-file("src/caffeine_lang/codegen/dependency_graph.gleam", 57).
?DOC(" Generates Mermaid edge declarations for hard and soft dependencies.\n").
-spec build_edges(
list(caffeine_lang@linker@ir:intermediate_representation(caffeine_lang@linker@ir:resolved()))
) -> list(binary()).
build_edges(Irs) ->
_pipe = Irs,
gleam@list:flat_map(
_pipe,
fun(Ir) ->
Source_id = sanitize_id(
caffeine_lang@linker@ir:ir_to_identifier(Ir)
),
case erlang:element(8, erlang:element(5, Ir)) of
none ->
[];
{some, Relations} ->
Hard_edges = begin
_pipe@1 = gleam_stdlib:map_get(Relations, hard),
_pipe@2 = gleam@result:unwrap(_pipe@1, []),
gleam@list:map(
_pipe@2,
fun(Target) ->
<<<<<<" "/utf8, Source_id/binary>>/binary,
" -->|hard| "/utf8>>/binary,
(sanitize_id(Target))/binary>>
end
)
end,
Soft_edges = begin
_pipe@3 = gleam_stdlib:map_get(Relations, soft),
_pipe@4 = gleam@result:unwrap(_pipe@3, []),
gleam@list:map(
_pipe@4,
fun(Target@1) ->
<<<<<<" "/utf8, Source_id/binary>>/binary,
" -.->|soft| "/utf8>>/binary,
(sanitize_id(Target@1))/binary>>
end
)
end,
lists:append(Hard_edges, Soft_edges)
end
end
).
-file("src/caffeine_lang/codegen/dependency_graph.gleam", 88).
?DOC(
" Escapes characters that have special meaning in Mermaid labels.\n"
" Uses numeric HTML entity codes (e.g. #91; for [) which are broadly compatible.\n"
).
-spec escape_label(binary()) -> binary().
escape_label(Text) ->
_pipe = Text,
_pipe@1 = gleam@string:replace(_pipe, <<"\""/utf8>>, <<"#34;"/utf8>>),
_pipe@2 = gleam@string:replace(_pipe@1, <<"["/utf8>>, <<"#91;"/utf8>>),
_pipe@3 = gleam@string:replace(_pipe@2, <<"]"/utf8>>, <<"#93;"/utf8>>),
_pipe@4 = gleam@string:replace(_pipe@3, <<"("/utf8>>, <<"#40;"/utf8>>),
_pipe@5 = gleam@string:replace(_pipe@4, <<")"/utf8>>, <<"#41;"/utf8>>),
_pipe@6 = gleam@string:replace(_pipe@5, <<"{"/utf8>>, <<"#123;"/utf8>>),
_pipe@7 = gleam@string:replace(_pipe@6, <<"}"/utf8>>, <<"#125;"/utf8>>),
_pipe@8 = gleam@string:replace(_pipe@7, <<"<"/utf8>>, <<"#60;"/utf8>>),
gleam@string:replace(_pipe@8, <<">"/utf8>>, <<"#62;"/utf8>>).
-file("src/caffeine_lang/codegen/dependency_graph.gleam", 49).
?DOC(" Generates a single Mermaid node declaration with just the expectation name.\n").
-spec build_node(
caffeine_lang@linker@ir:intermediate_representation(caffeine_lang@linker@ir:resolved())
) -> binary().
build_node(Ir) ->
Path = caffeine_lang@linker@ir:ir_to_identifier(Ir),
Id = sanitize_id(Path),
Safe_name = escape_label(
erlang:element(2, erlang:element(2, erlang:element(2, Ir)))
),
<<<<<<<<" "/utf8, Id/binary>>/binary, "[\""/utf8>>/binary,
Safe_name/binary>>/binary,
"\"]"/utf8>>.
-file("src/caffeine_lang/codegen/dependency_graph.gleam", 44).
?DOC(" Builds the service grouping key from IR metadata.\n").
-spec service_key(
caffeine_lang@linker@ir:intermediate_representation(caffeine_lang@linker@ir:resolved())
) -> binary().
service_key(Ir) ->
erlang:element(2, erlang:element(4, erlang:element(2, Ir))).
-file("src/caffeine_lang/codegen/dependency_graph.gleam", 23).
?DOC(" Groups IRs by service and generates Mermaid subgraph blocks.\n").
-spec build_subgraphs(
list(caffeine_lang@linker@ir:intermediate_representation(caffeine_lang@linker@ir:resolved()))
) -> list(binary()).
build_subgraphs(Irs) ->
_pipe = Irs,
_pipe@1 = gleam@list:group(_pipe, fun(Ir) -> service_key(Ir) end),
_pipe@2 = maps:to_list(_pipe@1),
_pipe@3 = gleam@list:sort(
_pipe@2,
fun(A, B) ->
gleam@string:compare(erlang:element(1, A), erlang:element(1, B))
end
),
gleam@list:flat_map(
_pipe@3,
fun(Group) ->
{Service, Group_irs} = Group,
Header = <<<<<<<<" subgraph "/utf8,
(sanitize_id(Service))/binary>>/binary,
"[\""/utf8>>/binary,
(escape_label(Service))/binary>>/binary,
"\"]"/utf8>>,
Nodes = gleam@list:map(Group_irs, fun build_node/1),
lists:append([[Header], Nodes, [<<" end"/utf8>>]])
end
).
-file("src/caffeine_lang/codegen/dependency_graph.gleam", 13).
?DOC(
" Generates a Mermaid flowchart string from dependency relations in IRs.\n"
" Nodes are grouped into subgraphs by service.\n"
).
-spec generate(
list(caffeine_lang@linker@ir:intermediate_representation(caffeine_lang@linker@ir:resolved()))
) -> binary().
generate(Irs) ->
Subgraphs = build_subgraphs(Irs),
Edges = build_edges(Irs),
_pipe = [[<<"graph TD"/utf8>>], Subgraphs, Edges],
_pipe@1 = lists:append(_pipe),
gleam@string:join(_pipe@1, <<"\n"/utf8>>).