-module(molt@internal@utils). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/molt/internal/utils.gleam"). -export([toml_kind/1, index_entry_to_string/1, is_bare_key/1, make_key_token/1, list_at/2, quote_key/1, path_to_string/1, resolve_index/2, resolve_insert_position/2, all_prefixes/1, split_at/2, reverse_concat/1, unescape_basic_string/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/molt/internal/utils.gleam", 12). ?DOC(false). -spec toml_kind(molt@types:toml_kind()) -> binary(). toml_kind(Value) -> case Value of array -> <<"array"/utf8>>; array_element -> <<"array_element"/utf8>>; array_of_tables -> <<"array_of_tables"/utf8>>; bare_key -> <<"bare_key"/utf8>>; basic_string -> <<"basic_string"/utf8>>; binary_integer -> <<"binary_integer"/utf8>>; bom -> <<"bom"/utf8>>; bool_false -> <<"false"/utf8>>; bool_true -> <<"true"/utf8>>; comma -> <<"comma"/utf8>>; comment -> <<"comment"/utf8>>; dot -> <<"dot"/utf8>>; equals -> <<"equals"/utf8>>; error -> <<"error"/utf8>>; float -> <<"float"/utf8>>; hex_integer -> <<"hex_integer"/utf8>>; inf -> <<"unsigned_inf"/utf8>>; inline_table -> <<"inline_table"/utf8>>; integer -> <<"integer"/utf8>>; invalid_value -> <<"invalid_value"/utf8>>; invalid_basic_string -> <<"invalid_basic_string"/utf8>>; invalid_literal_string -> <<"invalid_literal_string"/utf8>>; invalid_multiline_basic_string -> <<"invalid_multiline_basic_string"/utf8>>; invalid_multiline_literal_string -> <<"invalid_multiline_literal_string"/utf8>>; key -> <<"key"/utf8>>; key_value -> <<"key_value"/utf8>>; left_brace -> <<"left_brace"/utf8>>; left_bracket -> <<"left_bracket"/utf8>>; literal_string -> <<"literal_string"/utf8>>; local_date -> <<"local_date"/utf8>>; local_date_time -> <<"local_datetime"/utf8>>; local_time -> <<"local_time"/utf8>>; multiline_basic_string -> <<"multiline_basic_string"/utf8>>; multiline_basic_string_nl -> <<"multiline_basic_string_nl"/utf8>>; multiline_literal_string -> <<"multiline_literal_string"/utf8>>; multiline_literal_string_nl -> <<"multiline_literal_string_nl"/utf8>>; na_n -> <<"unsigned_nan"/utf8>>; neg_inf -> <<"negative_inf"/utf8>>; neg_na_n -> <<"negative_nan"/utf8>>; newline -> <<"newline"/utf8>>; octal_integer -> <<"octal_integer"/utf8>>; offset_date_time -> <<"offset_datetime"/utf8>>; post_script -> <<"postscript"/utf8>>; pos_inf -> <<"positive_inf"/utf8>>; pos_na_n -> <<"positive_nan"/utf8>>; right_brace -> <<"right_brace"/utf8>>; right_bracket -> <<"right_bracket"/utf8>>; root -> <<"document"/utf8>>; table -> <<"table"/utf8>>; whitespace -> <<"whitespace"/utf8>> end. -file("src/molt/internal/utils.gleam", 67). ?DOC(false). -spec index_entry_to_string(molt@types:index_entry()) -> binary(). index_entry_to_string(Entry) -> case Entry of {index_table, _} -> <<"table"/utf8>>; {index_array_of_tables, _, _} -> <<"array of tables"/utf8>>; {index_array_of_tables_entry, _, _, _} -> <<"array of tables entry"/utf8>>; {index_implicit_table, _} -> <<"implicit table"/utf8>>; {index_scalar_value, _} -> <<"value"/utf8>>; {index_inline_table_value, _} -> <<"inline table"/utf8>>; {index_array_value, _} -> <<"array"/utf8>> end. -file("src/molt/internal/utils.gleam", 173). ?DOC(false). -spec escape_key(binary()) -> binary(). escape_key(Key) -> _pipe = Key, _pipe@1 = gleam@string:replace(_pipe, <<"\\"/utf8>>, <<"\\\\"/utf8>>), gleam@string:replace(_pipe@1, <<"\""/utf8>>, <<"\\\""/utf8>>). -file("src/molt/internal/utils.gleam", 169). ?DOC(false). -spec is_bare_key_char(binary()) -> boolean(). is_bare_key_char(Char) -> (casefold:is_alnum_grapheme(Char) orelse (Char =:= <<"-"/utf8>>)) orelse (Char =:= <<"_"/utf8>>). -file("src/molt/internal/utils.gleam", 139). ?DOC(false). -spec is_bare_key(binary()) -> boolean(). is_bare_key(Key) -> (Key /= <<""/utf8>>) andalso begin _pipe = Key, _pipe@1 = gleam@string:to_graphemes(_pipe), gleam@list:all(_pipe@1, fun is_bare_key_char/1) end. -file("src/molt/internal/utils.gleam", 79). ?DOC(false). -spec make_key_token(binary()) -> greenwood:token(molt@types:toml_kind()). make_key_token(Name) -> gleam@bool:guard( is_bare_key(Name), {token, bare_key, Name}, fun() -> {token, basic_string, escape_key(Name)} end ). -file("src/molt/internal/utils.gleam", 84). ?DOC(false). -spec list_at(list(FUP), integer()) -> {ok, FUP} | {error, nil}. list_at(Items, Index) -> _pipe = gleam@list:drop(Items, Index), gleam@list:first(_pipe). -file("src/molt/internal/utils.gleam", 145). ?DOC(false). -spec quote_key(binary()) -> binary(). quote_key(Key) -> gleam@bool:guard( is_bare_key(Key), Key, fun() -> <<<<"\""/utf8, (escape_key(Key))/binary>>/binary, "\""/utf8>> end ). -file("src/molt/internal/utils.gleam", 88). ?DOC(false). -spec path_to_string(list(molt@types:path_segment())) -> binary(). path_to_string(Segments) -> _pipe = gleam@list:map(Segments, fun(Segment) -> case Segment of {key_segment, Key} -> quote_key(Key); {index_segment, Index} -> <<<<"["/utf8, (erlang:integer_to_binary(Index))/binary>>/binary, "]"/utf8>> end end), _pipe@1 = gleam@string:join(_pipe, <<"."/utf8>>), gleam@string:replace(_pipe@1, <<".["/utf8>>, <<"["/utf8>>). -file("src/molt/internal/utils.gleam", 99). ?DOC(false). -spec resolve_index(integer(), integer()) -> integer(). resolve_index(Index, Length) -> gleam@bool:guard(Index < 0, Length + Index, fun() -> Index end). -file("src/molt/internal/utils.gleam", 107). ?DOC(false). -spec resolve_insert_position(integer(), integer()) -> {ok, integer()} | {error, nil}. resolve_insert_position(Index, Length) -> Min = 0 - Length, case Index of I when (I >= 0) andalso (I =< Length) -> {ok, I}; I@1 when (I@1 < 0) andalso (I@1 >= Min) -> {ok, Length + I@1}; _ -> {error, nil} end. -file("src/molt/internal/utils.gleam", 124). ?DOC(false). -spec do_all_prefixes(list(FUZ), list(FUZ), list(list(FUZ))) -> list(list(FUZ)). do_all_prefixes(Segments, Current, Acc) -> case Segments of [] -> lists:reverse(Acc); [_] -> lists:reverse(Acc); [Segment | Path] -> Current@1 = lists:append(Current, [Segment]), do_all_prefixes(Path, Current@1, [Current@1 | Acc]) end. -file("src/molt/internal/utils.gleam", 120). ?DOC(false). -spec all_prefixes(list(FUV)) -> list(list(FUV)). all_prefixes(Segments) -> do_all_prefixes(Segments, [], []). -file("src/molt/internal/utils.gleam", 153). ?DOC(false). -spec split_at(binary(), integer()) -> {binary(), binary()}. split_at(S, Index) -> Len = string:length(S), gleam@bool:guard( Len < Index, {S, <<""/utf8>>}, fun() -> gleam@bool:lazy_guard( Index >= 0, fun() -> {gleam@string:slice(S, 0, Index), gleam@string:slice(S, Index, Len)} end, fun() -> {gleam@string:slice(S, 0, Len + Index), gleam@string:slice(S, Len + Index, Len)} end ) end ). -file("src/molt/internal/utils.gleam", 165). ?DOC(false). -spec reverse_concat(list(binary())) -> binary(). reverse_concat(Strings) -> _pipe = Strings, _pipe@1 = lists:reverse(_pipe), erlang:list_to_binary(_pipe@1). -file("src/molt/internal/utils.gleam", 235). ?DOC(false). -spec skip_continuation_whitespace(list(binary())) -> list(binary()). skip_continuation_whitespace(Input) -> case Input of [<<" "/utf8>> | Rest] -> skip_continuation_whitespace(Rest); [<<"\t"/utf8>> | Rest] -> skip_continuation_whitespace(Rest); [<<"\n"/utf8>> | Rest] -> skip_continuation_whitespace(Rest); [<<"\r"/utf8>> | Rest] -> skip_continuation_whitespace(Rest); _ -> Input end. -file("src/molt/internal/utils.gleam", 226). ?DOC(false). -spec skip_line_continuation(list(binary())) -> gleam@option:option(list(binary())). skip_line_continuation(Input) -> case Input of [<<" "/utf8>> | Rest] -> skip_line_continuation(Rest); [<<"\t"/utf8>> | Rest] -> skip_line_continuation(Rest); [<<"\r"/utf8>>, <<"\n"/utf8>> | Rest@1] -> {some, skip_continuation_whitespace(Rest@1)}; [<<"\n"/utf8>> | Rest@1] -> {some, skip_continuation_whitespace(Rest@1)}; [<<"\r"/utf8>> | Rest@1] -> {some, skip_continuation_whitespace(Rest@1)}; _ -> none end. -file("src/molt/internal/utils.gleam", 243). ?DOC(false). -spec decode_unicode(list(binary()), integer()) -> {binary(), list(binary())}. decode_unicode(Input, N) -> {Hex, Rest} = gleam@list:split(Input, N), Hex@1 = erlang:list_to_binary(Hex), case gleam@int:base_parse(Hex@1, 16) of {ok, Codepoint} -> case gleam@string:utf_codepoint(Codepoint) of {ok, Cp} -> {gleam_stdlib:utf_codepoint_list_to_string([Cp]), Rest}; {error, nil} -> {<<"\\u"/utf8, Hex@1/binary>>, Rest} end; {error, nil} -> {<<"\\u"/utf8, Hex@1/binary>>, Rest} end. -file("src/molt/internal/utils.gleam", 199). ?DOC(false). -spec interpret_basic_string_escape(list(binary())) -> {binary(), list(binary())}. interpret_basic_string_escape(Input) -> case Input of [] -> {<<"\\"/utf8>>, []}; [<<"b"/utf8>> | Rest] -> {<<"\x{0008}"/utf8>>, Rest}; [<<"t"/utf8>> | Rest@1] -> {<<"\t"/utf8>>, Rest@1}; [<<"n"/utf8>> | Rest@2] -> {<<"\n"/utf8>>, Rest@2}; [<<"f"/utf8>> | Rest@3] -> {<<"\x{000C}"/utf8>>, Rest@3}; [<<"r"/utf8>> | Rest@4] -> {<<"\r"/utf8>>, Rest@4}; [<<"\""/utf8>> | Rest@5] -> {<<"\""/utf8>>, Rest@5}; [<<"\\"/utf8>> | Rest@6] -> {<<"\\"/utf8>>, Rest@6}; [<<"u"/utf8>> | Rest@7] -> decode_unicode(Rest@7, 4); [<<"U"/utf8>> | Rest@8] -> decode_unicode(Rest@8, 8); [<<"x"/utf8>> | Rest@9] -> decode_unicode(Rest@9, 2); _ -> case skip_line_continuation(Input) of {some, Rest@10} -> {<<""/utf8>>, Rest@10}; none -> case Input of [Ch | Rest@11] -> {<<"\\"/utf8, Ch/binary>>, Rest@11}; [] -> {<<"\\"/utf8>>, []} end end end. -file("src/molt/internal/utils.gleam", 185). ?DOC(false). -spec do_unescape_basic_string(list(binary()), list(binary())) -> list(binary()). do_unescape_basic_string(S, Acc) -> case S of [] -> lists:reverse(Acc); [<<"\\"/utf8>> | Rest] -> {Ch, Rest@1} = interpret_basic_string_escape(Rest), do_unescape_basic_string(Rest@1, [Ch | Acc]); [Ch@1 | Rest@2] -> do_unescape_basic_string(Rest@2, [Ch@1 | Acc]) end. -file("src/molt/internal/utils.gleam", 179). ?DOC(false). -spec unescape_basic_string(binary()) -> binary(). unescape_basic_string(S) -> _pipe = gleam@string:to_graphemes(S), _pipe@1 = do_unescape_basic_string(_pipe, []), erlang:list_to_binary(_pipe@1).