-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:map(_pipe, fun(Kv) -> encode_kv(Kv) end), gleam@bit_string:concat(_pipe@1) end, Size = gleam@bit_string:byte_size(Doc@1) + 5, {entity, {kind, <<16#03>>}, begin _pipe@2 = [<>, Doc@1, <<0>>], gleam@bit_string:concat(_pipe@2) end}. -spec encode_kv({binary(), bson@types:value()}) -> bitstring(). encode_kv(Pair) -> Key = <<(erlang:element(1, Pair))/binary, 0>>, Value@11 = 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); {binary, Value@4} -> binary(Value@4); {boolean, Value@5} -> boolean(Value@5); {integer, Value@6} -> integer(Value@6); {document, Value@7} -> document(Value@7); {date_time, Value@8} -> datetime(Value@8); {object_id, Value@9} -> object_id(Value@9); {timestamp, Value@10} -> timestamp(Value@10) end, case Value@11 of {entity, Kind, Value@12} -> _pipe = [erlang:element(2, Kind), Key, Value@12], 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 ), document(_pipe@2) 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 binary(bson@binary:binary_()) -> entity(). binary(Value) -> Value@1 = begin _pipe = Value, bson@binary:to_bit_string(_pipe) end, Length = gleam@bit_string:byte_size(Value@1), {entity, {kind, <<16#05>>}, begin _pipe@1 = [<>, erlang:element(2, {sub_kind, <<16#0>>}), Value@1], gleam@bit_string:concat(_pipe@1) 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}.