Packages

Base-X encoding and decoding in Gleam!

Current section

Files

Jump to
base_x_gleam src base_x_gleam.erl
Raw

src/base_x_gleam.erl

-module(base_x_gleam).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([generate/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.
-file("src/base_x_gleam.gleam", 36).
-spec recurse_encode(
integer(),
gleam@dict:dict(integer(), binary()),
integer(),
binary()
) -> binary().
recurse_encode(Remaining_input, Alphabet_map, Alphabet_length, Acc) ->
Remainder = case Alphabet_length of
0 -> 0;
Gleam@denominator -> Remaining_input rem Gleam@denominator
end,
Input_rest = case Alphabet_length of
0 -> 0;
Gleam@denominator@1 -> Remaining_input div Gleam@denominator@1
end,
_assert_subject = gleam_stdlib:map_get(Alphabet_map, Remainder),
{ok, Next_char} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail,
module => <<"base_x_gleam"/utf8>>,
function => <<"recurse_encode"/utf8>>,
line => 45})
end,
New_acc = <<Next_char/binary, Acc/binary>>,
case Input_rest of
0 ->
New_acc;
_ ->
recurse_encode(Input_rest, Alphabet_map, Alphabet_length, New_acc)
end.
-file("src/base_x_gleam.gleam", 71).
-spec alphabet_to_map(list(binary())) -> gleam@dict:dict(integer(), binary()).
alphabet_to_map(Alphabet) ->
_pipe = Alphabet,
gleam@list:index_fold(
_pipe,
maps:new(),
fun(Acc, Letter, Index) -> gleam@dict:insert(Acc, Index, Letter) end
).
-file("src/base_x_gleam.gleam", 78).
-spec map_reverse(gleam@dict:dict(EZZ, FAA)) -> gleam@dict:dict(FAA, EZZ).
map_reverse(Map) ->
Keys = maps:keys(Map),
Values = maps:values(Map),
_assert_subject = gleam@list:strict_zip(Values, Keys),
{ok, Zipped} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail,
module => <<"base_x_gleam"/utf8>>,
function => <<"map_reverse"/utf8>>,
line => 81})
end,
maps:from_list(Zipped).
-file("src/base_x_gleam.gleam", 26).
-spec encode(bitstring(), gleam@dict:dict(integer(), binary()), integer()) -> binary().
encode(Input, Alphabet_map, Alphabet_size) ->
_pipe = Input,
_pipe@1 = binary:decode_unsigned(_pipe),
recurse_encode(_pipe@1, Alphabet_map, Alphabet_size, <<""/utf8>>).
-file("src/base_x_gleam.gleam", 55).
-spec decode(binary(), gleam@dict:dict(binary(), integer()), integer()) -> {ok,
bitstring()} |
{error, nil}.
decode(Input, Reverse_alphabet_map, Alphabet_size) ->
_pipe@1 = begin
gleam@list:try_fold(
begin
_pipe = Input,
gleam@string:to_graphemes(_pipe)
end,
0,
fun(Acc, Current_letter) ->
gleam@result:'try'(
gleam_stdlib:map_get(Reverse_alphabet_map, Current_letter),
fun(Character_value) ->
{ok, (Acc * Alphabet_size) + Character_value}
end
)
end
)
end,
gleam@result:map(_pipe@1, fun(Integer_result) -> _pipe@2 = Integer_result,
binary:encode_unsigned(_pipe@2) end).
-file("src/base_x_gleam.gleam", 8).
?DOC(" Returns a tuple containing the encoding and decoding functions.\n").
-spec generate(binary()) -> {ok,
{fun((bitstring()) -> binary()),
fun((binary()) -> {ok, bitstring()} | {error, nil})}} |
{error, nil}.
generate(Alphabet) ->
gleam@bool:guard(
string:length(Alphabet) =< 2,
{error, nil},
fun() ->
Alphabet_list = gleam@string:to_graphemes(Alphabet),
gleam@bool:guard(
begin
_pipe = Alphabet_list,
erlang:length(_pipe)
end
/= begin
_pipe@1 = Alphabet_list,
_pipe@2 = gleam@list:unique(_pipe@1),
erlang:length(_pipe@2)
end,
{error, nil},
fun() ->
Alphabet_map = alphabet_to_map(Alphabet_list),
Reverse_alphabet_map = map_reverse(Alphabet_map),
Alphabet_size = maps:size(Alphabet_map),
Encoder = fun(_capture) ->
encode(_capture, Alphabet_map, Alphabet_size)
end,
Decoder = fun(_capture@1) ->
decode(_capture@1, Reverse_alphabet_map, Alphabet_size)
end,
{ok, {Encoder, Decoder}}
end
)
end
).