-module(gg_cn@internal@merge).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gg_cn/internal/merge.gleam").
-export([new/1, merge_class_list/2]).
-export_type([engine/0, descriptor/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.
?MODULEDOC(false).
-type engine() :: {engine,
gg_cn@internal@config:config(),
gg_cn@internal@class_map:class_part(),
gleam@set:set(binary()),
gleam@set:set(binary())}.
-type descriptor() :: external | {managed, binary(), list(binary())}.
-file("src/gg_cn/internal/merge.gleam", 31).
?DOC(false).
-spec new(gg_cn@internal@config:config()) -> engine().
new(Config) ->
{engine,
Config,
gg_cn@internal@class_map:build(Config),
gleam@set:from_list(erlang:element(7, Config)),
gleam@set:from_list(erlang:element(6, Config))}.
-file("src/gg_cn/internal/merge.gleam", 153).
?DOC(false).
-spec modifier_id(engine(), gg_cn@internal@parse:parsed()) -> binary().
modifier_id(Engine, Parsed) ->
Variant = case erlang:element(2, Parsed) of
[] ->
<<""/utf8>>;
[Single] ->
Single;
Many ->
_pipe = gg_cn@internal@sort_modifiers:sort_modifiers(
erlang:element(4, Engine),
Many
),
gleam@string:join(_pipe, <<":"/utf8>>)
end,
case erlang:element(3, Parsed) of
true ->
<<Variant/binary, "!"/utf8>>;
false ->
Variant
end.
-file("src/gg_cn/internal/merge.gleam", 136).
?DOC(false).
-spec finish(engine(), gg_cn@internal@parse:parsed(), binary(), boolean()) -> descriptor().
finish(Engine, Parsed, Group_id, Has_postfix_modifier) ->
Modifier_id = modifier_id(Engine, Parsed),
Conflict_groups = gg_cn@internal@class_map:get_conflicting_class_group_ids(
erlang:element(2, Engine),
Group_id,
Has_postfix_modifier
),
Conflict_ids = gleam@list:map(
Conflict_groups,
fun(G) -> <<Modifier_id/binary, G/binary>> end
),
{managed, <<Modifier_id/binary, Group_id/binary>>, Conflict_ids}.
-file("src/gg_cn/internal/merge.gleam", 86).
?DOC(false).
-spec compute_descriptor(engine(), binary()) -> descriptor().
compute_descriptor(Engine, Class_name) ->
Parsed = gg_cn@internal@parse:parse_class_name(Class_name),
case erlang:element(5, Parsed) of
{some, Position} ->
Base_without_postfix = gleam@string:slice(
erlang:element(4, Parsed),
0,
Position
),
case gg_cn@internal@class_map:get_class_group_id(
erlang:element(3, Engine),
Base_without_postfix
) of
{some, Group_id} ->
case gleam@set:contains(erlang:element(5, Engine), Group_id) of
true ->
case gg_cn@internal@class_map:get_class_group_id(
erlang:element(3, Engine),
erlang:element(4, Parsed)
) of
{some, Group_with_postfix} when Group_with_postfix =/= Group_id ->
finish(
Engine,
Parsed,
Group_with_postfix,
false
);
_ ->
finish(Engine, Parsed, Group_id, true)
end;
false ->
finish(Engine, Parsed, Group_id, true)
end;
none ->
case gg_cn@internal@class_map:get_class_group_id(
erlang:element(3, Engine),
erlang:element(4, Parsed)
) of
{some, Group_id@1} ->
finish(Engine, Parsed, Group_id@1, false);
none ->
external
end
end;
none ->
case gg_cn@internal@class_map:get_class_group_id(
erlang:element(3, Engine),
erlang:element(4, Parsed)
) of
{some, Group_id@2} ->
finish(Engine, Parsed, Group_id@2, false);
none ->
external
end
end.
-file("src/gg_cn/internal/merge.gleam", 64).
?DOC(false).
-spec resolve(engine(), list(binary())) -> list(binary()).
resolve(Engine, Tokens) ->
{Kept@1, _} = gleam@list:fold(
lists:reverse(Tokens),
{[], gleam@set:new()},
fun(Acc, Token) ->
{Kept, Claimed} = Acc,
case compute_descriptor(Engine, Token) of
external ->
{[Token | Kept], Claimed};
{managed, Class_id, Conflict_ids} ->
case gleam@set:contains(Claimed, Class_id) of
true ->
{Kept, Claimed};
false ->
Claimed@1 = gleam@list:fold(
[Class_id | Conflict_ids],
Claimed,
fun(S, Key) -> gleam@set:insert(S, Key) end
),
{[Token | Kept], Claimed@1}
end
end
end
),
Kept@1.
-file("src/gg_cn/internal/merge.gleam", 193).
?DOC(false).
-spec is_whitespace(binary()) -> boolean().
is_whitespace(Char) ->
(((((Char =:= <<" "/utf8>>) orelse (Char =:= <<"\t"/utf8>>)) orelse (Char
=:= <<"\n"/utf8>>))
orelse (Char =:= <<"\r"/utf8>>))
orelse (Char =:= <<"\f"/utf8>>))
orelse (Char =:= <<"\x{000B}"/utf8>>).
-file("src/gg_cn/internal/merge.gleam", 169).
?DOC(false).
-spec split_class_list(binary()) -> list(binary()).
split_class_list(Class_list) ->
_pipe = Class_list,
_pipe@1 = gleam@string:to_graphemes(_pipe),
_pipe@2 = gleam@list:fold(
_pipe@1,
{[], <<""/utf8>>},
fun(Acc, Char) ->
{Tokens_rev, Current} = Acc,
case is_whitespace(Char) of
true ->
case Current of
<<""/utf8>> ->
{Tokens_rev, <<""/utf8>>};
_ ->
{[Current | Tokens_rev], <<""/utf8>>}
end;
false ->
{Tokens_rev, <<Current/binary, Char/binary>>}
end
end
),
_pipe@3 = (fun(State) ->
{Tokens_rev@1, Current@1} = State,
case Current@1 of
<<""/utf8>> ->
Tokens_rev@1;
_ ->
[Current@1 | Tokens_rev@1]
end
end)(_pipe@2),
lists:reverse(_pipe@3).
-file("src/gg_cn/internal/merge.gleam", 48).
?DOC(false).
-spec merge_class_list(engine(), binary()) -> binary().
merge_class_list(Engine, Class_list) ->
Tokens = split_class_list(Class_list),
case Tokens of
[Single] ->
Single;
_ ->
Kept = resolve(Engine, Tokens),
gleam@string:join(Kept, <<" "/utf8>>)
end.