-module(ids@ulid). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([monotonic_generate/1, monotonic_from_timestamp/2, decode/1, from_parts/2, from_timestamp/1, generate/0, start/0]). -export_type([message/0, state/0]). -opaque message() :: {generate, gleam@erlang@process:subject({ok, binary()} | {error, binary()})} | {generate_from_timestamp, integer(), gleam@erlang@process:subject({ok, binary()} | {error, binary()})}. -opaque state() :: {state, integer(), bitstring()}. -file("/Users/rvcas/thelab/me/ids/src/ids/ulid.gleam", 56). -spec monotonic_generate(gleam@erlang@process:subject(message())) -> {ok, binary()} | {error, binary()}. monotonic_generate(Channel) -> gleam@otp@actor:call(Channel, fun(Field@0) -> {generate, Field@0} end, 1000). -file("/Users/rvcas/thelab/me/ids/src/ids/ulid.gleam", 70). -spec monotonic_from_timestamp( gleam@erlang@process:subject(message()), integer() ) -> {ok, binary()} | {error, binary()}. monotonic_from_timestamp(Channel, Timestamp) -> gleam@otp@actor:call( Channel, fun(Subject) -> {generate_from_timestamp, Timestamp, Subject} end, 1000 ). -file("/Users/rvcas/thelab/me/ids/src/ids/ulid.gleam", 119). -spec decode(binary()) -> {ok, {integer(), bitstring()}} | {error, binary()}. decode(Ulid) -> case ids@base32:decode(Ulid, <<"0123456789ABCDEFGHJKMNPQRSTVWXYZ"/utf8>>) of {ok, <>} -> {ok, {Timestamp, Randomness}}; _ -> {error, <<"Error: Decoding failed. Is a valid ULID being supplied?"/utf8>>} end. -file("/Users/rvcas/thelab/me/ids/src/ids/ulid.gleam", 97). -spec from_parts(integer(), bitstring()) -> {ok, binary()} | {error, binary()}. from_parts(Timestamp, Randomness) -> case {Timestamp, Randomness} of {Time, <>} when Time =< 281474976710655 -> _pipe = <>, _pipe@1 = ids@base32:encode( _pipe, <<"0123456789ABCDEFGHJKMNPQRSTVWXYZ"/utf8>> ), {ok, _pipe@1}; {_, _} -> Error = gleam@string:concat( [<<"Error: The timestamp is too large or randomness isn't 80 bits. Please use an Unix timestamp smaller than "/utf8>>, erlang:integer_to_binary(281474976710655), <<"."/utf8>>] ), {error, Error} end. -file("/Users/rvcas/thelab/me/ids/src/ids/ulid.gleam", 92). -spec from_timestamp(integer()) -> {ok, binary()} | {error, binary()}. from_timestamp(Timestamp) -> from_parts(Timestamp, crypto:strong_rand_bytes(10)). -file("/Users/rvcas/thelab/me/ids/src/ids/ulid.gleam", 82). -spec generate() -> binary(). generate() -> Timestamp = os:system_time(millisecond), case from_timestamp(Timestamp) of {ok, Ulid} -> Ulid; _ -> erlang:error(#{gleam_error => panic, message => <<"Error: Couldn't generate ULID."/utf8>>, module => <<"ids/ulid"/utf8>>, function => <<"generate"/utf8>>, line => 87}) end. -file("/Users/rvcas/thelab/me/ids/src/ids/ulid.gleam", 142). -spec generate_response_ulid( integer(), gleam@erlang@process:subject({ok, binary()} | {error, binary()}), state() ) -> gleam@otp@actor:next(message(), state()). generate_response_ulid(Timestamp, Reply, State) -> case erlang:element(2, State) =:= Timestamp of true -> Randomness = begin _pipe = erlang:element(3, State), _pipe@1 = binary:decode_unsigned(_pipe), _pipe@2 = gleam@int:add(_pipe@1, 1), binary:encode_unsigned(_pipe@2) end, case from_parts(Timestamp, Randomness) of {ok, Ulid} -> gleam@otp@actor:send(Reply, {ok, Ulid}); _ -> gleam@otp@actor:send( Reply, {error, <<"Error: Couldn't generate ULID."/utf8>>} ) end, gleam@otp@actor:continue({state, Timestamp, Randomness}); false -> Randomness@1 = crypto:strong_rand_bytes(10), case from_parts(Timestamp, Randomness@1) of {ok, Ulid@1} -> gleam@otp@actor:send(Reply, {ok, Ulid@1}); _ -> gleam@otp@actor:send( Reply, {error, <<"Error: Couldn't generate ULID."/utf8>>} ) end, gleam@otp@actor:continue({state, Timestamp, Randomness@1}) end. -file("/Users/rvcas/thelab/me/ids/src/ids/ulid.gleam", 128). -spec handle_msg(message(), state()) -> gleam@otp@actor:next(message(), state()). handle_msg(Msg, State) -> case Msg of {generate, Reply} -> _pipe = os:system_time(millisecond), generate_response_ulid(_pipe, Reply, State); {generate_from_timestamp, Timestamp, Reply@1} -> _pipe@1 = Timestamp, generate_response_ulid(_pipe@1, Reply@1, State) end. -file("/Users/rvcas/thelab/me/ids/src/ids/ulid.gleam", 42). -spec start() -> {ok, gleam@erlang@process:subject(message())} | {error, gleam@otp@actor:start_error()}. start() -> gleam@otp@actor:start({state, 0, <<>>}, fun handle_msg/2).