-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@10 = case erlang:element(2, Pair) of null -> null(); min -> min(); max -> max(); {js, Value} -> js(Value); {str, Value@1} -> string(Value@1); {array, Value@2} -> array(Value@2); {double, Value@3} -> double(Value@3); {boolean, Value@4} -> boolean(Value@4); {integer, Value@5} -> integer(Value@5); {document, Value@6} -> document(Value@6); {date_time, Value@7} -> datetime(Value@7); {object_id, Value@8} -> object_id(Value@8); {timestamp, Value@9} -> timestamp(Value@9) end, case Value@10 of {entity, Kind, Value@11} -> _pipe = [erlang:element(2, Kind), Key, Value@11], 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 datetime(integer()) -> entity(). datetime(Value) -> {entity, {kind, <<16#09>>}, <>}. -spec timestamp(integer()) -> entity(). timestamp(Value) -> {entity, {kind, <<16#11>>}, <>}. -spec js(binary()) -> entity(). js(Value) -> Length = gleam@bit_string:byte_size(<>) + 1, {entity, {kind, <<16#0D>>}, <>}. -spec min() -> entity(). min() -> {entity, {kind, <<16#FF>>}, <<>>}. -spec max() -> entity(). max() -> {entity, {kind, <<16#7F>>}, <<>>}. -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}.