Packages
gleam_bson
0.24.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([to_datetime/1, compare/2, to_bit_string/1, from_int_list/1, from_bit_string/1, from_string/1, from_datetime/1, new/0, range/3, to_string/1, to_int_list/1]).
-export_type([object_id/0]).
-opaque object_id() :: {object_id, bitstring()}.
-spec to_datetime(object_id()) -> birl@time:date_time().
to_datetime(Id) ->
case Id of
{object_id, <<Timestamp:32/big, _/bitstring>>} ->
birl@time:from_unix(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 => 237})
end,
Digit@1.
-spec from_datetime(birl@time:date_time()) -> object_id().
from_datetime(Datetime) ->
Moment = birl@time:to_unix(Datetime),
_assert_subject = gleam@int:modulo(birl@time:monotonic_now(), 16#ffffff),
{ok, Counter} = 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 => <<"from_datetime"/utf8>>,
line => 24})
end,
_assert_subject@1 = inet:gethostname(),
{ok, Hostname} = 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 => <<"from_datetime"/utf8>>,
line => 26})
end,
<<Machine_id:24, _/bitstring>> = crypto:hash(sha256, Hostname),
_assert_subject@2 = 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@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 => <<"from_datetime"/utf8>>,
line => 30})
end,
_assert_subject@3 = gleam@int:parse(String_pid),
{ok, 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 => <<"from_datetime"/utf8>>,
line => 35})
end,
_assert_subject@4 = 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@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 => <<"from_datetime"/utf8>>,
line => 37})
end,
Id.
-spec new() -> object_id().
new() ->
from_datetime(birl@time:utc_now()).
-spec range(
object_id(),
gleam@option:option(object_id()),
birl@duration:duration()
) -> gleam@iterator:iterator(object_id()).
range(A, B, S) ->
_pipe = birl@time:range(
to_datetime(A),
gleam@option:map(B, fun to_datetime/1),
S
),
gleam@iterator:map(_pipe, fun from_datetime/1).
-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.