Packages
caffeine_lang
4.4.3
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", 42).
?DOC(" Builds the service grouping key from IR metadata.\n").
-spec service_key(caffeine_lang@linker@ir:intermediate_representation()) -> binary().
service_key(Ir) ->
erlang:element(4, erlang:element(2, Ir)).
-file("src/caffeine_lang/codegen/dependency_graph.gleam", 85).
?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", 116).
-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", 99).
?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", 47).
?DOC(" Generates a single Mermaid node declaration with just the expectation name.\n").
-spec build_node(caffeine_lang@linker@ir:intermediate_representation()) -> 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, Ir))),
<<<<<<<<" "/utf8, Id/binary>>/binary, "[\""/utf8>>/binary,
Safe_name/binary>>/binary,
"\"]"/utf8>>.
-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())
) -> 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", 55).
?DOC(" Generates Mermaid edge declarations for hard and soft dependencies.\n").
-spec build_edges(list(caffeine_lang@linker@ir:intermediate_representation())) -> list(binary()).
build_edges(Irs) ->
_pipe = Irs,
_pipe@1 = gleam@list:filter(
_pipe,
fun(Ir) ->
gleam@list:contains(erlang:element(4, Ir), dependency_relations)
end
),
gleam@list:flat_map(
_pipe@1,
fun(Ir@1) ->
Source_id = sanitize_id(
caffeine_lang@linker@ir:ir_to_identifier(Ir@1)
),
case caffeine_lang@linker@ir:get_dependency_fields(
erlang:element(6, Ir@1)
) of
none ->
[];
{some, Dep} ->
Hard_edges = begin
_pipe@2 = gleam_stdlib:map_get(
erlang:element(2, Dep),
hard
),
_pipe@3 = gleam@result:unwrap(_pipe@2, []),
gleam@list:map(
_pipe@3,
fun(Target) ->
<<<<<<" "/utf8, Source_id/binary>>/binary,
" -->|hard| "/utf8>>/binary,
(sanitize_id(Target))/binary>>
end
)
end,
Soft_edges = begin
_pipe@4 = gleam_stdlib:map_get(
erlang:element(2, Dep),
soft
),
_pipe@5 = gleam@result:unwrap(_pipe@4, []),
gleam@list:map(
_pipe@5,
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", 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())) -> 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>>).