-module(bson@encoder). -compile(no_auto_import). -export([encode/1]). -export_type([entity/0]). -type entity() :: {entity, bson@types:kind(), bitstring()}. -spec encode(list({binary(), bson@types:value()})) -> bitstring(). encode(Doc) -> case document(Doc) of {entity, _@1, Value} -> Value end. -spec document(list({binary(), bson@types:value()})) -> entity(). document(Doc) -> Doc@1 = begin _pipe = Doc, _pipe@1 = gleam@list:reverse(_pipe), _pipe@2 = gleam@list:map(_pipe@1, fun(Kv) -> encode_kv(Kv) end), gleam@bit_string:concat(_pipe@2) end, Size = gleam@bit_string:byte_size(Doc@1) + 5, {entity, {kind, <<16#03>>}, begin _pipe@3 = [<>, Doc@1, <<0>>], gleam@bit_string:concat(_pipe@3) end}. -spec encode_kv({binary(), bson@types:value()}) -> bitstring(). encode_kv(Pair) -> Key = <<(erlang:element(1, Pair))/binary, 0>>, Value@7 = case erlang:element(2, Pair) of null -> null(); {str, Value} -> string(Value); {array, Value@1} -> array(Value@1); {double, Value@2} -> double(Value@2); {boolean, Value@3} -> boolean(Value@3); {integer, Value@4} -> integer(Value@4); {document, Value@5} -> document(Value@5); {object_id, Value@6} -> object_id(Value@6) end, case Value@7 of {entity, Kind, Value@8} -> _pipe = [erlang:element(2, Kind), Key, Value@8], gleam@bit_string:concat(_pipe) end. -spec array(list(bson@types:value())) -> entity(). array(List) -> case begin _pipe = List, _pipe@2 = gleam@list:index_map( _pipe, fun(Index, Item) -> {begin _pipe@1 = Index, gleam@int:to_string(_pipe@1) end, Item} end ), _pipe@3 = gleam@list:reverse(_pipe@2), document(_pipe@3) end of {entity, _@1, Value} -> {entity, {kind, <<16#04>>}, Value} end. -spec string(binary()) -> entity(). string(Value) -> Length = gleam@bit_string:byte_size(<>) + 1, {entity, {kind, <<16#02>>}, <>}. -spec double(float()) -> entity(). double(Value) -> {entity, {kind, <<16#01>>}, <>}. -spec null() -> entity(). null() -> {entity, {kind, <<16#0A>>}, <<>>}. -spec boolean(boolean()) -> entity(). boolean(Value) -> case Value of true -> {entity, {kind, <<16#08>>}, <<1>>}; false -> {entity, {kind, <<16#08>>}, <<0>>} end. -spec integer(integer()) -> entity(). integer(Value) -> case (Value < 2147483647) andalso (Value > -2147483648) of true -> {entity, {kind, <<16#10>>}, <>}; false -> {entity, {kind, <<16#12>>}, <>} end. -spec object_id(bson@object_id:object_id()) -> entity(). object_id(Value) -> {entity, {kind, <<16#07>>}, begin _pipe = Value, bson@object_id:to_bit_string(_pipe) end}.