-module(gliff@internal@fuzzy_patch).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gliff/internal/fuzzy_patch.gleam").
-export([apply_patch_fuzzy/3]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(false).
-file("src/gliff/internal/fuzzy_patch.gleam", 59).
?DOC(false).
-spec consume_fuzzy(list(binary()), list(binary()), float()) -> {ok,
list(binary())} |
{error, binary()}.
consume_fuzzy(Lines, Expected, Threshold) ->
case Expected of
[] ->
{ok, Lines};
[Exp | Rest_exp] ->
case Lines of
[] ->
{error,
<<"Unexpected end of input, expected: "/utf8,
Exp/binary>>};
[Line | Rest_lines] ->
case Line =:= Exp of
true ->
consume_fuzzy(Rest_lines, Rest_exp, Threshold);
false ->
Sim = gliff@internal@similarity:line_similarity(
Exp,
Line
),
case Sim >= Threshold of
true ->
consume_fuzzy(
Rest_lines,
Rest_exp,
Threshold
);
false ->
{error,
<<<<<<<<"Fuzzy mismatch: expected '"/utf8,
Exp/binary>>/binary,
"' but got '"/utf8>>/binary,
Line/binary>>/binary,
"'"/utf8>>}
end
end
end
end.
-file("src/gliff/internal/fuzzy_patch.gleam", 91).
?DOC(false).
-spec split_lines(binary()) -> list(binary()).
split_lines(Text) ->
case Text of
<<""/utf8>> ->
[];
_ ->
gleam@string:split(Text, <<"\n"/utf8>>)
end.
-file("src/gliff/internal/fuzzy_patch.gleam", 98).
?DOC(false).
-spec prepend_reversed(list(EPE), list(EPE)) -> list(EPE).
prepend_reversed(Items, Onto) ->
case Items of
[] ->
Onto;
[H | T] ->
prepend_reversed(T, [H | Onto])
end.
-file("src/gliff/internal/fuzzy_patch.gleam", 16).
?DOC(false).
-spec apply_edits_fuzzy(
list(binary()),
list(gliff@types:edit()),
float(),
list(binary())
) -> {ok, binary()} | {error, binary()}.
apply_edits_fuzzy(Lines, Edits, Threshold, Acc) ->
case Edits of
[] ->
case Lines of
[] ->
{ok, gleam@string:join(lists:reverse(Acc), <<"\n"/utf8>>)};
Remaining ->
{ok,
gleam@string:join(
lists:append(lists:reverse(Acc), Remaining),
<<"\n"/utf8>>
)}
end;
[Edit | Rest_edits] ->
case Edit of
{equal, Expected} ->
case consume_fuzzy(Lines, Expected, Threshold) of
{ok, Remaining@1} ->
apply_edits_fuzzy(
Remaining@1,
Rest_edits,
Threshold,
prepend_reversed(Expected, Acc)
);
{error, E} ->
{error, E}
end;
{delete, Expected@1} ->
case consume_fuzzy(Lines, Expected@1, Threshold) of
{ok, Remaining@2} ->
apply_edits_fuzzy(
Remaining@2,
Rest_edits,
Threshold,
Acc
);
{error, E@1} ->
{error, E@1}
end;
{insert, New_lines} ->
apply_edits_fuzzy(
Lines,
Rest_edits,
Threshold,
prepend_reversed(New_lines, Acc)
)
end
end.
-file("src/gliff/internal/fuzzy_patch.gleam", 6).
?DOC(false).
-spec apply_patch_fuzzy(binary(), list(gliff@types:edit()), float()) -> {ok,
binary()} |
{error, binary()}.
apply_patch_fuzzy(Text, Edits, Tolerance) ->
Lines = split_lines(Text),
Threshold = 1.0 - Tolerance,
apply_edits_fuzzy(Lines, Edits, Threshold, []).