-module(glanoid). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([make_generator/1]). -spec fix4(fun((fun((FNB, FNC, FND, FNE) -> FNK), FNB, FNC, FND, FNE) -> FNK)) -> fun((FNB, FNC, FND, FNE) -> FNK). fix4(F) -> fun(A, B, C, D) -> F(fix4(F), A, B, C, D) end. -spec do_bit_size(integer(), integer()) -> integer(). do_bit_size(N, Acc) -> case N of 0 -> Acc; _ -> do_bit_size(erlang:'bsr'(N, 1), Acc + 1) end. -spec bit_size(integer()) -> integer(). bit_size(N) -> do_bit_size(N, 0). -spec make_generator(binary()) -> {ok, fun((integer()) -> binary())} | {error, nil}. make_generator(Alphabet) -> gleam@bool:guard( gleam@string:length(Alphabet) =:= 0, {error, nil}, fun() -> Bit_mask = begin _pipe = Alphabet, _pipe@1 = gleam@string:length(_pipe), _pipe@2 = gleam@int:subtract(_pipe@1, 1), _pipe@3 = bit_size(_pipe@2), _pipe@4 = erlang:'bsl'(2, _pipe@3), gleam@int:subtract(_pipe@4, 1) end, To_alphabet@1 = fix4( fun(To_alphabet, Bits, Size, Alphabet@1, Acc) -> case {gleam@string:length(Acc) =:= Size, Bits} of {true, _} -> Acc; {false, <>} -> Index = erlang:'band'(X, Bit_mask), Letter = gleam@string:slice(Alphabet@1, Index, 1), case Letter of <<""/utf8>> -> To_alphabet(Rest, Size, Alphabet@1, Acc); _ -> To_alphabet( Rest, Size, Alphabet@1, <> ) end; {false, <<>>} -> To_alphabet( crypto:strong_rand_bytes(Size * 2), Size, Alphabet@1, Acc ); {_, _} -> erlang:error(#{gleam_error => panic, message => <<"panic expression evaluated"/utf8>>, module => <<"glanoid"/utf8>>, function => <<"make_generator"/utf8>>, line => 48}) end end ), {ok, fun(Size@1) -> _pipe@5 = crypto:strong_rand_bytes(Size@1 * 2), To_alphabet@1(_pipe@5, Size@1, Alphabet, <<""/utf8>>) end} end ).