Packages
caffeine_lang
5.4.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@source_snippet.erl
-module(caffeine_lang@source_snippet).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/caffeine_lang/source_snippet.gleam").
-export([extract_snippet/4]).
-export_type([source_snippet/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type source_snippet() :: {source_snippet, binary()}.
-file("src/caffeine_lang/source_snippet.gleam", 125).
-spec insert_marker_loop(
list(binary()),
integer(),
binary(),
integer(),
list(binary())
) -> list(binary()).
insert_marker_loop(Lines, Error_index, Marker, Current, Acc) ->
case Lines of
[] ->
Acc;
[Line | Rest] ->
New_acc = case Current =:= Error_index of
true ->
[Marker, Line | Acc];
false ->
[Line | Acc]
end,
insert_marker_loop(Rest, Error_index, Marker, Current + 1, New_acc)
end.
-file("src/caffeine_lang/source_snippet.gleam", 115).
?DOC(" Inserts the marker line after the error line in the context.\n").
-spec insert_marker(list(binary()), integer(), integer(), binary()) -> list(binary()).
insert_marker(Context_lines, Error_line, Start_line, Marker_line) ->
_pipe = insert_marker_loop(
Context_lines,
Error_line - Start_line,
Marker_line,
0,
[]
),
lists:reverse(_pipe).
-file("src/caffeine_lang/source_snippet.gleam", 107).
?DOC(" Formats the marker line with carets under the error position.\n").
-spec format_marker(integer(), integer(), integer()) -> binary().
format_marker(Column, Span_width, Gutter_width) ->
Gutter_space = gleam@string:repeat(<<" "/utf8>>, Gutter_width),
Col_space = gleam@string:repeat(<<" "/utf8>>, gleam@int:max(0, Column - 1)),
Carets = gleam@string:repeat(<<"^"/utf8>>, Span_width),
<<<<<<Gutter_space/binary, " | "/utf8>>/binary, Col_space/binary>>/binary,
Carets/binary>>.
-file("src/caffeine_lang/source_snippet.gleam", 100).
?DOC(" Formats a single line with its line number gutter.\n").
-spec format_line(integer(), binary(), integer()) -> binary().
format_line(Line_num, Content, Gutter_width) ->
Num_str = erlang:integer_to_binary(Line_num),
Padding = gleam@string:repeat(
<<" "/utf8>>,
Gutter_width - string:length(Num_str)
),
<<<<<<Padding/binary, Num_str/binary>>/binary, " | "/utf8>>/binary,
Content/binary>>.
-file("src/caffeine_lang/source_snippet.gleam", 78).
?DOC(" Collects lines from current_line to end_line (inclusive).\n").
-spec collect_lines(binary(), integer(), integer(), list({integer(), binary()})) -> list({integer(),
binary()}).
collect_lines(Source, Current_line, End_line, Acc) ->
gleam@bool:guard(
Current_line > End_line,
Acc,
fun() -> case gleam@string:split_once(Source, <<"\n"/utf8>>) of
{ok, {Line, Rest}} ->
collect_lines(
Rest,
Current_line + 1,
End_line,
[{Current_line, Line} | Acc]
);
{error, _} ->
gleam@bool:guard(
gleam@string:is_empty(Source),
Acc,
fun() -> [{Current_line, Source} | Acc] end
)
end end
).
-file("src/caffeine_lang/source_snippet.gleam", 69).
?DOC(" Skips past the first `count` lines by splitting on newlines.\n").
-spec skip_lines(binary(), integer()) -> binary().
skip_lines(Source, Count) ->
gleam@bool:guard(
Count =< 0,
Source,
fun() -> case gleam@string:split_once(Source, <<"\n"/utf8>>) of
{ok, {_, Rest}} ->
skip_lines(Rest, Count - 1);
{error, _} ->
Source
end end
).
-file("src/caffeine_lang/source_snippet.gleam", 58).
?DOC(
" Extracts only the lines in [start_line, end_line] without splitting the entire source.\n"
" Uses split_once to skip lines before the range and stop after it.\n"
).
-spec extract_context_lines(binary(), integer(), integer()) -> list({integer(),
binary()}).
extract_context_lines(Source, Start_line, End_line) ->
Remaining = skip_lines(Source, Start_line - 1),
_pipe = collect_lines(Remaining, Start_line, End_line, []),
lists:reverse(_pipe).
-file("src/caffeine_lang/source_snippet.gleam", 18).
?DOC(
" Extracts a source snippet around the given line/column position.\n"
" Shows 1 line of context above and below the error line.\n"
" Adds a caret (^) marker under the error position.\n"
" Line and column are 1-indexed.\n"
).
-spec extract_snippet(
binary(),
integer(),
integer(),
gleam@option:option(integer())
) -> source_snippet().
extract_snippet(Source_content, Line, Column, End_column) ->
Start_line = gleam@int:max(1, Line - 1),
End_line = Line + 1,
Context = extract_context_lines(Source_content, Start_line, End_line),
Max_line_num = case gleam@list:last(Context) of
{ok, {N, _}} ->
N;
{error, _} ->
End_line
end,
Gutter_width = string:length(erlang:integer_to_binary(Max_line_num)),
Context_lines = begin
_pipe = Context,
gleam@list:map(
_pipe,
fun(Pair) ->
format_line(
erlang:element(1, Pair),
erlang:element(2, Pair),
Gutter_width
)
end
)
end,
Span_width = case End_column of
{some, End_col} ->
gleam@int:max(1, End_col - Column);
none ->
1
end,
Marker_line = format_marker(Column, Span_width, Gutter_width),
Rendered = begin
_pipe@1 = insert_marker(Context_lines, Line, Start_line, Marker_line),
gleam@string:join(_pipe@1, <<"\n"/utf8>>)
end,
{source_snippet, Rendered}.