-module(birdie@internal@diff). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([line_by_line/2]). -export_type([diff_line/0, diff_line_kind/0]). -type diff_line() :: {diff_line, integer(), binary(), diff_line_kind()}. -type diff_line_kind() :: old | new | shared. -spec do_map2_index( list(IDZ), list(IEB), fun((IDZ, IEB, integer()) -> IED), list(IED), integer() ) -> {list(IED), list(IDZ), list(IEB), integer()}. do_map2_index(One, Other, Fun, Acc, Index) -> case {One, Other} of {Rest_one, []} -> {gleam@list:reverse(Acc), Rest_one, [], Index}; {[], Rest_other} -> {gleam@list:reverse(Acc), [], Rest_other, Index}; {[One@1 | Rest_one@1], [Other@1 | Rest_other@1]} -> _pipe = [Fun(One@1, Other@1, Index) | Acc], do_map2_index(Rest_one@1, Rest_other@1, Fun, _pipe, Index + 1) end. -spec map2_index(list(IDR), list(IDT), fun((IDR, IDT, integer()) -> IDV)) -> {list(IDV), list(IDR), list(IDT), integer()}. map2_index(One, Other, Fun) -> do_map2_index(One, Other, Fun, [], 1). -spec line_by_line(binary(), binary()) -> list(diff_line()). line_by_line(Old, New) -> Old_lines = gleam@string:split(Old, <<"\n"/utf8>>), New_lines = gleam@string:split(New, <<"\n"/utf8>>), {Diffs, Rest_old, Rest_new, Line_number} = (map2_index( Old_lines, New_lines, fun(Old_line, New_line, Line) -> Equal_lines = Old_line =:= New_line, Shared_diff_line = {diff_line, Line, Old_line, shared}, gleam@bool:guard( Equal_lines, [Shared_diff_line], fun() -> Comparison = begin _pipe = gap:compare_strings(New_line, Old_line), _pipe@1 = gap@styling:from_comparison(_pipe), _pipe@2 = gap@styling:highlight( _pipe@1, fun gleam_community@ansi:underline/1, fun gleam_community@ansi:underline/1, fun gap@styling:no_highlight/1 ), gap@styling:to_styled_comparison(_pipe@2) end, [{diff_line, Line, erlang:element(3, Comparison), old}, {diff_line, Line, erlang:element(2, Comparison), new}] end ) end )), _pipe@3 = gleam@list:concat(Diffs), _pipe@4 = gleam@list:append( _pipe@3, gleam@list:index_map( Rest_old, fun(Line@1, I) -> {diff_line, (Line_number + I) + 1, Line@1, old} end ) ), gleam@list:append( _pipe@4, gleam@list:index_map( Rest_new, fun(Line@2, I@1) -> {diff_line, (Line_number + I@1) + 1, Line@2, new} end ) ).