-module(bison@decoder). -compile([no_auto_import, nowarn_unused_vars]). -export([decode/1]). -spec consume_till_zero(bitstring(), bitstring()) -> {ok, bitstring()} | {error, nil}. consume_till_zero(Data, Storage) -> case gleam@bit_string:byte_size(Data) of 0 -> {error, nil}; _ -> <> = Data, case Ch of 0 -> {ok, Storage}; _ -> consume_till_zero( Rest, gleam@bit_string:append(Storage, <>) ) end end. -spec decode_boolean(integer(), fun((boolean()) -> {ok, HCJ} | {error, nil})) -> {ok, HCJ} | {error, nil}. decode_boolean(Value, Rest) -> case Value of 0 -> Rest(false); 1 -> Rest(true); _ -> {error, nil} end. -spec decode_body(bitstring(), list({binary(), bison@value:value()})) -> {ok, list({binary(), bison@value:value()})} | {error, nil}. decode_body(Data, Storage) -> gleam@bool:guard( gleam@bit_string:byte_size(Data) =:= 0, {ok, Storage}, fun() -> <> = Data, Total_size = gleam@bit_string:byte_size(Data@1), gleam@result:then( consume_till_zero(Data@1, <<>>), fun(Key) -> Key_size = gleam@bit_string:byte_size(Key), gleam@result:then( gleam@bit_string:to_string(Key), fun(Key@1) -> gleam@result:then( gleam@bit_string:slice( Data@1, Key_size + 1, (Total_size - Key_size) - 1 ), fun(Rest) -> Kind = {kind, <>}, case Kind of Kind@1 when Kind@1 =:= {kind, <<16#FF>>} -> recurse_with_new_kv( Rest, Storage, Key@1, min ); Kind@2 when Kind@2 =:= {kind, <<16#7F>>} -> recurse_with_new_kv( Rest, Storage, Key@1, max ); Kind@3 when Kind@3 =:= {kind, <<16#0A>>} -> recurse_with_new_kv( Rest, Storage, Key@1, null ); Kind@4 when Kind@4 =:= {kind, <<16#10>>} -> <> = Rest, recurse_with_new_kv( Rest@1, Storage, Key@1, {int32, Value} ); Kind@5 when Kind@5 =:= {kind, <<16#12>>} -> <> = Rest, recurse_with_new_kv( Rest@2, Storage, Key@1, {int64, Value@1} ); Kind@6 when Kind@6 =:= {kind, <<16#01>>} -> <> = Rest, recurse_with_new_kv( Rest@3, Storage, Key@1, {double, Value@2} ); Kind@7 when Kind@7 =:= {kind, <<16#11>>} -> <> = Rest, recurse_with_new_kv( Rest@4, Storage, Key@1, {timestamp, Value@3} ); Kind@8 when Kind@8 =:= {kind, <<16#07>>} -> <> = Rest, gleam@result:then( bison@object_id:from_bit_string( Value@4 ), fun(Oid) -> recurse_with_new_kv( Rest@5, Storage, Key@1, {object_id, Oid} ) end ); Kind@9 when Kind@9 =:= {kind, <<16#08>>} -> <> = Rest, decode_boolean( Value@5, fun(Value@6) -> recurse_with_new_kv( Rest@6, Storage, Key@1, {boolean, Value@6} ) end ); Kind@10 when Kind@10 =:= {kind, <<16#09>>} -> <> = Rest, Value@8 = birl@time:add( {date_time, 0, 0, none, none}, birl@duration:accurate_new( [{Value@7, milli_second}] ) ), recurse_with_new_kv( Rest@7, Storage, Key@1, {date_time, Value@8} ); Kind@11 when Kind@11 =:= {kind, <<16#0B>>} -> gleam@result:then( consume_till_zero(Rest, <<>>), fun(Pattern_bytes) -> Pattern_size = (gleam@bit_string:byte_size( Pattern_bytes ) + 1) * 8, <<_:Pattern_size, Rest@8/bitstring>> = Rest, gleam@result:then( consume_till_zero( Rest@8, <<>> ), fun(Options_bytes) -> Options_size = (gleam@bit_string:byte_size( Options_bytes ) + 1) * 8, <<_:Options_size, Rest@9/bitstring>> = Rest@8, gleam@result:then( gleam@bit_string:to_string( Pattern_bytes ), fun(Pattern) -> gleam@result:then( gleam@bit_string:to_string( Options_bytes ), fun( Options ) -> recurse_with_new_kv( Rest@9, Storage, Key@1, {regex, {Pattern, Options}} ) end ) end ) end ) end ); Kind@12 when Kind@12 =:= {kind, <<16#02>>} -> <> = Rest, gleam@result:then( consume_till_zero(Rest@10, <<>>), fun(Str) -> Str_size = gleam@bit_string:byte_size( Str ), case Given_size =:= (Str_size + 1) of true -> gleam@result:then( gleam@bit_string:to_string( Str ), fun(Str@1) -> gleam@result:then( gleam@bit_string:slice( Rest@10, Str_size + 1, (gleam@bit_string:byte_size( Rest@10 ) - Str_size) - 1 ), fun( Rest@11 ) -> recurse_with_new_kv( Rest@11, Storage, Key@1, {str, Str@1} ) end ) end ); false -> {error, nil} end end ); Kind@13 when Kind@13 =:= {kind, <<16#0D>>} -> <> = Rest, gleam@result:then( consume_till_zero(Rest@12, <<>>), fun(Str@2) -> Str_size@1 = gleam@bit_string:byte_size( Str@2 ), case Given_size@1 =:= (Str_size@1 + 1) of true -> gleam@result:then( gleam@bit_string:to_string( Str@2 ), fun(Str@3) -> gleam@result:then( gleam@bit_string:slice( Rest@12, Str_size@1 + 1, (gleam@bit_string:byte_size( Rest@12 ) - Str_size@1) - 1 ), fun( Rest@13 ) -> recurse_with_new_kv( Rest@13, Storage, Key@1, {js, Str@3} ) end ) end ); false -> {error, nil} end end ); Kind@14 when (Kind@14 =:= {kind, <<16#03>>}) orelse (Kind@14 =:= {kind, <<16#04>>}) -> <> = Rest, gleam@result:then( gleam@bit_string:slice( Rest, 0, Doc_size ), fun(Doc) -> gleam@result:then( decode_document(Doc), fun(Doc@1) -> {document, Doc@2} = case Doc@1 of {document, _} -> Doc@1; _assert_fail -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"bison/decoder"/utf8>>, function => <<"decode_body"/utf8>>, line => 166} ) end, gleam@result:then( case Kind@14 of Kind@15 when Kind@15 =:= {kind, <<16#03>>} -> _pipe = Doc@2, _pipe@1 = {document, _pipe}, {ok, _pipe@1}; Kind@16 when Kind@16 =:= {kind, <<16#04>>} -> gleam@result:then( gleam@list:try_map( Doc@2, fun( Item ) -> gleam@result:then( gleam@int:parse( erlang:element( 1, Item ) ), fun( First ) -> {ok, {First, erlang:element( 2, Item )}} end ) end ), fun( Doc@3 ) -> _pipe@2 = Doc@3, _pipe@3 = gleam@list:sort( _pipe@2, fun( A, B ) -> gleam@int:compare( erlang:element( 1, A ), erlang:element( 1, B ) ) end ), _pipe@4 = gleam@list:map( _pipe@3, fun gleam@pair:second/1 ), _pipe@5 = {array, _pipe@4}, {ok, _pipe@5} end ); _ -> {error, nil} end, fun(Doc@4) -> case gleam@bit_string:slice( Rest, Doc_size, gleam@bit_string:byte_size( Rest ) - Doc_size ) of {ok, Rest@14} -> recurse_with_new_kv( Rest@14, Storage, Key@1, Doc@4 ); {error, nil} -> {error, nil} end end ) end ) end ); Kind@17 when Kind@17 =:= {kind, <<16#05>>} -> <> = Rest, Given_size@2 = Byte_size * 8, <> = Rest@15, Sub_kind = {sub_kind, <>}, case Sub_kind of Sub_kind@1 when Sub_kind@1 =:= {sub_kind, <<16#0>>} -> gleam@result:then( bison@generic:from_bit_string( Value@9 ), fun(Value@10) -> recurse_with_new_kv( Rest@16, Storage, Key@1, begin _pipe@6 = Value@10, _pipe@7 = {generic, _pipe@6}, {binary, _pipe@7} end ) end ); Sub_kind@2 when Sub_kind@2 =:= {sub_kind, <<16#5>>} -> gleam@result:then( bison@md5:from_bit_string( Value@9 ), fun(Value@11) -> recurse_with_new_kv( Rest@16, Storage, Key@1, begin _pipe@8 = Value@11, _pipe@9 = {md5, _pipe@8}, {binary, _pipe@9} end ) end ); Sub_kind@3 when Sub_kind@3 =:= {sub_kind, <<16#4>>} -> gleam@result:then( bison@uuid:from_bit_string( Value@9 ), fun(Value@12) -> recurse_with_new_kv( Rest@16, Storage, Key@1, begin _pipe@10 = Value@12, _pipe@11 = {uuid, _pipe@10}, {binary, _pipe@11} end ) end ); _ when Sub_code >= 16#80 -> gleam@result:then( bison@custom:from_bit_string_with_code( Sub_code, Value@9 ), fun(Value@13) -> recurse_with_new_kv( Rest@16, Storage, Key@1, begin _pipe@12 = Value@13, _pipe@13 = {custom, _pipe@12}, {binary, _pipe@13} end ) end ); _ -> {error, nil} end; _ -> {error, nil} end end ) end ) end ) end ). -spec recurse_with_new_kv( bitstring(), list({binary(), bison@value:value()}), binary(), bison@value:value() ) -> {ok, list({binary(), bison@value:value()})} | {error, nil}. recurse_with_new_kv(Rest, Storage, Key, Value) -> decode_body(Rest, gleam@list:key_set(Storage, Key, Value)). -spec decode_document(bitstring()) -> {ok, bison@value:value()} | {error, nil}. decode_document(Data) -> Total_size = gleam@bit_string:byte_size(Data), Last_byte = gleam@bit_string:slice(Data, Total_size, -1), case Last_byte of {ok, <<0>>} -> <> = Data, case Total_size =:= Given_size of true -> gleam@result:then( gleam@bit_string:slice(Rest, 0, (Total_size - 4) - 1), fun(Body) -> gleam@result:then( decode_body(Body, []), fun(Body@1) -> _pipe = Body@1, _pipe@1 = {document, _pipe}, {ok, _pipe@1} end ) end ); false -> {error, nil} end; _ -> {error, nil} end. -spec decode(bitstring()) -> {ok, list({binary(), bison@value:value()})} | {error, nil}. decode(Data) -> case decode_document(Data) of {ok, {document, Doc}} -> {ok, Doc}; _ -> {error, nil} end.