-module(kdleam@normalize). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/kdleam/normalize.gleam"). -export([normalize/1]). -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/kdleam/normalize.gleam", 83). ?DOC(false). -spec write_type(gleam@option:option(binary())) -> binary(). write_type(Ty) -> case Ty of {some, Ty@1} -> <<<<"("/utf8, (kdleam@serialize:write_identifier_or_string(Ty@1))/binary>>/binary, ")"/utf8>>; none -> <<""/utf8>> end. -file("src/kdleam/normalize.gleam", 174). ?DOC(false). -spec normalize_exponent_tail(list(binary())) -> binary(). normalize_exponent_tail(Chars) -> case Chars of [] -> <<"+"/utf8>>; [<<"+"/utf8>> | _] -> kdleam@scanner:join(Chars); [<<"-"/utf8>> | _] -> kdleam@scanner:join(Chars); _ -> <<"+"/utf8, (kdleam@scanner:join(Chars))/binary>> end. -file("src/kdleam/normalize.gleam", 163). ?DOC(false). -spec strip_decimal_leading_zeros_chars(list(binary())) -> binary(). strip_decimal_leading_zeros_chars(Chars) -> case Chars of [<<"0"/utf8>>, Next | Rest] -> case kdleam@scanner:is_ascii_digit(Next) of true -> strip_decimal_leading_zeros_chars([Next | Rest]); false -> kdleam@scanner:join(Chars) end; _ -> kdleam@scanner:join(Chars) end. -file("src/kdleam/normalize.gleam", 159). ?DOC(false). -spec strip_decimal_leading_zeros(binary()) -> binary(). strip_decimal_leading_zeros(Value) -> strip_decimal_leading_zeros_chars(gleam@string:to_graphemes(Value)). -file("src/kdleam/normalize.gleam", 145). ?DOC(false). -spec normalize_exponent_chars(list(binary()), binary()) -> binary(). normalize_exponent_chars(Chars, Acc) -> case Chars of [] -> strip_decimal_leading_zeros(Acc); [Ch | Rest] -> case (Ch =:= <<"e"/utf8>>) orelse (Ch =:= <<"E"/utf8>>) of true -> <<<<(strip_decimal_leading_zeros(Acc))/binary, "E"/utf8>>/binary, (normalize_exponent_tail(Rest))/binary>>; false -> normalize_exponent_chars(Rest, <>) end end. -file("src/kdleam/normalize.gleam", 141). ?DOC(false). -spec normalize_exponent(binary()) -> binary(). normalize_exponent(Clean) -> normalize_exponent_chars(gleam@string:to_graphemes(Clean), <<""/utf8>>). -file("src/kdleam/normalize.gleam", 134). ?DOC(false). -spec apply_sign(binary(), binary()) -> binary(). apply_sign(Sign, Body) -> case Body of <<"0"/utf8>> -> <<"0"/utf8>>; _ -> <> end. -file("src/kdleam/normalize.gleam", 201). ?DOC(false). -spec try_prefix(binary(), list({binary(), integer()})) -> {gleam@option:option(integer()), binary()}. try_prefix(Rest, Prefixes) -> case Prefixes of [] -> {none, Rest}; [{Prefix, Base} | Others] -> Body = gleam_stdlib:string_remove_prefix(Rest, Prefix), case Body /= Rest of true -> {{some, Base}, Body}; false -> try_prefix(Rest, Others) end end. -file("src/kdleam/normalize.gleam", 197). ?DOC(false). -spec prefix(binary()) -> {gleam@option:option(integer()), binary()}. prefix(Rest) -> try_prefix(Rest, kdleam@scanner:radix_prefixes()). -file("src/kdleam/normalize.gleam", 183). ?DOC(false). -spec remove_sign(binary()) -> {binary(), binary()}. remove_sign(Raw) -> Minus = gleam_stdlib:string_remove_prefix(Raw, <<"-"/utf8>>), case Minus /= Raw of true -> {<<"-"/utf8>>, Minus}; false -> Plus = gleam_stdlib:string_remove_prefix(Raw, <<"+"/utf8>>), case Plus /= Raw of true -> {<<""/utf8>>, Plus}; false -> {<<""/utf8>>, Raw} end end. -file("src/kdleam/normalize.gleam", 120). ?DOC(false). -spec normalize_raw_number(binary()) -> binary(). normalize_raw_number(Raw) -> {Sign, Rest} = remove_sign(Raw), case prefix(Rest) of {{some, Base}, Body} -> case kdleam@bignum:base_to_decimal( kdleam@scanner:clean_underscores(Body), Base ) of {ok, <<"0"/utf8>>} -> <<"0"/utf8>>; {ok, V} -> <>; {error, _} -> <> end; {none, _} -> apply_sign( Sign, begin _pipe = kdleam@scanner:clean_underscores(Rest), normalize_exponent(_pipe) end ) end. -file("src/kdleam/normalize.gleam", 112). ?DOC(false). -spec normalize_number(kdleam@document:kdl_number()) -> binary(). normalize_number(Number) -> Raw = kdleam@document:number_raw(Number), case gleam_stdlib:string_starts_with(Raw, <<"#"/utf8>>) of true -> Raw; false -> normalize_raw_number(Raw) end. -file("src/kdleam/normalize.gleam", 102). ?DOC(false). -spec write_value(kdleam@document:kdl_value()) -> binary(). write_value(Value) -> case Value of {kdl_string, Value@1} -> kdleam@serialize:write_identifier_or_string(Value@1); {kdl_number_value, Number} -> normalize_number(Number); {kdl_bool, true} -> <<"#true"/utf8>>; {kdl_bool, false} -> <<"#false"/utf8>>; kdl_null -> <<"#null"/utf8>> end. -file("src/kdleam/normalize.gleam", 90). ?DOC(false). -spec write_entry(kdleam@document:kdl_entry()) -> binary(). write_entry(Entry) -> case Entry of {kdl_argument, Ty, Value} -> <<(write_type(Ty))/binary, (write_value(Value))/binary>>; {kdl_property, Key, Ty@1, Value@1} -> <<<<<<(kdleam@serialize:write_identifier_or_string(Key))/binary, "="/utf8>>/binary, (write_type(Ty@1))/binary>>/binary, (write_value(Value@1))/binary>> end. -file("src/kdleam/normalize.gleam", 72). ?DOC(false). -spec prop_key(kdleam@document:kdl_entry()) -> binary(). prop_key(Entry) -> case Entry of {kdl_property, Key, _, _} -> Key; _ -> <<""/utf8>> end. -file("src/kdleam/normalize.gleam", 79). ?DOC(false). -spec compare_prop(kdleam@document:kdl_entry(), kdleam@document:kdl_entry()) -> gleam@order:order(). compare_prop(A, B) -> gleam@string:compare(prop_key(A), prop_key(B)). -file("src/kdleam/normalize.gleam", 61). ?DOC(false). -spec dedupe_props( list(kdleam@document:kdl_entry()), list(kdleam@document:kdl_entry()) ) -> list(kdleam@document:kdl_entry()). dedupe_props(Props, Acc) -> case Props of [] -> Acc; [Prop | Rest] -> Key = prop_key(Prop), Without = gleam@list:filter(Acc, fun(P) -> prop_key(P) /= Key end), dedupe_props(Rest, [Prop | Without]) end. -file("src/kdleam/normalize.gleam", 46). ?DOC(false). -spec split_entries( list(kdleam@document:kdl_entry()), list(kdleam@document:kdl_entry()), list(kdleam@document:kdl_entry()) ) -> {list(kdleam@document:kdl_entry()), list(kdleam@document:kdl_entry())}. split_entries(Entries, Args, Props) -> case Entries of [] -> {lists:reverse(Args), lists:reverse(Props)}; [Entry | Rest] -> case Entry of {kdl_argument, _, _} -> split_entries(Rest, [Entry | Args], Props); {kdl_property, _, _, _} -> split_entries(Rest, Args, [Entry | Props]) end end. -file("src/kdleam/normalize.gleam", 21). ?DOC(false). -spec write_node(kdleam@document:kdl_node(), integer()) -> binary(). write_node(Node, Depth) -> {kdl_node, Ty, Name, Entries, Children} = Node, {Args, Props} = split_entries(Entries, [], []), Sorted_props = begin _pipe = Props, _pipe@1 = dedupe_props(_pipe, []), gleam@list:sort(_pipe@1, fun compare_prop/2) end, Entry_text = begin _pipe@2 = lists:append(Args, Sorted_props), _pipe@3 = gleam@list:map( _pipe@2, fun(Entry) -> <<" "/utf8, (write_entry(Entry))/binary>> end ), gleam@string:join(_pipe@3, <<""/utf8>>) end, Head = <<<<<<(kdleam@scanner:repeat(<<" "/utf8>>, Depth))/binary, (write_type(Ty))/binary>>/binary, (kdleam@serialize:write_identifier_or_string(Name))/binary>>/binary, Entry_text/binary>>, case Children of {some, Kids} when Kids =/= [] -> <<<<<<<>/binary, (begin _pipe@4 = Kids, _pipe@5 = gleam@list:map( _pipe@4, fun(_capture) -> write_node(_capture, Depth + 1) end ), gleam@string:join(_pipe@5, <<""/utf8>>) end)/binary>>/binary, (kdleam@scanner:repeat(<<" "/utf8>>, Depth))/binary>>/binary, "}\n"/utf8>>; _ -> <> end. -file("src/kdleam/normalize.gleam", 13). ?DOC(false). -spec normalize(kdleam@document:kdl_document()) -> binary(). normalize(Doc) -> {kdl_document, Nodes} = Doc, case Nodes of [] -> <<"\n"/utf8>>; _ -> _pipe = Nodes, _pipe@1 = gleam@list:map( _pipe, fun(_capture) -> write_node(_capture, 0) end ), gleam@string:join(_pipe@1, <<""/utf8>>) end.