-module(apiculture@key). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/apiculture/key.gleam"). -export([new/0, with_random_bytes/2, with_random_chars/2, with_alphabet/2, with_encoding/2, with_prefix/2, with_separator/2, with_checksum/2, with_checksum_bytes/2, without_checksum/1, generate/1, from_bytes/2, from_uuid_with/2, from_uuid/1, from_ulid_with/2, from_ulid/1, value/1, bytes/1]). -export_type([key_config/0, key/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. -type key_config() :: {key_config, gleam@option:option(integer()), gleam@option:option(integer()), gleam@option:option(apiculture@alphabet:alphabet()), gleam@option:option(apiculture@encoding:encoding()), gleam@option:option(binary()), gleam@option:option(binary()), gleam@option:option(apiculture@checksum:checksum()), gleam@option:option(integer())}. -type key() :: {key, binary(), bitstring()}. -file("src/apiculture/key.gleam", 36). -spec new() -> key_config(). new() -> {key_config, none, none, none, none, none, none, none, none}. -file("src/apiculture/key.gleam", 49). -spec with_random_bytes(key_config(), integer()) -> key_config(). with_random_bytes(Config, Count) -> {key_config, {some, Count}, erlang:element(3, Config), erlang:element(4, Config), erlang:element(5, Config), erlang:element(6, Config), erlang:element(7, Config), erlang:element(8, Config), erlang:element(9, Config)}. -file("src/apiculture/key.gleam", 53). -spec with_random_chars(key_config(), integer()) -> key_config(). with_random_chars(Config, Count) -> {key_config, erlang:element(2, Config), {some, Count}, erlang:element(4, Config), erlang:element(5, Config), erlang:element(6, Config), erlang:element(7, Config), erlang:element(8, Config), erlang:element(9, Config)}. -file("src/apiculture/key.gleam", 57). -spec with_alphabet(key_config(), apiculture@alphabet:alphabet()) -> key_config(). with_alphabet(Config, Alphabet) -> {key_config, erlang:element(2, Config), erlang:element(3, Config), {some, Alphabet}, erlang:element(5, Config), erlang:element(6, Config), erlang:element(7, Config), erlang:element(8, Config), erlang:element(9, Config)}. -file("src/apiculture/key.gleam", 61). -spec with_encoding(key_config(), apiculture@encoding:encoding()) -> key_config(). with_encoding(Config, Encoding) -> {key_config, erlang:element(2, Config), erlang:element(3, Config), erlang:element(4, Config), {some, Encoding}, erlang:element(6, Config), erlang:element(7, Config), erlang:element(8, Config), erlang:element(9, Config)}. -file("src/apiculture/key.gleam", 65). -spec with_prefix(key_config(), binary()) -> key_config(). with_prefix(Config, Prefix) -> {key_config, erlang:element(2, Config), erlang:element(3, Config), erlang:element(4, Config), erlang:element(5, Config), {some, Prefix}, erlang:element(7, Config), erlang:element(8, Config), erlang:element(9, Config)}. -file("src/apiculture/key.gleam", 69). -spec with_separator(key_config(), binary()) -> key_config(). with_separator(Config, Separator) -> {key_config, erlang:element(2, Config), erlang:element(3, Config), erlang:element(4, Config), erlang:element(5, Config), erlang:element(6, Config), {some, Separator}, erlang:element(8, Config), erlang:element(9, Config)}. -file("src/apiculture/key.gleam", 73). -spec with_checksum(key_config(), apiculture@checksum:checksum()) -> key_config(). with_checksum(Config, Checksum) -> {key_config, erlang:element(2, Config), erlang:element(3, Config), erlang:element(4, Config), erlang:element(5, Config), erlang:element(6, Config), erlang:element(7, Config), {some, Checksum}, erlang:element(9, Config)}. -file("src/apiculture/key.gleam", 77). -spec with_checksum_bytes(key_config(), integer()) -> key_config(). with_checksum_bytes(Config, Count) -> {key_config, erlang:element(2, Config), erlang:element(3, Config), erlang:element(4, Config), erlang:element(5, Config), erlang:element(6, Config), erlang:element(7, Config), erlang:element(8, Config), {some, Count}}. -file("src/apiculture/key.gleam", 81). -spec without_checksum(key_config()) -> key_config(). without_checksum(Config) -> {key_config, erlang:element(2, Config), erlang:element(3, Config), erlang:element(4, Config), erlang:element(5, Config), erlang:element(6, Config), erlang:element(7, Config), none, none}. -file("src/apiculture/key.gleam", 414). -spec hex_digit(integer()) -> binary(). hex_digit(Nibble) -> case Nibble of 0 -> <<"0"/utf8>>; 1 -> <<"1"/utf8>>; 2 -> <<"2"/utf8>>; 3 -> <<"3"/utf8>>; 4 -> <<"4"/utf8>>; 5 -> <<"5"/utf8>>; 6 -> <<"6"/utf8>>; 7 -> <<"7"/utf8>>; 8 -> <<"8"/utf8>>; 9 -> <<"9"/utf8>>; 10 -> <<"a"/utf8>>; 11 -> <<"b"/utf8>>; 12 -> <<"c"/utf8>>; 13 -> <<"d"/utf8>>; 14 -> <<"e"/utf8>>; 15 -> <<"f"/utf8>>; _ -> <<""/utf8>> end. -file("src/apiculture/key.gleam", 408). -spec int_to_hex(integer()) -> binary(). int_to_hex(Byte) -> Nibble_high = Byte div 16, Nibble_low = Byte rem 16, <<(hex_digit(Nibble_high))/binary, (hex_digit(Nibble_low))/binary>>. -file("src/apiculture/key.gleam", 397). -spec do_bytes_to_hex(bitstring(), list(binary())) -> list(binary()). do_bytes_to_hex(Bytes, Acc) -> case Bytes of <<>> -> Acc; <> -> Hex = int_to_hex(Byte), do_bytes_to_hex(Rest, [Hex | Acc]); _ -> Acc end. -file("src/apiculture/key.gleam", 390). -spec bytes_to_hex(bitstring()) -> binary(). bytes_to_hex(Bytes) -> _pipe = Bytes, _pipe@1 = do_bytes_to_hex(_pipe, []), _pipe@2 = lists:reverse(_pipe@1), erlang:list_to_binary(_pipe@2). -file("src/apiculture/key.gleam", 170). -spec encode_bytes_with_config(bitstring(), key_config()) -> binary(). encode_bytes_with_config(Bytes, Config) -> case erlang:element(5, Config) of {some, Enc} -> apiculture@encoding:encode(Enc, Bytes); none -> bytes_to_hex(Bytes) end. -file("src/apiculture/key.gleam", 122). -spec generate_from_bytes(key_config()) -> {ok, key()} | {error, apiculture@error:error()}. generate_from_bytes(Config) -> case erlang:element(2, Config) of {some, Byte_count} -> case apiculture@random:random_bytes(Byte_count) of {ok, Bytes} -> Encoded = encode_bytes_with_config(Bytes, Config), {ok, {key, Encoded, Bytes}}; {error, E} -> {error, E} end; none -> {error, invalid_byte_count} end. -file("src/apiculture/key.gleam", 224). -spec encode_checksum(bitstring(), key_config()) -> binary(). encode_checksum(Crc_bytes, Config) -> case erlang:element(5, Config) of {some, Enc} -> apiculture@encoding:encode(Enc, Crc_bytes); none -> bytes_to_hex(Crc_bytes) end. -file("src/apiculture/key.gleam", 205). -spec drop_first_bytes(bitstring(), integer()) -> bitstring(). drop_first_bytes(Bytes, N) -> case N of 0 -> Bytes; _ -> case Bytes of <<_, Rest/binary>> -> drop_first_bytes(Rest, N - 1); _ -> <<>> end end. -file("src/apiculture/key.gleam", 198). -spec truncate_checksum(bitstring(), gleam@option:option(integer())) -> bitstring(). truncate_checksum(Bytes, Byte_count) -> case Byte_count of {some, Count} -> drop_first_bytes(Bytes, erlang:byte_size(Bytes) - Count); none -> Bytes end. -file("src/apiculture/key.gleam", 177). -spec format_key(binary(), bitstring(), key_config()) -> binary(). format_key(Content, Bytes, Config) -> Prefixed = case erlang:element(6, Config) of {some, Prefix} -> Sep = begin _pipe = erlang:element(7, Config), gleam@option:unwrap(_pipe, <<""/utf8>>) end, <<<>/binary, Content/binary>>; none -> Content end, case erlang:element(8, Config) of {some, Chk} -> Checksum = (erlang:element(2, Chk))(Bytes), Checksum_truncated = truncate_checksum( Checksum, erlang:element(9, Config) ), Checksum_encoded = encode_checksum(Checksum_truncated, Config), <>; none -> Prefixed end. -file("src/apiculture/key.gleam", 154). -spec generate_from_encoding(key_config()) -> {ok, key()} | {error, apiculture@error:error()}. generate_from_encoding(Config) -> case {erlang:element(2, Config), erlang:element(5, Config)} of {{some, Byte_count}, {some, Encoding}} -> case apiculture@random:random_bytes(Byte_count) of {ok, Bytes} -> Encoded = apiculture@encoding:encode(Encoding, Bytes), Formatted = format_key(Encoded, Bytes, Config), {ok, {key, Formatted, Bytes}}; {error, E} -> {error, E} end; {_, _} -> {error, invalid_byte_count} end. -file("src/apiculture/key.gleam", 382). -spec get_nth(integer(), list(binary())) -> binary(). get_nth(N, Items) -> case {N, Items} of {0, [First | _]} -> First; {_, [_ | Rest]} -> get_nth(N - 1, Rest); {_, []} -> <<""/utf8>> end. -file("src/apiculture/key.gleam", 370). -spec chars_from_indices(list(integer()), apiculture@alphabet:alphabet()) -> binary(). chars_from_indices(Indices, Alphabet) -> Char_list = apiculture@alphabet:characters(Alphabet), _pipe = Indices, _pipe@1 = gleam@list:map( _pipe, fun(Index) -> case (Index >= 0) andalso (Index < erlang:length(Char_list)) of true -> get_nth(Index, Char_list); false -> <<""/utf8>> end end ), erlang:list_to_binary(_pipe@1). -file("src/apiculture/key.gleam", 137). -spec generate_from_alphabet(key_config()) -> {ok, key()} | {error, apiculture@error:error()}. generate_from_alphabet(Config) -> case {erlang:element(3, Config), erlang:element(4, Config)} of {{some, Char_count}, {some, Alphabet}} -> case apiculture@random:random_chars(Alphabet, Char_count) of {ok, Indices} -> Chars = chars_from_indices(Indices, Alphabet), Bytes = gleam_stdlib:identity(Chars), Formatted = format_key(Chars, Bytes, Config), {ok, {key, Formatted, Bytes}}; {error, E} -> {error, E} end; {_, _} -> {error, invalid_byte_count} end. -file("src/apiculture/key.gleam", 85). -spec generate(key_config()) -> {ok, key()} | {error, apiculture@error:error()}. generate(Config) -> case {erlang:element(2, Config), erlang:element(3, Config), erlang:element(4, Config), erlang:element(5, Config)} of {none, {some, _}, {some, _}, none} -> generate_from_alphabet(Config); {{some, _}, none, none, {some, _}} -> generate_from_encoding(Config); {{some, _}, none, none, none} -> generate_from_bytes(Config); {_, _, _, _} -> {error, invalid_byte_count} end. -file("src/apiculture/key.gleam", 94). -spec from_bytes(key_config(), bitstring()) -> {ok, key()} | {error, apiculture@error:error()}. from_bytes(Config, Bytes) -> Encoded = encode_bytes_with_config(Bytes, Config), Formatted = format_key(Encoded, Bytes, Config), {ok, {key, Formatted, Bytes}}. -file("src/apiculture/key.gleam", 217). -spec default_import_config() -> key_config(). default_import_config() -> _pipe = new(), _pipe@1 = with_encoding(_pipe, apiculture@encoding:base62()), _pipe@2 = with_checksum(_pipe@1, apiculture@checksum:crc32_checksum()), with_checksum_bytes(_pipe@2, 4). -file("src/apiculture/key.gleam", 231). -spec parse_uuid_bytes(binary()) -> {ok, bitstring()} | {error, apiculture@error:error()}. parse_uuid_bytes(Input) -> Normalized = begin _pipe = Input, _pipe@1 = string:lowercase(_pipe), _pipe@2 = gleam@string:replace( _pipe@1, <<"urn:uuid:"/utf8>>, <<""/utf8>> ), gleam@string:replace(_pipe@2, <<"-"/utf8>>, <<""/utf8>>) end, case string:length(Normalized) =:= 32 of false -> {error, malformed_input}; true -> case apiculture@encoding:decode( apiculture@encoding:hex_lower(), Normalized ) of {ok, Bytes} -> case erlang:byte_size(Bytes) =:= 16 of true -> {ok, Bytes}; false -> {error, malformed_input} end; _ -> {error, malformed_input} end end. -file("src/apiculture/key.gleam", 104). -spec from_uuid_with(key_config(), binary()) -> {ok, key()} | {error, apiculture@error:error()}. from_uuid_with(Config, Input) -> case parse_uuid_bytes(Input) of {ok, Bytes} -> from_bytes(Config, Bytes); {error, E} -> {error, E} end. -file("src/apiculture/key.gleam", 100). -spec from_uuid(binary()) -> {ok, key()} | {error, apiculture@error:error()}. from_uuid(Input) -> from_uuid_with(default_import_config(), Input). -file("src/apiculture/key.gleam", 356). -spec low_bits_mask(integer()) -> integer(). low_bits_mask(Bit_count) -> case Bit_count of 0 -> 0; _ -> erlang:'bsl'(1, Bit_count) - 1 end. -file("src/apiculture/key.gleam", 318). -spec ulid_char_value(binary()) -> {ok, integer()} | {error, apiculture@error:error()}. ulid_char_value(Char) -> case Char of <<"0"/utf8>> -> {ok, 0}; <<"O"/utf8>> -> {ok, 0}; <<"1"/utf8>> -> {ok, 1}; <<"I"/utf8>> -> {ok, 1}; <<"L"/utf8>> -> {ok, 1}; <<"2"/utf8>> -> {ok, 2}; <<"3"/utf8>> -> {ok, 3}; <<"4"/utf8>> -> {ok, 4}; <<"5"/utf8>> -> {ok, 5}; <<"6"/utf8>> -> {ok, 6}; <<"7"/utf8>> -> {ok, 7}; <<"8"/utf8>> -> {ok, 8}; <<"9"/utf8>> -> {ok, 9}; <<"A"/utf8>> -> {ok, 10}; <<"B"/utf8>> -> {ok, 11}; <<"C"/utf8>> -> {ok, 12}; <<"D"/utf8>> -> {ok, 13}; <<"E"/utf8>> -> {ok, 14}; <<"F"/utf8>> -> {ok, 15}; <<"G"/utf8>> -> {ok, 16}; <<"H"/utf8>> -> {ok, 17}; <<"J"/utf8>> -> {ok, 18}; <<"K"/utf8>> -> {ok, 19}; <<"M"/utf8>> -> {ok, 20}; <<"N"/utf8>> -> {ok, 21}; <<"P"/utf8>> -> {ok, 22}; <<"Q"/utf8>> -> {ok, 23}; <<"R"/utf8>> -> {ok, 24}; <<"S"/utf8>> -> {ok, 25}; <<"T"/utf8>> -> {ok, 26}; <<"V"/utf8>> -> {ok, 27}; <<"W"/utf8>> -> {ok, 28}; <<"X"/utf8>> -> {ok, 29}; <<"Y"/utf8>> -> {ok, 30}; <<"Z"/utf8>> -> {ok, 31}; _ -> {error, malformed_input} end. -file("src/apiculture/key.gleam", 363). -spec ints_to_bytes(list(integer())) -> bitstring(). ints_to_bytes(Ints) -> case Ints of [] -> <<>>; [First | Rest] -> gleam@bit_array:append(<>, ints_to_bytes(Rest)) end. -file("src/apiculture/key.gleam", 277). -spec decode_ulid_chars(list(binary()), integer(), integer(), list(integer())) -> {ok, bitstring()} | {error, apiculture@error:error()}. decode_ulid_chars(Chars, Acc, Bit_count, Out) -> case Chars of [] -> case ((erlang:length(Out) =:= 16) andalso (Bit_count =:= 0)) andalso (Acc =:= 0) of true -> {ok, ints_to_bytes(lists:reverse(Out))}; false -> {error, malformed_input} end; [Char | Rest] -> case ulid_char_value(Char) of {ok, Value} -> Next_acc = (Acc * 32) + Value, Next_bit_count = Bit_count + 5, case Next_bit_count >= 8 of true -> Remaining_bits = Next_bit_count - 8, Byte = begin _pipe = Next_acc, _pipe@1 = erlang:'bsr'(_pipe, Remaining_bits), erlang:'band'(_pipe@1, 255) end, Remaining = erlang:'band'( Next_acc, low_bits_mask(Remaining_bits) ), decode_ulid_chars( Rest, Remaining, Remaining_bits, [Byte | Out] ); false -> decode_ulid_chars( Rest, Next_acc, Next_bit_count, Out ) end; {error, E} -> {error, E} end end. -file("src/apiculture/key.gleam", 252). -spec parse_ulid_bytes(binary()) -> {ok, bitstring()} | {error, apiculture@error:error()}. parse_ulid_bytes(Input) -> Chars = begin _pipe = Input, _pipe@1 = string:uppercase(_pipe), gleam@string:to_graphemes(_pipe@1) end, case erlang:length(Chars) =:= 26 of false -> {error, malformed_input}; true -> case Chars of [First | Rest] -> case ulid_char_value(First) of {ok, Value} -> case Value =< 7 of true -> decode_ulid_chars(Rest, Value, 3, []); false -> {error, malformed_input} end; _ -> {error, malformed_input} end; [] -> {error, malformed_input} end end. -file("src/apiculture/key.gleam", 115). -spec from_ulid_with(key_config(), binary()) -> {ok, key()} | {error, apiculture@error:error()}. from_ulid_with(Config, Input) -> case parse_ulid_bytes(Input) of {ok, Bytes} -> from_bytes(Config, Bytes); {error, E} -> {error, E} end. -file("src/apiculture/key.gleam", 111). -spec from_ulid(binary()) -> {ok, key()} | {error, apiculture@error:error()}. from_ulid(Input) -> from_ulid_with(default_import_config(), Input). -file("src/apiculture/key.gleam", 437). ?DOC(" Returns the string value of the key.\n"). -spec value(key()) -> binary(). value(Key) -> erlang:element(2, Key). -file("src/apiculture/key.gleam", 442). ?DOC(" Returns the raw bytes that were used to generate the key.\n"). -spec bytes(key()) -> bitstring(). bytes(Key) -> erlang:element(3, Key).