Packages
caffeine_lang
4.7.9
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", 71).
?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", 80).
?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", 60).
?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", 102).
?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", 109).
?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", 127).
-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", 117).
?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", 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}.