Packages

Create informative & beautiful source code reports.

Current section

Files

Jump to
report src report.erl
Raw

src/report.erl

-module(report).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([error/5, warning/5, info/5, primary_label/3, secondary_label/3, context_label/3, to_string/2]).
-export_type([report/0, level/0, info/0, position/0, span/0, label_style/0, label/0, relevant_labels/0, ctx/0, line/0]).
-opaque report() :: {report,
binary(),
binary(),
binary(),
level(),
list(info()),
list(label())}.
-type level() :: err | warning | info.
-type info() :: {text, binary()} |
{note, binary(), binary()} |
{rows, list({binary(), binary()}), binary()}.
-type position() :: {position, integer(), integer()}.
-type span() :: {span, position(), position()}.
-type label_style() :: primary | secondary | context.
-opaque label() :: {label, label_style(), binary(), span()}.
-type relevant_labels() :: {relevant_labels,
list(label()),
list({integer(), label()}),
list({integer(), label()}),
list({integer(), label()}),
list({integer(), label()}),
list({integer(), label()})}.
-type ctx() :: {ctx,
fun((binary()) -> binary()),
fun((binary()) -> binary()),
fun((binary()) -> binary()),
fun((binary()) -> binary()),
integer(),
integer(),
list(line()),
integer(),
integer(),
gleam@option:option(label()),
list(label()),
list({integer(), label()})}.
-type line() :: {break, integer()} | {line, integer(), binary()}.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 95).
-spec error(binary(), binary(), binary(), list(label()), list(info())) -> report().
error(File, Source, Message, Labels, Info) ->
{report, File, Source, Message, err, Info, Labels}.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 116).
-spec warning(binary(), binary(), binary(), list(label()), list(info())) -> report().
warning(File, Source, Message, Labels, Info) ->
{report, File, Source, Message, warning, Info, Labels}.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 135).
-spec info(binary(), binary(), binary(), list(label()), list(info())) -> report().
info(File, Source, Message, Labels, Info) ->
{report, File, Source, Message, info, Info, Labels}.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 145).
-spec span({integer(), integer()}, {integer(), integer()}) -> span().
span(From, To) ->
{span,
{position, erlang:element(1, From), erlang:element(2, From)},
{position, erlang:element(1, To), erlang:element(2, To)}}.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 155).
-spec primary_label(binary(), {integer(), integer()}, {integer(), integer()}) -> label().
primary_label(Message, Start, End) ->
{label, primary, Message, span(Start, End)}.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 165).
-spec secondary_label(binary(), {integer(), integer()}, {integer(), integer()}) -> label().
secondary_label(Message, Start, End) ->
{label, secondary, Message, span(Start, End)}.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 183).
-spec context_label(binary(), {integer(), integer()}, {integer(), integer()}) -> label().
context_label(Message, Start, End) ->
{label, context, Message, span(Start, End)}.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 345).
-spec find_relevant_labels(integer(), ctx()) -> relevant_labels().
find_relevant_labels(Line, Ctx) ->
Single_labels = gleam@list:filter(
erlang:element(12, Ctx),
fun(Label) ->
Line =:= erlang:element(
2,
erlang:element(2, erlang:element(4, Label))
)
end
),
{Multi_labels, Multi_starts, Multi_ends, Without_starts@1, Without_ends@1} = begin
Add_if = fun(Acc, Predicate, Label@1) -> case Predicate of
true ->
[Label@1 | Acc];
false ->
Acc
end end,
gleam@list:fold(
erlang:element(13, Ctx),
{[], [], [], [], []},
fun(Acc@1, Tagged) ->
{_, Label@2} = Tagged,
{Labels, Starts, Ends, Without_starts, Without_ends} = Acc@1,
Is_relevant = (Line >= erlang:element(
2,
erlang:element(2, erlang:element(4, Label@2))
))
andalso (Line =< erlang:element(
2,
erlang:element(3, erlang:element(4, Label@2))
)),
Is_start = Line =:= erlang:element(
2,
erlang:element(2, erlang:element(4, Label@2))
),
Is_end = Line =:= erlang:element(
2,
erlang:element(3, erlang:element(4, Label@2))
),
{Add_if(Labels, Is_relevant, Tagged),
Add_if(Starts, Is_start, Tagged),
Add_if(Ends, Is_end, Tagged),
Add_if(
Without_starts,
Is_relevant andalso not Is_start,
Tagged
),
Add_if(Without_ends, Is_relevant andalso not Is_end, Tagged)}
end
)
end,
{relevant_labels,
Single_labels,
Multi_labels,
Multi_starts,
Multi_ends,
Without_starts@1,
Without_ends@1}.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 386).
-spec highlight_source(binary(), integer(), ctx()) -> binary().
highlight_source(Source, Line, Ctx) ->
case erlang:element(11, Ctx) of
{some, Label} when (Line >= erlang:element(
2,
erlang:element(2, erlang:element(4, Label))
)) andalso (Line =< erlang:element(
2,
erlang:element(3, erlang:element(4, Label))
)) ->
Length = gleam@string:length(Source),
From = case Line =:= erlang:element(
2,
erlang:element(2, erlang:element(4, Label))
) of
true ->
erlang:element(
3,
erlang:element(2, erlang:element(4, Label))
)
- 1;
false ->
0
end,
To = case Line =:= erlang:element(
2,
erlang:element(3, erlang:element(4, Label))
) of
true ->
erlang:element(
3,
erlang:element(3, erlang:element(4, Label))
)
- 1;
false ->
Length
end,
Left = gleam@string:slice(Source, 0, From),
Middle = gleam@string:slice(Source, From, To - From),
Right = gleam@string:slice(Source, To, Length - To),
<<<<Left/binary, ((erlang:element(2, Ctx))(Middle))/binary>>/binary,
Right/binary>>;
_ ->
Source
end.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 595).
-spec gutter(gleam@option:option(binary()), binary(), ctx()) -> binary().
gutter(Inner, Separator, Ctx) ->
Inner@2 = case Inner of
none ->
gleam@string:repeat(<<" "/utf8>>, erlang:element(9, Ctx));
{some, Inner@1} ->
string_width:align(
Inner@1,
erlang:element(9, Ctx),
right,
<<" "/utf8>>
)
end,
<<<<<<Inner@2/binary, " "/utf8>>/binary,
((erlang:element(3, Ctx))(Separator))/binary>>/binary,
" "/utf8>>.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 787).
-spec build_columns(
integer(),
fun((integer(), binary()) -> {binary(), binary()})
) -> binary().
build_columns(Columns, Do) ->
gleam@bool:guard(
Columns < 1,
<<""/utf8>>,
fun() ->
_pipe = gleam@list:fold(
gleam@list:range(1, Columns),
{<<""/utf8>>, <<" "/utf8>>},
fun(Acc, Column) ->
{Result, Filler} = Acc,
{Rendered, Filler@1} = Do(Column, Filler),
{<<Result/binary, Rendered/binary>>, Filler@1}
end
),
gleam@pair:first(_pipe)
end
).
-file("/home/mystic/projects/gleam/report/src/report.gleam", 853).
-spec full_line(binary(), ctx()) -> binary().
full_line(Prefix, Ctx) ->
Padding = gleam@string:repeat(<<" "/utf8>>, erlang:element(9, Ctx) + 1),
(erlang:element(3, Ctx))(
<<<<Padding/binary, Prefix/binary>>/binary,
(gleam@string:repeat(
<<"─"/utf8>>,
(erlang:element(6, Ctx) - erlang:element(9, Ctx)) - 2
))/binary>>
).
-file("/home/mystic/projects/gleam/report/src/report.gleam", 1005).
-spec tag_multi_labels(list(label())) -> {list({integer(), label()}), integer()}.
tag_multi_labels(Labels) ->
{Labels@3, Max_overlapping@1, _, _, _} = begin
_pipe = gleam@list:sort(
Labels,
fun(A, B) ->
gleam@int:compare(
erlang:element(2, erlang:element(2, erlang:element(4, A))),
erlang:element(2, erlang:element(2, erlang:element(4, B)))
)
end
),
gleam@list:fold(
_pipe,
{[], 0, 1, 0, 0},
fun(Acc, Label) ->
{Labels@1,
Max_overlapping,
Overlapping_labels,
Greatest_start,
Greatest_end} = Acc,
Start = erlang:element(
2,
erlang:element(2, erlang:element(4, Label))
),
End = erlang:element(
2,
erlang:element(3, erlang:element(4, Label))
),
Overlaps = (Start >= Greatest_start) andalso (Start =< Greatest_end),
Overlapping_labels@1 = case Overlaps of
true ->
Overlapping_labels + 1;
false ->
1
end,
Labels@2 = [{Overlapping_labels@1, Label} | Labels@1],
{Labels@2,
gleam@int:max(Overlapping_labels@1, Max_overlapping),
Overlapping_labels@1,
Start,
gleam@int:max(End, Greatest_end)}
end
)
end,
{Labels@3, Max_overlapping@1}.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 904).
-spec init_ctx(report(), boolean()) -> ctx().
init_ctx(Report, Has_style) ->
{Min_line, Max_line, Single_labels@2, Multi_labels@2, Primary_label@2} = gleam@list:fold(
erlang:element(7, Report),
{0, 0, [], [], none},
fun(Acc, Label) ->
{Min, Max, Single_labels, Multi_labels, Primary_label} = Acc,
Min@1 = case Min of
0 ->
erlang:element(
2,
erlang:element(2, erlang:element(4, Label))
);
_ ->
gleam@int:min(
erlang:element(
2,
erlang:element(2, erlang:element(4, Label))
),
Min
)
end,
Max@1 = gleam@int:max(
Max,
erlang:element(2, erlang:element(3, erlang:element(4, Label)))
),
{Single_labels@1, Multi_labels@1} = case erlang:element(
2,
erlang:element(2, erlang:element(4, Label))
)
=:= erlang:element(2, erlang:element(3, erlang:element(4, Label))) of
true ->
{[Label | Single_labels], Multi_labels};
false ->
{Single_labels, [Label | Multi_labels]}
end,
Primary_label@1 = case {Primary_label, erlang:element(2, Label)} of
{none, primary} ->
{some, Label};
{_, _} ->
Primary_label
end,
{Min@1, Max@1, Single_labels@1, Multi_labels@1, Primary_label@1}
end
),
Single_labels@3 = lists:reverse(Single_labels@2),
{Tagged_multi_labels, Max_overlapping} = tag_multi_labels(Multi_labels@2),
Relevant_lines = begin
_pipe = erlang:element(3, Report),
_pipe@1 = gleam@string:split(_pipe, <<"\n"/utf8>>),
_pipe@2 = gleam@iterator:from_list(_pipe@1),
_pipe@3 = gleam@iterator:index(_pipe@2),
_pipe@4 = gleam@iterator:filter(
_pipe@3,
fun(Pair) ->
Line = erlang:element(2, Pair) + 1,
(Line >= Min_line) andalso (Line =< Max_line)
end
),
_pipe@5 = gleam@iterator:fold(
_pipe@4,
[],
fun(Lines, Pair@1) ->
{Source, I} = Pair@1,
Line@1 = I + 1,
Has_label = gleam@list:any(
erlang:element(7, Report),
fun(Label@1) ->
(Line@1 >= erlang:element(
2,
erlang:element(2, erlang:element(4, Label@1))
))
andalso (Line@1 =< erlang:element(
2,
erlang:element(3, erlang:element(4, Label@1))
))
end
),
case {Has_label, Lines} of
{false, [{break, _} | _]} ->
Lines;
{false, _} ->
[{break, Line@1} | Lines];
{true, _} ->
[{line, Line@1, Source} | Lines]
end
end
),
lists:reverse(_pipe@5)
end,
Number_offset = begin
_pipe@6 = Max_line,
_pipe@7 = gleam@int:to_string(_pipe@6),
gleam@string:length(_pipe@7)
end,
Style = fun(Style_fn) -> case Has_style of
true ->
Style_fn;
false ->
fun(X) -> X end
end end,
Color = begin
_pipe@8 = case erlang:element(5, Report) of
err ->
fun gleam_community@ansi:red/1;
warning ->
fun gleam_community@ansi:yellow/1;
info ->
fun gleam_community@ansi:blue/1
end,
Style(_pipe@8)
end,
Terminal_width = begin
_pipe@9 = string_width:get_terminal_size(),
_pipe@10 = gleam@result:map(
_pipe@9,
fun(Size) -> erlang:element(3, Size) end
),
gleam@result:unwrap(_pipe@10, 80)
end,
Max_width = begin
_pipe@11 = Terminal_width,
gleam@int:min(_pipe@11, 80)
end,
{ctx,
Color,
Style(fun gleam_community@ansi:dim/1),
Style(fun gleam_community@ansi:bold/1),
Style(fun gleam_community@ansi:cyan/1),
Terminal_width,
Max_width,
Relevant_lines,
Number_offset,
Max_overlapping,
Primary_label@2,
Single_labels@3,
Tagged_multi_labels}.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 1057).
-spec pos_to_string(position()) -> binary().
pos_to_string(Pos) ->
Line = begin
_pipe = erlang:element(2, Pos),
gleam@int:to_string(_pipe)
end,
Column = begin
_pipe@1 = erlang:element(3, Pos),
gleam@int:to_string(_pipe@1)
end,
<<<<Line/binary, ":"/utf8>>/binary, Column/binary>>.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 1063).
-spec color_of(label(), ctx()) -> fun((binary()) -> binary()).
color_of(Label, Ctx) ->
case erlang:element(2, Label) of
primary ->
erlang:element(2, Ctx);
secondary ->
erlang:element(5, Ctx);
context ->
erlang:element(3, Ctx)
end.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 467).
-spec build_underline(
list(label()),
integer(),
integer(),
gleam@option:option(label()),
ctx()
) -> binary().
build_underline(Labels, From, To, Trailing, Ctx) ->
Padding = gleam@string:repeat(<<" "/utf8>>, From - 1),
Underline = (gleam@list:fold(
gleam@list:range(From, To - 1),
<<""/utf8>>,
fun(Acc, Column) ->
Found_label = gleam@list:find(
Labels,
fun(Label) ->
(Column >= erlang:element(
3,
erlang:element(2, erlang:element(4, Label))
))
andalso (Column < erlang:element(
3,
erlang:element(3, erlang:element(4, Label))
))
end
),
case Found_label of
{error, _} ->
<<Acc/binary, " "/utf8>>;
{ok, Label@1} ->
Color = color_of(Label@1, Ctx),
Render_start_char = (Column =:= erlang:element(
3,
erlang:element(2, erlang:element(4, Label@1))
))
andalso (Trailing /= {some, Label@1}),
Char = case {Render_start_char, erlang:element(2, Label@1)} of
{true, primary} ->
<<"┯"/utf8>>;
{false, primary} ->
<<"━"/utf8>>;
{false, context} ->
<<"╌"/utf8>>;
{true, _} ->
<<"┬"/utf8>>;
{false, _} ->
<<"─"/utf8>>
end,
<<Acc/binary, (Color(Char))/binary>>
end
end
)),
Message = case Trailing of
{some, Label@2} ->
<<" "/utf8,
((color_of(Label@2, Ctx))(erlang:element(3, Label@2)))/binary>>;
none ->
<<""/utf8>>
end,
<<<<Padding/binary, Underline/binary>>/binary, Message/binary>>.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 552).
-spec build_message_line(binary(), gleam@queue:queue(label()), integer(), ctx()) -> binary().
build_message_line(Result, Labels, Offset, Ctx) ->
case gleam@queue:is_empty(Labels) of
true ->
Result;
false ->
_assert_subject = gleam@queue:pop_front(Labels),
{ok, {Label, Without_first}} = case _assert_subject of
{ok, {_, _}} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail,
module => <<"report"/utf8>>,
function => <<"build_message_line"/utf8>>,
line => 561})
end,
Padding = gleam@string:repeat(
<<" "/utf8>>,
(erlang:element(3, erlang:element(2, erlang:element(4, Label)))
- Offset)
- 1
),
End = case gleam@queue:is_empty(Without_first) of
true ->
<<"╰╴ "/utf8, (erlang:element(3, Label))/binary>>;
false ->
<<"│"/utf8>>
end,
Result@1 = <<<<Result/binary, Padding/binary>>/binary,
((color_of(Label, Ctx))(End))/binary>>,
build_message_line(
Result@1,
Without_first,
erlang:element(3, erlang:element(2, erlang:element(4, Label))),
Ctx
)
end.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 527).
-spec build_message_lines(gleam@queue:queue(label()), list(binary()), ctx()) -> list(binary()).
build_message_lines(Label_queue, Result, Ctx) ->
case gleam@queue:is_empty(Label_queue) of
true ->
lists:reverse(Result);
false ->
Line = build_message_line(<<""/utf8>>, Label_queue, 0, Ctx),
_assert_subject = gleam@queue:pop_back(Label_queue),
{ok, {_, Without_last}} = case _assert_subject of
{ok, {_, _}} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail,
module => <<"report"/utf8>>,
function => <<"build_message_lines"/utf8>>,
line => 536})
end,
build_message_lines(Without_last, [Line | Result], Ctx)
end.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 417).
-spec render_single_labels(list(label()), ctx()) -> list(binary()).
render_single_labels(Labels, Ctx) ->
gleam@bool:guard(
Labels =:= [],
[],
fun() ->
Sorted_labels = gleam@list:sort(
Labels,
fun(A, B) ->
gleam@int:compare(
erlang:element(
3,
erlang:element(2, erlang:element(4, A))
),
erlang:element(
3,
erlang:element(2, erlang:element(4, B))
)
)
end
),
[First | _] = case Sorted_labels of
[_ | _] -> Sorted_labels;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail,
module => <<"report"/utf8>>,
function => <<"render_single_labels"/utf8>>,
line => 433})
end,
From = erlang:element(
3,
erlang:element(2, erlang:element(4, First))
),
{_, To@1, Trailing_label, Reversed_labels} = gleam@list:fold(
Sorted_labels,
{0, 0, false, []},
fun(Acc, Label) ->
{From@1, To, _, Reversed} = Acc,
{gleam@int:max(
From@1,
erlang:element(
3,
erlang:element(2, erlang:element(4, Label))
)
),
gleam@int:max(
To,
erlang:element(
3,
erlang:element(3, erlang:element(4, Label))
)
),
(erlang:element(
3,
erlang:element(2, erlang:element(4, Label))
)
>= From@1)
andalso (erlang:element(
3,
erlang:element(3, erlang:element(4, Label))
)
>= To),
[Label | Reversed]}
end
),
{Trailing@1, Without_trailing} = case {Trailing_label,
Reversed_labels} of
{true, [Trailing | Rest]} ->
{{some, Trailing}, lists:reverse(Rest)};
{_, _} ->
{none, lists:reverse(Reversed_labels)}
end,
Underline = build_underline(Labels, From, To@1, Trailing@1, Ctx),
Label_queue = gleam@queue:from_list(Without_trailing),
Message_lines = build_message_lines(Label_queue, [], Ctx),
[Underline | Message_lines]
end
).
-file("/home/mystic/projects/gleam/report/src/report.gleam", 620).
-spec inner_gutter(list({integer(), label()}), integer(), ctx()) -> binary().
inner_gutter(Labels, Line, Ctx) ->
build_columns(
erlang:element(10, Ctx),
fun(Column, Filler) -> case gleam@list:key_find(Labels, Column) of
{error, _} ->
{gleam@string:repeat(Filler, 2), Filler};
{ok, Label} ->
Color = color_of(Label, Ctx),
Chars = case Line =:= erlang:element(
2,
erlang:element(2, erlang:element(4, Label))
) of
true ->
gleam@string:repeat(Filler, 2);
false ->
<<"│"/utf8, Filler/binary>>
end,
{Color(Chars), Filler}
end end
).
-file("/home/mystic/projects/gleam/report/src/report.gleam", 677).
-spec render_multi_label_start(
{integer(), label()},
list({integer(), label()}),
ctx()
) -> binary().
render_multi_label_start(Start, Labels, Ctx) ->
{Start_col, Start_label} = Start,
Start_color = color_of(Start_label, Ctx),
Result_start = (build_columns(
erlang:element(10, Ctx),
fun(Column, Filler) -> case Column =:= Start_col of
true ->
{Start_color(<<"╭─"/utf8>>), Start_color(<<"─"/utf8>>)};
false ->
case gleam@list:key_find(Labels, Column) of
{ok, Label} ->
Color = color_of(Label, Ctx),
{<<(Color(<<"│"/utf8>>))/binary, Filler/binary>>,
Filler};
{error, _} ->
{gleam@string:repeat(Filler, 2), Filler}
end
end end
)),
Pointer = <<(gleam@string:repeat(
<<"─"/utf8>>,
erlang:element(3, erlang:element(2, erlang:element(4, Start_label)))
- 1
))/binary,
"^"/utf8>>,
<<Result_start/binary, (Start_color(Pointer))/binary>>.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 653).
-spec do_render_multi_label_starts(
list({integer(), label()}),
list(binary()),
list({integer(), label()}),
ctx()
) -> list(binary()).
do_render_multi_label_starts(Starts, Result, Others, Ctx) ->
case Starts of
[] ->
lists:reverse(Result);
[Start | Rest_starts] ->
Rendered = render_multi_label_start(Start, Others, Ctx),
do_render_multi_label_starts(
Rest_starts,
[Rendered | Result],
[Start | Others],
Ctx
)
end.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 643).
-spec render_multi_label_starts(
list({integer(), label()}),
list({integer(), label()}),
ctx()
) -> list(binary()).
render_multi_label_starts(Starts, Others, Ctx) ->
Starts_outside_in = gleam@list:sort(
Starts,
fun(A, B) ->
gleam@int:compare(erlang:element(1, A), erlang:element(1, B))
end
),
do_render_multi_label_starts(Starts_outside_in, [], Others, Ctx).
-file("/home/mystic/projects/gleam/report/src/report.gleam", 739).
-spec render_multi_label_end(
{integer(), label()},
list({integer(), label()}),
ctx()
) -> binary().
render_multi_label_end(End, Labels, Ctx) ->
{End_col, End_label} = End,
End_color = color_of(End_label, Ctx),
Start = (build_columns(
erlang:element(10, Ctx),
fun(Column, Filler) -> case Column =:= End_col of
true ->
{End_color(<<"╰─"/utf8>>), End_color(<<"─"/utf8>>)};
false ->
case gleam@list:key_find(Labels, Column) of
{ok, Label} ->
Color = color_of(Label, Ctx),
{<<(Color(<<"│"/utf8>>))/binary, Filler/binary>>,
Filler};
{error, _} ->
{gleam@string:repeat(Filler, 2), Filler}
end
end end
)),
Pointer = <<<<(gleam@string:repeat(
<<"─"/utf8>>,
erlang:element(
3,
erlang:element(3, erlang:element(4, End_label))
)
- 2
))/binary,
"^ "/utf8>>/binary,
(erlang:element(3, End_label))/binary>>,
<<Start/binary, (End_color(Pointer))/binary>>.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 717).
-spec do_render_multi_label_ends(
list({integer(), label()}),
list(binary()),
list({integer(), label()}),
ctx()
) -> list(binary()).
do_render_multi_label_ends(Ends, Result, Others, Ctx) ->
case Ends of
[] ->
lists:reverse(Result);
[End | Rest_ends] ->
Rendered = render_multi_label_end(
End,
gleam@list:concat([Others, Rest_ends]),
Ctx
),
do_render_multi_label_ends(
Rest_ends,
[Rendered | Result],
Others,
Ctx
)
end.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 706).
-spec render_multi_label_ends(
list({integer(), label()}),
list({integer(), label()}),
ctx()
) -> list(binary()).
render_multi_label_ends(Ends, Others, Ctx) ->
Ends_inside_out = gleam@list:sort(
Ends,
fun(A, B) ->
gleam@order:negate(
gleam@int:compare(erlang:element(1, A), erlang:element(1, B))
)
end
),
do_render_multi_label_ends(Ends_inside_out, [], Others, Ctx).
-file("/home/mystic/projects/gleam/report/src/report.gleam", 273).
-spec render_line(line(), ctx()) -> list(binary()).
render_line(Line, Ctx) ->
case Line of
{break, _} ->
[begin
_pipe = gutter(none, <<"·"/utf8>>, Ctx),
(erlang:element(3, Ctx))(_pipe)
end];
{line, Number, Source} ->
Relevant = find_relevant_labels(Number, Ctx),
Inner_gutter = inner_gutter(
erlang:element(3, Relevant),
Number,
Ctx
),
Source_line = begin
Gutter = gutter(
{some,
begin
_pipe@1 = gleam@int:to_string(Number),
(erlang:element(3, Ctx))(_pipe@1)
end},
<<"│"/utf8>>,
Ctx
),
Highlighted = highlight_source(Source, Number, Ctx),
<<<<Gutter/binary, Inner_gutter/binary>>/binary,
Highlighted/binary>>
end,
Underline@1 = begin
_pipe@2 = render_single_labels(erlang:element(2, Relevant), Ctx),
gleam@list:map(
_pipe@2,
fun(Underline) ->
Gutter@1 = gutter(none, <<"│"/utf8>>, Ctx),
<<<<Gutter@1/binary, Inner_gutter/binary>>/binary,
Underline/binary>>
end
)
end,
Multi_starts = begin
_pipe@3 = render_multi_label_starts(
erlang:element(4, Relevant),
erlang:element(6, Relevant),
Ctx
),
gleam@list:map(
_pipe@3,
fun(Contents) ->
<<(gutter(none, <<"│"/utf8>>, Ctx))/binary,
Contents/binary>>
end
)
end,
Multi_ends = begin
_pipe@4 = render_multi_label_ends(
erlang:element(5, Relevant),
erlang:element(7, Relevant),
Ctx
),
gleam@list:map(
_pipe@4,
fun(Contents@1) ->
<<(gutter(none, <<"│"/utf8>>, Ctx))/binary,
Contents@1/binary>>
end
)
end,
[Source_line |
gleam@list:concat([Underline@1, Multi_starts, Multi_ends])]
end.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 818).
-spec render_rows(list({binary(), binary()}), binary(), integer(), ctx()) -> binary().
render_rows(Rows, Divider, Width, Ctx) ->
Left_width = gleam@list:fold(
Rows,
0,
fun(W, Row) ->
gleam@int:max(W, string_width:line(erlang:element(1, Row)))
end
),
_pipe@2 = gleam@list:map(
Rows,
fun(Row@1) ->
{Left, Right} = Row@1,
_pipe@1 = [begin
_pipe = string_width:align(
Left,
Left_width,
right,
<<" "/utf8>>
),
(erlang:element(4, Ctx))(_pipe)
end,
(erlang:element(3, Ctx))(Divider),
string_width:limit(
Right,
{size,
999999,
(Width - Left_width) - string_width:line(Divider)},
<<""/utf8>>
)],
string_width:stack_horizontal(_pipe@1, top, 0, <<" "/utf8>>)
end
),
string_width:stack_vertical(_pipe@2, left, 0, <<" "/utf8>>).
-file("/home/mystic/projects/gleam/report/src/report.gleam", 1073).
-spec wrap_with_prefix(binary(), binary(), integer()) -> binary().
wrap_with_prefix(Text, Prefix, Width) ->
Prefix_length = string_width:line(Prefix),
Gap = case Prefix_length of
0 ->
0;
_ ->
1
end,
_pipe@1 = [Prefix,
begin
_pipe = Text,
string_width:limit(
_pipe,
{size, 999999, (Width - Prefix_length) - Gap},
<<""/utf8>>
)
end],
string_width:stack_horizontal(_pipe@1, top, Gap, <<" "/utf8>>).
-file("/home/mystic/projects/gleam/report/src/report.gleam", 234).
-spec render_header(report(), ctx()) -> binary().
render_header(Report, Ctx) ->
Level = case erlang:element(5, Report) of
err ->
<<"error:"/utf8>>;
warning ->
<<"warning:"/utf8>>;
info ->
<<"info:"/utf8>>
end,
In = <<"in:"/utf8>>,
Message = begin
_pipe = erlang:element(4, Report),
_pipe@1 = wrap_with_prefix(
_pipe,
(erlang:element(2, Ctx))(Level),
erlang:element(7, Ctx)
),
(erlang:element(4, Ctx))(_pipe@1)
end,
Padding = gleam@string:repeat(
<<" "/utf8>>,
gleam@string:length(Level) - gleam@string:length(In)
),
Span = case erlang:element(11, Ctx) of
none ->
<<""/utf8>>;
{some, Label} ->
(erlang:element(3, Ctx))(
<<<<<<"@"/utf8,
(pos_to_string(
erlang:element(2, erlang:element(4, Label))
))/binary>>/binary,
"-"/utf8>>/binary,
(pos_to_string(erlang:element(3, erlang:element(4, Label))))/binary>>
)
end,
Location = begin
_pipe@2 = (<<(erlang:element(2, Report))/binary, Span/binary>>),
wrap_with_prefix(
_pipe@2,
<<Padding/binary, ((erlang:element(2, Ctx))(In))/binary>>,
erlang:element(7, Ctx)
)
end,
<<<<Message/binary, "\n"/utf8>>/binary, Location/binary>>.
-file("/home/mystic/projects/gleam/report/src/report.gleam", 801).
-spec render_info(info(), ctx()) -> binary().
render_info(Info_bit, Ctx) ->
At = (erlang:element(7, Ctx) - erlang:element(9, Ctx)) - 1,
Message@2 = case Info_bit of
{text, Message} ->
_pipe = Message,
wrap_with_prefix(_pipe, <<""/utf8>>, At);
{note, Prefix, Message@1} ->
_pipe@1 = Message@1,
wrap_with_prefix(
_pipe@1,
(erlang:element(4, Ctx))(<<Prefix/binary, ":"/utf8>>),
At
);
{rows, Rows, Divider} ->
render_rows(Rows, Divider, At, Ctx)
end,
string_width:stack_horizontal(
[gleam@string:repeat(<<" "/utf8>>, erlang:element(9, Ctx)), Message@2],
top,
1,
<<" "/utf8>>
).
-file("/home/mystic/projects/gleam/report/src/report.gleam", 201).
-spec to_string(report(), boolean()) -> binary().
to_string(Report, Has_style) ->
Ctx = init_ctx(Report, Has_style),
Header = render_header(Report, Ctx),
Info = begin
_pipe = erlang:element(6, Report),
_pipe@1 = gleam@list:map(
_pipe,
fun(_capture) -> render_info(_capture, Ctx) end
),
gleam@string:join(_pipe@1, <<"\n\n"/utf8>>)
end,
gleam@bool:lazy_guard(
erlang:element(7, Report) =:= [],
fun() -> <<Header/binary, (case erlang:element(6, Report) of
[] ->
<<""/utf8>>;
_ ->
<<"\n"/utf8, Info/binary>>
end)/binary>> end,
fun() ->
Lines = begin
_pipe@2 = erlang:element(8, Ctx),
_pipe@3 = gleam@list:flat_map(
_pipe@2,
fun(_capture@1) -> render_line(_capture@1, Ctx) end
),
gleam@string:join(_pipe@3, <<"\n"/utf8>>)
end,
<<<<<<<<<<<<<<Header/binary, "\n"/utf8>>/binary,
(full_line(<<"┌"/utf8>>, Ctx))/binary>>/binary,
"\n"/utf8>>/binary,
Lines/binary>>/binary,
"\n"/utf8>>/binary,
(full_line(<<"└"/utf8>>, Ctx))/binary>>/binary,
(case erlang:element(6, Report) of
[] ->
<<""/utf8>>;
_ ->
<<"\n"/utf8, Info/binary>>
end)/binary>>
end
).