-module(distribute@codec@composite). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/distribute/codec/composite.gleam"). -export([result_sized_decoder/2, result_decoder/2, result_encoder/2, result/2, option_encoder/1, option_decoder/1, option/1, option_sized_decoder/1, tuple2_encoder/2, tuple2_sized_decoder/2, tuple2_decoder/2, tuple3_encoder/3, tuple3_sized_decoder/3, tuple3_decoder/3, tuple2/2, tuple3/3]). -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/composite.gleam", 85). -spec result_sized_decoder( fun((bitstring()) -> {ok, {IFG, bitstring()}} | {error, distribute@codec:decode_error()}), fun((bitstring()) -> {ok, {IFI, bitstring()}} | {error, distribute@codec:decode_error()}) ) -> fun((bitstring()) -> {ok, {{ok, IFG} | {error, IFI}, bitstring()}} | {error, distribute@codec:decode_error()}). result_sized_decoder(Ok_decoder, Error_decoder) -> fun(Data) -> case Data of <<0, Rest/binary>> -> gleam@result:'try'( Ok_decoder(Rest), fun(_use0) -> {Value, Remaining} = _use0, {ok, {{ok, Value}, Remaining}} end ); <<1, Rest@1/binary>> -> gleam@result:'try'( Error_decoder(Rest@1), fun(_use0@1) -> {Err, Remaining@1} = _use0@1, {ok, {{error, Err}, Remaining@1}} end ); _ -> {error, {invalid_binary, <<"invalid result tag"/utf8>>}} end end. -file("src/distribute/codec/composite.gleam", 104). -spec result_decoder( fun((bitstring()) -> {ok, IFN} | {error, distribute@codec:decode_error()}), fun((bitstring()) -> {ok, IFP} | {error, distribute@codec:decode_error()}) ) -> fun((bitstring()) -> {ok, {ok, IFN} | {error, IFP}} | {error, distribute@codec:decode_error()}). result_decoder(Ok_decoder, Error_decoder) -> fun(Data) -> case Data of <<0, Rest/binary>> -> gleam@result:'try'( Ok_decoder(Rest), fun(Value) -> {ok, {ok, Value}} end ); <<1, Rest@1/binary>> -> gleam@result:'try'( Error_decoder(Rest@1), fun(Err) -> {ok, {error, Err}} end ); _ -> {error, {invalid_binary, <<"invalid result tag"/utf8>>}} end end. -file("src/distribute/codec/composite.gleam", 67). ?DOC(" Encoder for Result(a, e). Ok is 0x00 + encoded, Error is 0x01 + encoded.\n"). -spec result_encoder( fun((IEZ) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}), fun((IFB) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}) ) -> fun(({ok, IEZ} | {error, IFB}) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}). result_encoder(Ok_encoder, Error_encoder) -> fun(Res) -> case Res of {ok, Value} -> gleam@result:'try'( Ok_encoder(Value), fun(Encoded) -> {ok, gleam@bit_array:append(<<0>>, Encoded)} end ); {error, Err} -> gleam@result:'try'( Error_encoder(Err), fun(Encoded@1) -> {ok, gleam@bit_array:append(<<1>>, Encoded@1)} end ) end end. -file("src/distribute/codec/composite.gleam", 304). -spec result(distribute@codec:codec(IHG), distribute@codec:codec(IHI)) -> distribute@codec:codec({ok, IHG} | {error, IHI}). result(Ok_codec, Error_codec) -> {codec, result_encoder( erlang:element(2, Ok_codec), erlang:element(2, Error_codec) ), result_decoder( erlang:element(3, Ok_codec), erlang:element(3, Error_codec) ), result_sized_decoder( erlang:element(4, Ok_codec), erlang:element(4, Error_codec) )}. -file("src/distribute/codec/composite.gleam", 14). ?DOC(" Encoder for Option(a). None is 0x00, Some(v) is 0x01 + encoded value.\n"). -spec option_encoder( fun((IEN) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}) ) -> fun((gleam@option:option(IEN)) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}). option_encoder(Inner) -> fun(Opt) -> case Opt of none -> {ok, <<0>>}; {some, Value} -> gleam@result:'try'( Inner(Value), fun(Encoded) -> {ok, gleam@bit_array:append(<<1>>, Encoded)} end ) end end. -file("src/distribute/codec/composite.gleam", 47). ?DOC( " Strict top-level `Option(a)` decoder. `None` is one byte (`0`)\n" " followed by EOF; `Some(a)` is `1` followed by `a`'s encoded form.\n" "\n" " The earlier `<<0, _:bytes>>` pattern matched a `None` tag plus any\n" " number of trailing bytes, mirroring the smuggling vector that we\n" " closed inside `tuple2`/`tuple3`. The `Some` branch is already strict\n" " because `inner` is itself a top-level `Decoder(a)` (built via\n" " `to_decoder`).\n" ). -spec option_decoder( fun((bitstring()) -> {ok, IEV} | {error, distribute@codec:decode_error()}) ) -> fun((bitstring()) -> {ok, gleam@option:option(IEV)} | {error, distribute@codec:decode_error()}). option_decoder(Inner) -> fun(Data) -> case Data of <<0>> -> {ok, none}; <<0, _, _/binary>> -> {error, {invalid_binary, <<"trailing bytes after option None tag"/utf8>>}}; <<1, Rest/binary>> -> gleam@result:'try'( Inner(Rest), fun(Value) -> {ok, {some, Value}} end ); _ -> {error, {invalid_binary, <<"invalid option tag"/utf8>>}} end end. -file("src/distribute/codec/composite.gleam", 318). -spec option(distribute@codec:codec(IHN)) -> distribute@codec:codec(gleam@option:option(IHN)). option(Inner) -> {codec, option_encoder(erlang:element(2, Inner)), option_decoder(erlang:element(3, Inner)), option_sized_decoder(erlang:element(4, Inner))}. -file("src/distribute/codec/composite.gleam", 26). -spec option_sized_decoder( fun((bitstring()) -> {ok, {IER, bitstring()}} | {error, distribute@codec:decode_error()}) ) -> fun((bitstring()) -> {ok, {gleam@option:option(IER), bitstring()}} | {error, distribute@codec:decode_error()}). option_sized_decoder(Inner) -> fun(Data) -> case Data of <<0, Rest/binary>> -> {ok, {none, Rest}}; <<1, Rest@1/binary>> -> gleam@result:'try'( Inner(Rest@1), fun(_use0) -> {Value, Remaining} = _use0, {ok, {{some, Value}, Remaining}} end ); _ -> {error, {invalid_binary, <<"invalid option tag"/utf8>>}} end end. -file("src/distribute/codec/composite.gleam", 134). ?DOC( " Encoder for `#(a, b)`. First element is length-prefixed (32-bit).\n" "\n" " The length prefix is validated against the unsigned-32 bound. A\n" " first element larger than 4 GiB would silently truncate the prefix\n" " and corrupt the wire frame. Mirrors the bound enforced by\n" " `string_encoder` / `bitarray_encoder` / `list_encoder` /\n" " `subject_encoder` / `tagged.encoder`.\n" ). -spec tuple2_encoder( fun((IFU) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}), fun((IFW) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}) ) -> fun(({IFU, IFW}) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}). tuple2_encoder(First, Second) -> fun(Tuple) -> {A, B} = Tuple, gleam@result:'try'( First(A), fun(Encoded_a) -> gleam@result:'try'( Second(B), fun(Encoded_b) -> Len_a = erlang:byte_size(Encoded_a), gleam@result:'try'( distribute@codec:check_32bit_length( Len_a, <<"tuple2 first element"/utf8>> ), fun(_) -> {ok, gleam_stdlib:bit_array_concat( [<>, Encoded_a, Encoded_b] )} end ) end ) end ) end. -file("src/distribute/codec/composite.gleam", 279). ?DOC( " Reject data smuggled past the inner decoder. The slice we hand to the\n" " inner decoder is sized exactly to `len_a`/`len_b`; if the decoder\n" " returned remaining bytes, the encoder declared a slice longer than\n" " the value consumed. A hostile sender hiding payload inside the\n" " length-prefixed envelope. Surface as `InvalidBinary` instead of\n" " silently passing bytes through.\n" ). -spec reject_inner_trailing(bitstring(), binary()) -> {ok, nil} | {error, distribute@codec:decode_error()}. reject_inner_trailing(Rest, Where_label) -> case Rest of <<>> -> {ok, nil}; _ -> {error, {invalid_binary, <<<<"trailing bytes smuggled inside "/utf8, Where_label/binary>>/binary, " element"/utf8>>}} end. -file("src/distribute/codec/composite.gleam", 148). -spec tuple2_sized_decoder( fun((bitstring()) -> {ok, {IFZ, bitstring()}} | {error, distribute@codec:decode_error()}), fun((bitstring()) -> {ok, {IGB, bitstring()}} | {error, distribute@codec:decode_error()}) ) -> fun((bitstring()) -> {ok, {{IFZ, IGB}, bitstring()}} | {error, distribute@codec:decode_error()}). tuple2_sized_decoder(First, Second) -> fun(Data) -> case Data of <> -> Rest_size = erlang:byte_size(Rest), gleam@result:'try'( begin _pipe = gleam_stdlib:bit_array_slice(Rest, 0, Len_a), gleam@result:replace_error( _pipe, {insufficient_data, <<"tuple2 first"/utf8>>} ) end, fun(First_data) -> gleam@result:'try'( First(First_data), fun(_use0) -> {A, First_leftover} = _use0, gleam@result:'try'( reject_inner_trailing( First_leftover, <<"tuple2 first"/utf8>> ), fun(_) -> gleam@result:'try'( begin _pipe@1 = gleam_stdlib:bit_array_slice( Rest, Len_a, Rest_size - Len_a ), gleam@result:replace_error( _pipe@1, {insufficient_data, <<"tuple2 second"/utf8>>} ) end, fun(After_first) -> gleam@result:'try'( Second(After_first), fun(_use0@1) -> {B, Remaining} = _use0@1, {ok, {{A, B}, Remaining}} end ) end ) end ) end ) end ); _ -> {error, {invalid_binary, <<"missing tuple2 length prefix"/utf8>>}} end end. -file("src/distribute/codec/composite.gleam", 183). -spec tuple2_decoder( fun((bitstring()) -> {ok, {IGE, bitstring()}} | {error, distribute@codec:decode_error()}), fun((bitstring()) -> {ok, {IGG, bitstring()}} | {error, distribute@codec:decode_error()}) ) -> fun((bitstring()) -> {ok, {IGE, IGG}} | {error, distribute@codec:decode_error()}). tuple2_decoder(First, Second) -> distribute@codec:to_decoder(tuple2_sized_decoder(First, Second)). -file("src/distribute/codec/composite.gleam", 198). ?DOC( " Encoder for `#(a, b, c)`. First two elements are length-prefixed (32-bit).\n" "\n" " Both length prefixes are validated against the unsigned-32 bound;\n" " see `tuple2_encoder` for the rationale.\n" ). -spec tuple3_encoder( fun((IGJ) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}), fun((IGL) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}), fun((IGN) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}) ) -> fun(({IGJ, IGL, IGN}) -> {ok, bitstring()} | {error, distribute@codec:encode_error()}). tuple3_encoder(First, Second, Third) -> fun(Tuple) -> {A, B, C} = Tuple, gleam@result:'try'( First(A), fun(Encoded_a) -> gleam@result:'try'( Second(B), fun(Encoded_b) -> gleam@result:'try'( Third(C), fun(Encoded_c) -> Len_a = erlang:byte_size(Encoded_a), Len_b = erlang:byte_size(Encoded_b), gleam@result:'try'( distribute@codec:check_32bit_length( Len_a, <<"tuple3 first element"/utf8>> ), fun(_) -> gleam@result:'try'( distribute@codec:check_32bit_length( Len_b, <<"tuple3 second element"/utf8>> ), fun(_) -> {ok, gleam_stdlib:bit_array_concat( [<>, Encoded_a, <>, Encoded_b, Encoded_c] )} end ) end ) end ) end ) end ) end. -file("src/distribute/codec/composite.gleam", 224). -spec tuple3_sized_decoder( fun((bitstring()) -> {ok, {IGQ, bitstring()}} | {error, distribute@codec:decode_error()}), fun((bitstring()) -> {ok, {IGS, bitstring()}} | {error, distribute@codec:decode_error()}), fun((bitstring()) -> {ok, {IGU, bitstring()}} | {error, distribute@codec:decode_error()}) ) -> fun((bitstring()) -> {ok, {{IGQ, IGS, IGU}, bitstring()}} | {error, distribute@codec:decode_error()}). tuple3_sized_decoder(First, Second, Third) -> fun(Data) -> case Data of <> -> Rest_size = erlang:byte_size(Rest), gleam@result:'try'( begin _pipe = gleam_stdlib:bit_array_slice(Rest, 0, Len_a), gleam@result:replace_error( _pipe, {insufficient_data, <<"tuple3 first"/utf8>>} ) end, fun(First_data) -> gleam@result:'try'( First(First_data), fun(_use0) -> {A, First_leftover} = _use0, gleam@result:'try'( reject_inner_trailing( First_leftover, <<"tuple3 first"/utf8>> ), fun(_) -> gleam@result:'try'( begin _pipe@1 = gleam_stdlib:bit_array_slice( Rest, Len_a, Rest_size - Len_a ), gleam@result:replace_error( _pipe@1, {insufficient_data, <<"tuple3 after first"/utf8>>} ) end, fun(After_first) -> case After_first of <> -> Rest2_size = erlang:byte_size( Rest2 ), gleam@result:'try'( begin _pipe@2 = gleam_stdlib:bit_array_slice( Rest2, 0, Len_b ), gleam@result:replace_error( _pipe@2, {insufficient_data, <<"tuple3 second"/utf8>>} ) end, fun(Second_data) -> gleam@result:'try'( Second( Second_data ), fun(_use0@1) -> {B, Second_leftover} = _use0@1, gleam@result:'try'( reject_inner_trailing( Second_leftover, <<"tuple3 second"/utf8>> ), fun( _ ) -> gleam@result:'try'( begin _pipe@3 = gleam_stdlib:bit_array_slice( Rest2, Len_b, Rest2_size - Len_b ), gleam@result:replace_error( _pipe@3, {insufficient_data, <<"tuple3 third"/utf8>>} ) end, fun( Third_data ) -> gleam@result:'try'( Third( Third_data ), fun( _use0@2 ) -> {C, Remaining} = _use0@2, {ok, {{A, B, C}, Remaining}} end ) end ) end ) end ) end ); _ -> {error, {invalid_binary, <<"tuple3 missing second length"/utf8>>}} end end ) end ) end ) end ); _ -> {error, {invalid_binary, <<"tuple3 missing length"/utf8>>}} end end. -file("src/distribute/codec/composite.gleam", 292). -spec tuple3_decoder( fun((bitstring()) -> {ok, {IGZ, bitstring()}} | {error, distribute@codec:decode_error()}), fun((bitstring()) -> {ok, {IHB, bitstring()}} | {error, distribute@codec:decode_error()}), fun((bitstring()) -> {ok, {IHD, bitstring()}} | {error, distribute@codec:decode_error()}) ) -> fun((bitstring()) -> {ok, {IGZ, IHB, IHD}} | {error, distribute@codec:decode_error()}). tuple3_decoder(First, Second, Third) -> distribute@codec:to_decoder(tuple3_sized_decoder(First, Second, Third)). -file("src/distribute/codec/composite.gleam", 326). -spec tuple2(distribute@codec:codec(IHR), distribute@codec:codec(IHT)) -> distribute@codec:codec({IHR, IHT}). tuple2(First, Second) -> {codec, tuple2_encoder(erlang:element(2, First), erlang:element(2, Second)), tuple2_decoder(erlang:element(4, First), erlang:element(4, Second)), tuple2_sized_decoder( erlang:element(4, First), erlang:element(4, Second) )}. -file("src/distribute/codec/composite.gleam", 340). -spec tuple3( distribute@codec:codec(IHW), distribute@codec:codec(IHY), distribute@codec:codec(IIA) ) -> distribute@codec:codec({IHW, IHY, IIA}). tuple3(First, Second, Third) -> {codec, tuple3_encoder( erlang:element(2, First), erlang:element(2, Second), erlang:element(2, Third) ), tuple3_decoder( erlang:element(4, First), erlang:element(4, Second), erlang:element(4, Third) ), tuple3_sized_decoder( erlang:element(4, First), erlang:element(4, Second), erlang:element(4, Third) )}.