Packages
Typed distributed messaging for Gleam on the BEAM.
Retired package: Deprecated - The project needs to be redesigned around a much smaller and clearer core.
Current section
Files
Jump to
Current section
Files
src/distribute@codec@builder.erl
-module(distribute@codec@builder).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/distribute/codec/builder.gleam").
-export([custom2/6, custom3/8, enum_codec/2]).
-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/distribute/codec/builder.gleam", 10).
?DOC(" Build a codec for a custom type with 2 fields.\n").
-spec custom2(
fun((IGR) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}),
fun((IGT) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}),
fun((bitstring()) -> {ok, IGR} | {error, distribute@codec:decode_error()}),
fun((bitstring()) -> {ok, IGT} | {error, distribute@codec:decode_error()}),
fun((IGR, IGT) -> IGX),
fun((IGX) -> {IGR, IGT})
) -> {fun((IGX) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}),
fun((bitstring()) -> {ok, IGX} | {error, distribute@codec:decode_error()})}.
custom2(Encoder1, Encoder2, Decoder1, Decoder2, Constructor, Destructor) ->
Encoder = fun(Value) ->
{Field1, Field2} = Destructor(Value),
gleam@result:'try'(
distribute@codec:encode(Encoder1, Field1),
fun(Enc1) ->
gleam@result:'try'(
distribute@codec:encode(Encoder2, Field2),
fun(Enc2) ->
Len1 = erlang:byte_size(Enc1),
Len2 = erlang:byte_size(Enc2),
{ok,
<<Len1:32, Enc1/bitstring, Len2:32, Enc2/bitstring>>}
end
)
end
)
end,
Decoder = fun(Binary) -> case Binary of
<<Len1@1:32, Rest/bitstring>> ->
case gleam_stdlib:bit_array_slice(Rest, 0, Len1@1) of
{ok, Enc1@1} ->
case gleam_stdlib:bit_array_slice(
Rest,
Len1@1,
erlang:byte_size(Rest) - Len1@1
) of
{ok, Remaining} ->
case Remaining of
<<Len2@1:32, Rest2/bitstring>> ->
case gleam_stdlib:bit_array_slice(
Rest2,
0,
Len2@1
) of
{ok, Enc2@1} ->
gleam@result:'try'(
distribute@codec:decode(
Decoder1,
Enc1@1
),
fun(Field1@1) ->
gleam@result:'try'(
distribute@codec:decode(
Decoder2,
Enc2@1
),
fun(Field2@1) ->
{ok,
Constructor(
Field1@1,
Field2@1
)}
end
)
end
);
{error, _} ->
{error,
{insufficient_data,
<<"Field 2 truncated"/utf8>>}}
end;
_ ->
{error,
{invalid_binary,
<<"Missing field 2 length"/utf8>>}}
end;
{error, _} ->
{error,
{insufficient_data,
<<"Field 1 truncated"/utf8>>}}
end;
{error, _} ->
{error,
{insufficient_data, <<"Field 1 truncated"/utf8>>}}
end;
_ ->
{error, {invalid_binary, <<"Missing field 1 length"/utf8>>}}
end end,
{Encoder, Decoder}.
-file("src/distribute/codec/builder.gleam", 67).
?DOC(" Build a codec for a custom type with 3 fields.\n").
-spec custom3(
fun((IHA) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}),
fun((IHC) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}),
fun((IHE) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}),
fun((bitstring()) -> {ok, IHA} | {error, distribute@codec:decode_error()}),
fun((bitstring()) -> {ok, IHC} | {error, distribute@codec:decode_error()}),
fun((bitstring()) -> {ok, IHE} | {error, distribute@codec:decode_error()}),
fun((IHA, IHC, IHE) -> IHJ),
fun((IHJ) -> {IHA, IHC, IHE})
) -> {fun((IHJ) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}),
fun((bitstring()) -> {ok, IHJ} | {error, distribute@codec:decode_error()})}.
custom3(
Encoder1,
Encoder2,
Encoder3,
Decoder1,
Decoder2,
Decoder3,
Constructor,
Destructor
) ->
Encoder = fun(Value) ->
{F1, F2, F3} = Destructor(Value),
gleam@result:'try'(
distribute@codec:encode(Encoder1, F1),
fun(Enc1) ->
gleam@result:'try'(
distribute@codec:encode(Encoder2, F2),
fun(Enc2) ->
gleam@result:'try'(
distribute@codec:encode(Encoder3, F3),
fun(Enc3) ->
Len1 = erlang:byte_size(Enc1),
Len2 = erlang:byte_size(Enc2),
Len3 = erlang:byte_size(Enc3),
{ok,
<<Len1:32,
Enc1/bitstring,
Len2:32,
Enc2/bitstring,
Len3:32,
Enc3/bitstring>>}
end
)
end
)
end
)
end,
Decoder = fun(Binary) -> case Binary of
<<Len1@1:32,
F1_data:Len1@1/binary,
Len2@1:32,
F2_data:Len2@1/binary,
Len3@1:32,
F3_data:Len3@1/binary>> ->
gleam@result:'try'(
distribute@codec:decode(Decoder1, F1_data),
fun(Field1) ->
gleam@result:'try'(
distribute@codec:decode(Decoder2, F2_data),
fun(Field2) ->
gleam@result:'try'(
distribute@codec:decode(Decoder3, F3_data),
fun(Field3) ->
{ok,
Constructor(Field1, Field2, Field3)}
end
)
end
)
end
);
_ ->
{error,
{invalid_binary,
<<"Invalid 3-field custom type format"/utf8>>}}
end end,
{Encoder, Decoder}.
-file("src/distribute/codec/builder.gleam", 115).
?DOC(" Build a codec for an enum (variant type without payloads).\n").
-spec enum_codec(
fun((IHM) -> integer()),
fun((integer()) -> {ok, IHM} | {error, nil})
) -> {fun((IHM) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}),
fun((bitstring()) -> {ok, IHM} | {error, distribute@codec:decode_error()})}.
enum_codec(To_int, From_int) ->
Encoder = fun(Value) ->
Tag = To_int(Value),
distribute@codec:encode(distribute@codec:int_encoder(), Tag)
end,
Decoder = fun(Binary) ->
gleam@result:'try'(
distribute@codec:decode(distribute@codec:int_decoder(), Binary),
fun(Tag@1) ->
gleam@result:'try'(
begin
_pipe = From_int(Tag@1),
gleam@result:replace_error(
_pipe,
{type_mismatch, <<"Unknown enum variant"/utf8>>}
)
end,
fun(Variant) -> {ok, Variant} end
)
end
)
end,
{Encoder, Decoder}.