Packages
gleam_bson
0.6.0
0.27.0
retired
0.26.0
retired
0.25.0
retired
0.24.0
retired
0.23.0
retired
0.22.0
retired
0.21.0
retired
0.20.0
retired
0.19.0
retired
0.18.0
retired
0.17.0
retired
0.16.0
retired
0.15.0
retired
0.14.0
retired
0.13.0
retired
0.12.0
retired
0.11.0
retired
0.10.1
retired
0.10.0
retired
0.9.0
retired
0.8.0
retired
0.7.0
retired
0.6.0
retired
0.5.0
retired
0.4.0
retired
0.3.0
retired
0.2.0
retired
0.1.0
retired
bson encoder and decoder for gleam
Retired package: Renamed - Republished as bison
Current section
Files
Jump to
Current section
Files
src/bson@decoder.erl
-module(bson@decoder).
-compile(no_auto_import).
-export([decode/1]).
-spec decode(bitstring()) -> {ok, list({binary(), bson@types:value()})} |
{error, nil}.
decode(Data) ->
case decode_document(Data) of
{ok, {document, Doc}} ->
{ok, Doc};
{error, nil} ->
{error, nil}
end.
-spec decode_document(bitstring()) -> {ok, bson@types: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 =:= {ok, <<0>>} of
true ->
<<Given_size:32/little-integer, Rest/bitstring>> = Data,
case Total_size =:= Given_size of
true ->
case gleam@bit_string:slice(Rest, 0, (Total_size - 4) - 1) of
{ok, Body} ->
case decode_body(Body, []) of
{ok, Body@1} ->
{ok, {document, Body@1}};
{error, nil} ->
{error, nil}
end;
{error, nil} ->
{error, nil}
end;
false ->
{error, nil}
end;
false ->
{error, nil}
end.
-spec decode_body(bitstring(), list({binary(), bson@types:value()})) -> {ok,
list({binary(),
bson@types:value()})} |
{error, nil}.
decode_body(Data, Storage) ->
case gleam@bit_string:byte_size(Data) =:= 0 of
true ->
{ok, Storage};
false ->
<<Code:8, Data@1/bitstring>> = Data,
Total_size = gleam@bit_string:byte_size(Data@1),
case consume_till_zero(Data@1, <<>>) of
{ok, Key} ->
Key_size = gleam@bit_string:byte_size(Key),
case gleam@bit_string:to_string(Key) of
{ok, Key@1} ->
case gleam@bit_string:slice(
Data@1,
Key_size
+ 1,
(Total_size
- Key_size)
- 1
) of
{ok, Rest} ->
Kind = {kind, <<Code>>},
case Kind of
Kind@1 when Kind@1 =:= {kind, <<16#01>>} ->
<<Value/little-float,
Rest@1/bitstring>> = Rest,
decode_body(
Rest@1,
[{Key@1, {double, Value}} |
Storage]
);
Kind@2 when Kind@2 =:= {kind, <<16#07>>} ->
<<Value@1:96/bitstring,
Rest@2/bitstring>> = Rest,
case bson@object_id:from_bit_string(
Value@1
) of
{ok, Oid} ->
decode_body(
Rest@2,
[{Key@1,
{object_id, Oid}} |
Storage]
);
{error, nil} ->
{error, nil}
end;
Kind@3 when Kind@3 =:= {kind, <<16#08>>} ->
<<Value@2:8, Rest@3/bitstring>> = Rest,
case Value@2 of
1 ->
decode_body(
Rest@3,
[{Key@1,
{boolean, true}} |
Storage]
);
0 ->
decode_body(
Rest@3,
[{Key@1,
{boolean, false}} |
Storage]
);
_@1 ->
{error, nil}
end;
Kind@4 when Kind@4 =:= {kind, <<16#0A>>} ->
decode_body(
Rest,
[{Key@1, null} | Storage]
);
Kind@5 when Kind@5 =:= {kind, <<16#FF>>} ->
decode_body(
Rest,
[{Key@1, min} | Storage]
);
Kind@6 when Kind@6 =:= {kind, <<16#7F>>} ->
decode_body(
Rest,
[{Key@1, max} | Storage]
);
Kind@7 when Kind@7 =:= {kind, <<16#10>>} ->
<<Value@3:32/little,
Rest@4/bitstring>> = Rest,
decode_body(
Rest@4,
[{Key@1, {integer, Value@3}} |
Storage]
);
Kind@8 when Kind@8 =:= {kind, <<16#12>>} ->
<<Value@4:64/little,
Rest@5/bitstring>> = Rest,
decode_body(
Rest@5,
[{Key@1, {integer, Value@4}} |
Storage]
);
Kind@9 when Kind@9 =:= {kind, <<16#09>>} ->
<<Value@5:64/little,
Rest@6/bitstring>> = Rest,
decode_body(
Rest@6,
[{Key@1, {date_time, Value@5}} |
Storage]
);
Kind@10 when Kind@10 =:= {kind,
<<16#11>>} ->
<<Value@6:64/little-unsigned,
Rest@7/bitstring>> = Rest,
decode_body(
Rest@7,
[{Key@1, {timestamp, Value@6}} |
Storage]
);
Kind@11 when Kind@11 =:= {kind,
<<16#02>>} ->
<<Given_size:32/little-integer,
Rest@8/bitstring>> = Rest,
case consume_till_zero(Rest@8, <<>>) of
{ok, Str} ->
Str_size = gleam@bit_string:byte_size(
Str
),
case Given_size
=:= (Str_size
+ 1) of
true ->
case gleam@bit_string:to_string(
Str
) of
{ok, Str@1} ->
case gleam@bit_string:slice(
Rest@8,
Str_size
+ 1,
(gleam@bit_string:byte_size(
Rest@8
)
- Str_size)
- 1
) of
{ok,
Rest@9} ->
decode_body(
Rest@9,
[{Key@1,
{str,
Str@1}} |
Storage]
);
{error,
nil} ->
{error,
nil}
end;
{error, nil} ->
{error, nil}
end;
false ->
{error, nil}
end;
{error, nil} ->
{error, nil}
end;
Kind@12 when Kind@12 =:= {kind,
<<16#0D>>} ->
<<Given_size@1:32/little-integer,
Rest@10/bitstring>> = Rest,
case consume_till_zero(
Rest@10,
<<>>
) of
{ok, Str@2} ->
Str_size@1 = gleam@bit_string:byte_size(
Str@2
),
case Given_size@1
=:= (Str_size@1
+ 1) of
true ->
case gleam@bit_string:to_string(
Str@2
) of
{ok, Str@3} ->
case gleam@bit_string:slice(
Rest@10,
Str_size@1
+ 1,
(gleam@bit_string:byte_size(
Rest@10
)
- Str_size@1)
- 1
) of
{ok,
Rest@11} ->
decode_body(
Rest@11,
[{Key@1,
{js,
Str@3}} |
Storage]
);
{error,
nil} ->
{error,
nil}
end;
{error, nil} ->
{error, nil}
end;
false ->
{error, nil}
end;
{error, nil} ->
{error, nil}
end;
Kind@13 when (Kind@13 =:= {kind,
<<16#03>>}) orelse (Kind@13 =:= {kind,
<<16#04>>}) ->
<<Doc_size:32/little-integer,
_@2/bitstring>> = Rest,
case gleam@bit_string:slice(
Rest,
0,
Doc_size
) of
{ok, Doc} ->
case decode_document(Doc) of
{ok, Doc@1} ->
Doc@3 = case Kind@13 of
Kind@14 when Kind@14 =:= {kind,
<<16#03>>} ->
{ok, Doc@1};
Kind@15 when Kind@15 =:= {kind,
<<16#04>>} ->
case Doc@1 of
{document,
Doc@2} ->
List = begin
_pipe = Doc@2,
gleam@list:map(
_pipe,
fun(
Item
) ->
{begin
_pipe@1 = Item,
_pipe@2 = gleam@pair:first(
_pipe@1
),
gleam@int:parse(
_pipe@2
)
end,
begin
_pipe@3 = Item,
gleam@pair:second(
_pipe@3
)
end}
end
)
end,
case gleam@list:any(
List,
fun(
Item@1
) ->
gleam@result:is_error(
begin
_pipe@4 = Item@1,
gleam@pair:first(
_pipe@4
)
end
)
end
) of
true ->
{error,
nil};
false ->
{ok,
{array,
begin
_pipe@5 = List,
_pipe@8 = gleam@list:map(
_pipe@5,
fun(
Item@2
) ->
{ok,
First@1} = case begin
_pipe@6 = Item@2,
gleam@pair:first(
_pipe@6
)
end of
{ok,
First} -> {ok,
First};
_try ->
erlang:error(
#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try,
module => <<"bson/decoder"/utf8>>,
function => <<"decode_body"/utf8>>,
line => 226}
)
end,
{First@1,
begin
_pipe@7 = Item@2,
gleam@pair:second(
_pipe@7
)
end}
end
),
_pipe@11 = gleam@list:sort(
_pipe@8,
fun(
A,
B
) ->
A_index = begin
_pipe@9 = A,
gleam@pair:first(
_pipe@9
)
end,
B_index = begin
_pipe@10 = B,
gleam@pair:first(
_pipe@10
)
end,
gleam@int:compare(
A_index,
B_index
)
end
),
gleam@list:map(
_pipe@11,
fun(
Item@3
) ->
_pipe@12 = Item@3,
gleam@pair:second(
_pipe@12
)
end
)
end}}
end;
_@3 ->
{error,
nil}
end;
_@4 ->
{error, nil}
end,
case Doc@3 of
{ok, Doc@4} ->
case Doc_size
=:= gleam@bit_string:byte_size(
Rest
) of
true ->
{ok,
[{Key@1,
Doc@4} |
Storage]};
false ->
case gleam@bit_string:slice(
Rest,
Doc_size,
gleam@bit_string:byte_size(
Rest
)
- Doc_size
) of
{ok,
Rest@12} ->
decode_body(
Rest@12,
[{Key@1,
Doc@4} |
Storage]
);
{error,
nil} ->
{error,
nil}
end
end;
{error, nil} ->
{error, nil}
end;
{error, nil} ->
{error, nil}
end;
{error, nil} ->
{error, nil}
end;
_@5 ->
{error, nil}
end;
{error, nil} ->
{error, nil}
end;
{error, nil} ->
{error, nil}
end;
{error, nil} ->
{error, nil}
end
end.
-spec consume_till_zero(bitstring(), bitstring()) -> {ok, bitstring()} |
{error, nil}.
consume_till_zero(Data, Storage) ->
case gleam@bit_string:byte_size(Data) =:= 0 of
false ->
<<Ch:8, Rest/bitstring>> = Data,
case Ch =:= 0 of
true ->
{ok, Storage};
false ->
consume_till_zero(
Rest,
gleam@bit_string:append(Storage, <<Ch>>)
)
end;
true ->
{error, nil}
end.