Packages
gleam_bson
0.13.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
{error, _try} -> {error, _try};
{ok, Body} ->
case decode_body(Body, []) of
{error, _try@1} -> {error, _try@1};
{ok, Body@1} ->
{ok, {document, Body@1}}
end
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
{error, _try} -> {error, _try};
{ok, Key} ->
Key_size = gleam@bit_string:byte_size(Key),
case gleam@bit_string:to_string(Key) of
{error, _try@1} -> {error, _try@1};
{ok, Key@1} ->
case gleam@bit_string:slice(
Data@1,
Key_size
+ 1,
(Total_size
- Key_size)
- 1
) of
{error, _try@2} -> {error, _try@2};
{ok, Rest} ->
Kind = {kind, <<Code>>},
case Kind of
Kind@1 when Kind@1 =:= {kind, <<16#05>>} ->
<<Byte_size:32/little-integer,
Sub_code:8,
Rest@1/bitstring>> = Rest,
Given_size = Byte_size
* 8,
<<Value:Given_size/bitstring,
Rest@2/bitstring>> = Rest@1,
Sub_kind = {sub_kind, <<Sub_code>>},
case Sub_kind of
Sub_kind@1 when Sub_kind@1 =:= {sub_kind,
<<16#0>>} ->
case bson@generic:from_bit_string(
Value
) of
{error, _try@3} -> {error, _try@3};
{ok, Value@1} ->
decode_body(
Rest@2,
gleam@list:append(
Storage,
[{Key@1,
{binary,
{generic,
Value@1}}}]
)
)
end;
Sub_kind@2 when Sub_kind@2 =:= {sub_kind,
<<16#5>>} ->
case bson@md5:from_bit_string(
Value
) of
{error, _try@4} -> {error, _try@4};
{ok, Value@2} ->
decode_body(
Rest@2,
gleam@list:append(
Storage,
[{Key@1,
{binary,
{md5,
Value@2}}}]
)
)
end;
Sub_kind@3 when Sub_kind@3 =:= {sub_kind,
<<16#4>>} ->
case bson@uuid:from_bit_string(
Value
) of
{error, _try@5} -> {error, _try@5};
{ok, Value@3} ->
decode_body(
Rest@2,
gleam@list:append(
Storage,
[{Key@1,
{binary,
{uuid,
Value@3}}}]
)
)
end;
_@1 when Sub_code >= 16#80 ->
case bson@custom:from_bit_string_with_code(
Sub_code,
Value
) of
{error, _try@6} -> {error, _try@6};
{ok, Value@4} ->
decode_body(
Rest@2,
gleam@list:append(
Storage,
[{Key@1,
{binary,
{custom,
Value@4}}}]
)
)
end;
_@2 ->
{error, nil}
end;
Kind@2 when Kind@2 =:= {kind, <<16#01>>} ->
<<Value@5/little-float,
Rest@3/bitstring>> = Rest,
decode_body(
Rest@3,
gleam@list:append(
Storage,
[{Key@1, {double, Value@5}}]
)
);
Kind@3 when Kind@3 =:= {kind, <<16#07>>} ->
<<Value@6:96/bitstring,
Rest@4/bitstring>> = Rest,
case bson@object_id:from_bit_string(
Value@6
) of
{error, _try@7} -> {error, _try@7};
{ok, Oid} ->
decode_body(
Rest@4,
gleam@list:append(
Storage,
[{Key@1,
{object_id, Oid}}]
)
)
end;
Kind@4 when Kind@4 =:= {kind, <<16#08>>} ->
<<Value@7:8, Rest@5/bitstring>> = Rest,
case Value@7 of
1 ->
decode_body(
Rest@5,
gleam@list:append(
Storage,
[{Key@1,
{boolean, true}}]
)
);
0 ->
decode_body(
Rest@5,
gleam@list:append(
Storage,
[{Key@1,
{boolean, false}}]
)
);
_@3 ->
{error, nil}
end;
Kind@5 when Kind@5 =:= {kind, <<16#0A>>} ->
decode_body(
Rest,
gleam@list:append(
Storage,
[{Key@1, null}]
)
);
Kind@6 when Kind@6 =:= {kind, <<16#FF>>} ->
decode_body(
Rest,
gleam@list:append(
Storage,
[{Key@1, min}]
)
);
Kind@7 when Kind@7 =:= {kind, <<16#7F>>} ->
decode_body(
Rest,
gleam@list:append(
Storage,
[{Key@1, max}]
)
);
Kind@8 when Kind@8 =:= {kind, <<16#10>>} ->
<<Value@8:32/little,
Rest@6/bitstring>> = Rest,
decode_body(
Rest@6,
gleam@list:append(
Storage,
[{Key@1, {integer, Value@8}}]
)
);
Kind@9 when Kind@9 =:= {kind, <<16#12>>} ->
<<Value@9:64/little,
Rest@7/bitstring>> = Rest,
decode_body(
Rest@7,
gleam@list:append(
Storage,
[{Key@1, {integer, Value@9}}]
)
);
Kind@10 when Kind@10 =:= {kind,
<<16#09>>} ->
<<Value@10:64/little,
Rest@8/bitstring>> = Rest,
decode_body(
Rest@8,
gleam@list:append(
Storage,
[{Key@1,
{date_time, Value@10}}]
)
);
Kind@11 when Kind@11 =:= {kind,
<<16#11>>} ->
<<Value@11:64/little-unsigned,
Rest@9/bitstring>> = Rest,
decode_body(
Rest@9,
gleam@list:append(
Storage,
[{Key@1,
{timestamp, Value@11}}]
)
);
Kind@12 when Kind@12 =:= {kind,
<<16#0B>>} ->
case consume_till_zero(Rest, <<>>) of
{error, _try@8} -> {error, _try@8};
{ok, Pattern_bytes} ->
Pattern_size = (gleam@bit_string:byte_size(
Pattern_bytes
)
+ 1)
* 8,
<<_@4:Pattern_size,
Rest@10/bitstring>> = Rest,
case consume_till_zero(
Rest@10,
<<>>
) of
{error, _try@9} -> {error, _try@9};
{ok, Options_bytes} ->
Options_size = (gleam@bit_string:byte_size(
Options_bytes
)
+ 1)
* 8,
<<_@5:Options_size,
Rest@11/bitstring>> = Rest@10,
case gleam@bit_string:to_string(
Pattern_bytes
) of
{error, _try@10} -> {error, _try@10};
{ok, Pattern} ->
case gleam@bit_string:to_string(
Options_bytes
) of
{error, _try@11} -> {error, _try@11};
{ok, Options} ->
decode_body(
Rest@11,
gleam@list:append(
Storage,
[{Key@1,
{regex,
{Pattern,
Options}}}]
)
)
end
end
end
end;
Kind@13 when Kind@13 =:= {kind,
<<16#02>>} ->
<<Given_size@1:32/little-integer,
Rest@12/bitstring>> = Rest,
case consume_till_zero(
Rest@12,
<<>>
) of
{error, _try@12} -> {error, _try@12};
{ok, Str} ->
Str_size = gleam@bit_string:byte_size(
Str
),
case Given_size@1
=:= (Str_size
+ 1) of
true ->
case gleam@bit_string:to_string(
Str
) of
{error, _try@13} -> {error, _try@13};
{ok, Str@1} ->
case gleam@bit_string:slice(
Rest@12,
Str_size
+ 1,
(gleam@bit_string:byte_size(
Rest@12
)
- Str_size)
- 1
) of
{error, _try@14} -> {error, _try@14};
{ok, Rest@13} ->
decode_body(
Rest@13,
gleam@list:append(
Storage,
[{Key@1,
{str,
Str@1}}]
)
)
end
end;
false ->
{error, nil}
end
end;
Kind@14 when Kind@14 =:= {kind,
<<16#0D>>} ->
<<Given_size@2:32/little-integer,
Rest@14/bitstring>> = Rest,
case consume_till_zero(
Rest@14,
<<>>
) of
{error, _try@15} -> {error, _try@15};
{ok, Str@2} ->
Str_size@1 = gleam@bit_string:byte_size(
Str@2
),
case Given_size@2
=:= (Str_size@1
+ 1) of
true ->
case gleam@bit_string:to_string(
Str@2
) of
{error, _try@16} -> {error, _try@16};
{ok, Str@3} ->
case gleam@bit_string:slice(
Rest@14,
Str_size@1
+ 1,
(gleam@bit_string:byte_size(
Rest@14
)
- Str_size@1)
- 1
) of
{error, _try@17} -> {error, _try@17};
{ok, Rest@15} ->
decode_body(
Rest@15,
gleam@list:append(
Storage,
[{Key@1,
{js,
Str@3}}]
)
)
end
end;
false ->
{error, nil}
end
end;
Kind@15 when (Kind@15 =:= {kind,
<<16#03>>}) orelse (Kind@15 =:= {kind,
<<16#04>>}) ->
<<Doc_size:32/little-integer,
_@6/bitstring>> = Rest,
case gleam@bit_string:slice(
Rest,
0,
Doc_size
) of
{error, _try@18} -> {error, _try@18};
{ok, Doc} ->
case decode_document(Doc) of
{error, _try@19} -> {error, _try@19};
{ok, {document, Doc@1}} ->
case case Kind@15 of
Kind@16 when Kind@16 =:= {kind,
<<16#03>>} ->
{ok,
{document,
Doc@1}};
Kind@17 when Kind@17 =:= {kind,
<<16#04>>} ->
case begin
_pipe = Doc@1,
gleam@list:try_map(
_pipe,
fun(
Item
) ->
case begin
_pipe@1 = Item,
_pipe@2 = gleam@pair:first(
_pipe@1
),
gleam@int:parse(
_pipe@2
)
end of
{error, _try@20} -> {error, _try@20};
{ok, First} ->
{ok,
{First,
begin
_pipe@3 = Item,
gleam@pair:second(
_pipe@3
)
end}}
end
end
)
end of
{error, _try@21} -> {error, _try@21};
{ok, Doc@2} ->
{ok,
{array,
begin
_pipe@4 = Doc@2,
_pipe@7 = gleam@list:sort(
_pipe@4,
fun(
A,
B
) ->
A_index = begin
_pipe@5 = A,
gleam@pair:first(
_pipe@5
)
end,
B_index = begin
_pipe@6 = B,
gleam@pair:first(
_pipe@6
)
end,
gleam@int:compare(
A_index,
B_index
)
end
),
gleam@list:map(
_pipe@7,
fun(
Item@1
) ->
_pipe@8 = Item@1,
gleam@pair:second(
_pipe@8
)
end
)
end}}
end;
_@7 ->
{error, nil}
end of
{error, _try@22} -> {error, _try@22};
{ok, Doc@3} ->
case Doc_size
=:= gleam@bit_string:byte_size(
Rest
) of
true ->
{ok,
gleam@list:append(
Storage,
[{Key@1,
Doc@3}]
)};
false ->
case gleam@bit_string:slice(
Rest,
Doc_size,
gleam@bit_string:byte_size(
Rest
)
- Doc_size
) of
{ok,
Rest@16} ->
decode_body(
Rest@16,
gleam@list:append(
Storage,
[{Key@1,
Doc@3}]
)
);
{error,
nil} ->
{error,
nil}
end
end
end
end
end;
_@8 ->
{error, nil}
end
end
end
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.