Current section
Files
Jump to
Current section
Files
gen/src/ids@cuid.erl
-module(ids@cuid).
-compile(no_auto_import).
-export([start/0, gen/1, is_cuid/1, slug/1, is_slug/1]).
start() ->
gleam@otp@actor:start({state, 0, get_fingerprint()}, fun handle_msg/2).
gen(Channel) ->
gleam@otp@actor:call(Channel, fun(A) -> {generate, A} end, 1000).
is_cuid(Id) ->
gleam@string:starts_with(Id, <<"c"/utf8>>).
slug(Channel) ->
gleam@otp@actor:call(Channel, fun(A) -> {generate_slug, A} end, 1000).
is_slug(Slug) ->
SlugLength = gleam@string:length(Slug),
(SlugLength >= 7) andalso (SlugLength =< 10).
handle_msg(Msg, State) ->
case Msg of
{generate, Reply} ->
Id = format_id(
[<<"c"/utf8>>,
timestamp(),
format_count(erlang:element(2, State)),
erlang:element(3, State),
random_block(),
random_block()]
),
gleam@otp@actor:send(Reply, Id),
{continue,
erlang:setelement(2, State, new_count(erlang:element(2, State)))};
{generate_slug, Reply@1} ->
Slug = format_id(
[gleam@string:slice(timestamp(), -2, 2),
gleam@string:slice(
format_count(erlang:element(2, State)),
-4,
4
),
gleam@string:concat(
[gleam@string:slice(erlang:element(3, State), 0, 1),
gleam@string:slice(erlang:element(3, State), -1, 1)]
),
gleam@string:slice(random_block(), -2, 2)]
),
gleam@otp@actor:send(Reply@1, Slug),
{continue,
erlang:setelement(2, State, new_count(erlang:element(2, State)))}
end.
format_id(IdData) ->
gleam@string:lowercase(gleam@string:concat(IdData)).
new_count(Count) ->
case Count < 1679616 of
true ->
Count + 1;
false ->
0
end.
timestamp() ->
Secs = gleam@os:system_time(millisecond),
gleam@int:to_base_string(Secs, 36).
format_count(Num) ->
gleam@string:pad_left(gleam@int:to_base_string(Num, 36), 4, <<"0"/utf8>>).
get_fingerprint() ->
Operator = 36 * 36,
{ok, Pid} = gleam@int:parse(erlang:list_to_binary(os:getpid())),
Id = (Pid rem Operator) * Operator,
Localhost = net_adm:localhost(),
Sum = gleam@list:fold(Localhost, 0, fun(Char, Acc) -> Char + Acc end),
Hostid = ((Sum + gleam@list:length(Localhost)) + 36) rem Operator,
gleam@int:to_base_string(Id + Hostid, 36).
random_block() ->
gleam@string:pad_left(
gleam@int:to_base_string(rand:uniform(1679616 - 1), 36),
4,
<<"0"/utf8>>
).