Packages
gleam_bson
0.22.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@object_id.erl
-module(bson@object_id).
-compile([no_auto_import, nowarn_unused_vars]).
-export([get_timestamp/1, compare/2, to_bit_string/1, from_int_list/1, from_bit_string/1, from_string/1, new/0, to_string/1, to_int_list/1]).
-export_type([object_id/0, unit/0]).
-opaque object_id() :: {object_id, bitstring()}.
-type unit() :: microsecond.
-spec get_timestamp(object_id()) -> integer().
get_timestamp(Id) ->
case Id of
{object_id, <<Timestamp:32/big, _/bitstring>>} ->
Timestamp
end.
-spec compare(object_id(), object_id()) -> gleam@order:order().
compare(A, B) ->
{object_id, <<Moment_a:32/big, _:24/big, _:16/big, Counter_a:24/big>>} = A,
{object_id, <<Moment_b:32/big, _:24/big, _:16/big, Counter_b:24/big>>} = B,
case Moment_a =:= Moment_b of
true ->
case Counter_a =:= Counter_b of
true ->
eq;
false ->
case Counter_a < Counter_b of
true ->
lt;
false ->
gt
end
end;
false ->
case Moment_a < Moment_b of
true ->
lt;
false ->
gt
end
end.
-spec to_bit_string(object_id()) -> bitstring().
to_bit_string(Id) ->
case Id of
{object_id, Value} ->
Value
end.
-spec from_int_list(list(integer())) -> {ok, object_id()} | {error, nil}.
from_int_list(Id) ->
case gleam@list:length(Id) of
12 ->
case gleam@list:try_fold(
Id,
<<>>,
fun(Acc, Code) -> case (Code >= 0) andalso (Code =< 255) of
true ->
_pipe = gleam@bit_string:append(Acc, <<Code>>),
{ok, _pipe};
false ->
{error, nil}
end end
) of
{ok, Id@1} ->
{ok, {object_id, Id@1}};
{error, nil} ->
{error, nil}
end;
24 ->
case gleam@list:try_map(
Id,
fun(Code@1) -> case (Code@1 >= 0) andalso (Code@1 =< 15) of
true ->
{ok, Code@1};
false ->
{error, nil}
end end
) of
{ok, Codes} ->
_pipe@1 = Codes,
_pipe@2 = gleam@list:sized_chunk(_pipe@1, 2),
_pipe@3 = gleam@list:map(
_pipe@2,
fun(Pair) ->
[High, Low] = Pair,
<<Num:8>> = <<High:4, Low:4>>,
Num
end
),
_pipe@4 = gleam@list:fold(
_pipe@3,
<<>>,
fun(Acc@1, Code@2) ->
gleam@bit_string:append(Acc@1, <<Code@2>>)
end
),
_pipe@5 = {object_id, _pipe@4},
{ok, _pipe@5};
{error, nil} ->
{error, nil}
end;
_ ->
{error, nil}
end.
-spec from_bit_string(bitstring()) -> {ok, object_id()} | {error, nil}.
from_bit_string(Id) ->
case gleam@bit_string:byte_size(Id) of
12 ->
{ok, {object_id, Id}};
_ ->
{error, nil}
end.
-spec to_digit(binary()) -> {ok, integer()} | {error, nil}.
to_digit(Char) ->
<<Code>> = gleam@bit_string:from_string(Char),
case Code of
Code@1 when (Code@1 >= 48) andalso (Code@1 =< 57) ->
<<_:4, Num:4>> = gleam@bit_string:from_string(Char),
{ok, Num};
Code@2 when ((Code@2 >= 65) andalso (Code@2 =< 70)) orelse ((Code@2 >= 97) andalso (Code@2 =< 102)) ->
<<_:5, Additive:3>> = gleam@bit_string:from_string(Char),
{ok, 9 + Additive};
_ ->
{error, nil}
end.
-spec from_string(binary()) -> {ok, object_id()} | {error, nil}.
from_string(Id) ->
case gleam@string:length(Id) of
24 ->
case begin
_pipe = Id,
_pipe@1 = gleam@string:to_graphemes(_pipe),
gleam@list:try_map(_pipe@1, fun to_digit/1)
end of
{ok, Codes} ->
_pipe@2 = Codes,
_pipe@3 = gleam@list:sized_chunk(_pipe@2, 2),
_pipe@4 = gleam@list:map(
_pipe@3,
fun(Pair) ->
[High, Low] = Pair,
<<High:4, Low:4>>
end
),
_pipe@5 = gleam@bit_string:concat(_pipe@4),
_pipe@6 = {object_id, _pipe@5},
{ok, _pipe@6};
{error, nil} ->
{error, nil}
end;
_ ->
{error, nil}
end.
-spec to_char(integer()) -> binary().
to_char(Digit) ->
Ch = case Digit < 10 of
true ->
Digit + 48;
false ->
Digit + 87
end,
_assert_subject = gleam@bit_string:to_string(<<Ch>>),
{ok, Digit@1} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"bson/object_id"/utf8>>,
function => <<"to_char"/utf8>>,
line => 224})
end,
Digit@1.
-spec now() -> integer().
now() ->
erlang:time_offset(microsecond) + erlang:monotonic_time(microsecond).
-spec new() -> object_id().
new() ->
Moment_in_microseconds = now(),
_assert_subject = gleam@int:divide(Moment_in_microseconds, 1000000),
{ok, Moment} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"bson/object_id"/utf8>>,
function => <<"new"/utf8>>,
line => 16})
end,
_assert_subject@1 = gleam@int:modulo(Moment_in_microseconds, 16#ffffff),
{ok, Counter} = case _assert_subject@1 of
{ok, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"bson/object_id"/utf8>>,
function => <<"new"/utf8>>,
line => 17})
end,
_assert_subject@2 = inet:gethostname(),
{ok, Hostname} = case _assert_subject@2 of
{ok, _} -> _assert_subject@2;
_assert_fail@2 ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@2,
module => <<"bson/object_id"/utf8>>,
function => <<"new"/utf8>>,
line => 19})
end,
<<Machine_id:24, _/bitstring>> = crypto:hash(sha256, Hostname),
_assert_subject@3 = begin
_pipe = os:getpid(),
_pipe@1 = gleam@list:fold(
_pipe,
<<>>,
fun(Acc, C) -> <<Acc/bitstring, C>> end
),
gleam@bit_string:to_string(_pipe@1)
end,
{ok, String_pid} = case _assert_subject@3 of
{ok, _} -> _assert_subject@3;
_assert_fail@3 ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@3,
module => <<"bson/object_id"/utf8>>,
function => <<"new"/utf8>>,
line => 23})
end,
_assert_subject@4 = gleam@int:parse(String_pid),
{ok, Pid} = case _assert_subject@4 of
{ok, _} -> _assert_subject@4;
_assert_fail@4 ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@4,
module => <<"bson/object_id"/utf8>>,
function => <<"new"/utf8>>,
line => 28})
end,
_assert_subject@5 = begin
_pipe@2 = <<Moment:32/big,
Machine_id:24/big,
Pid:16/big,
Counter:24/big>>,
from_bit_string(_pipe@2)
end,
{ok, Id} = case _assert_subject@5 of
{ok, _} -> _assert_subject@5;
_assert_fail@5 ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@5,
module => <<"bson/object_id"/utf8>>,
function => <<"new"/utf8>>,
line => 30})
end,
Id.
-spec to_string_internal(bitstring(), binary()) -> binary().
to_string_internal(Remaining, Storage) ->
<<High:4, Low:4, Remaining@1/binary>> = Remaining,
New_storage = begin
_pipe = Storage,
_pipe@1 = gleam@string:append(_pipe, to_char(High)),
gleam@string:append(_pipe@1, to_char(Low))
end,
case gleam@bit_string:byte_size(Remaining@1) of
0 ->
New_storage;
_ ->
to_string_internal(Remaining@1, New_storage)
end.
-spec to_string(object_id()) -> binary().
to_string(Id) ->
case Id of
{object_id, Value} ->
to_string_internal(Value, <<""/utf8>>)
end.
-spec to_int_list_internal(bitstring(), gleam@queue:queue(integer())) -> list(integer()).
to_int_list_internal(Remaining, Storage) ->
<<Num:8, Remaining@1/binary>> = Remaining,
New_storage = gleam@queue:push_back(Storage, Num),
case gleam@bit_string:byte_size(Remaining@1) of
0 ->
gleam@queue:to_list(New_storage);
_ ->
to_int_list_internal(Remaining@1, New_storage)
end.
-spec to_int_list(object_id()) -> list(integer()).
to_int_list(Id) ->
case Id of
{object_id, Value} ->
to_int_list_internal(Value, gleam@queue:new())
end.