-module(bison@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, to_int_list/1, from_string/1, to_string/1, from_datetime/1, new/0, range/3]). -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, <>} -> birl@time:from_unix(Timestamp) end. -spec compare(object_id(), object_id()) -> gleam@order:order(). compare(A, B) -> {object_id, <>} = A, {object_id, <>} = 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, <>), {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 end ), _pipe@4 = gleam@list:fold( _pipe@3, <<>>, fun(Acc@1, Code@2) -> gleam@bit_string:append(Acc@1, <>) 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_int_list_internal(bitstring(), gleam@queue:queue(integer())) -> list(integer()). to_int_list_internal(Remaining, Storage) -> <> = 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. -spec to_digit(binary()) -> {ok, integer()} | {error, nil}. to_digit(Char) -> <> = 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, <> 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(<>), {ok, Digit@1} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"bison/object_id"/utf8>>, function => <<"to_char"/utf8>>, line => 237}) end, Digit@1. -spec to_string_internal(bitstring(), binary()) -> binary(). to_string_internal(Remaining, Storage) -> <> = 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 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 => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"bison/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 => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"bison/object_id"/utf8>>, function => <<"from_datetime"/utf8>>, line => 26}) end, <> = crypto:hash(sha256, Hostname), _assert_subject@2 = begin _pipe = os:getpid(), _pipe@1 = gleam@list:fold( _pipe, <<>>, fun(Acc, 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 => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@2, module => <<"bison/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 => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@3, module => <<"bison/object_id"/utf8>>, function => <<"from_datetime"/utf8>>, line => 35}) end, _assert_subject@4 = begin _pipe@2 = <>, from_bit_string(_pipe@2) end, {ok, Id} = case _assert_subject@4 of {ok, _} -> _assert_subject@4; _assert_fail@4 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@4, module => <<"bison/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).