Current section
Files
Jump to
Current section
Files
src/bigben@fake_clock.erl
-module(bigben@fake_clock).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([now/1, set_now/2, advance/2, new_at/1, new/0]).
-export_type([fake_clock/0, message/0]).
-opaque fake_clock() :: {fake_clock, gleam@erlang@process:subject(message())}.
-type message() :: {get, gleam@erlang@process:subject(birl:time())} |
{set, birl:time()} |
{advance, birl@duration:duration()}.
-spec now(fake_clock()) -> birl:time().
now(Clock) ->
gleam@erlang@process:call(
erlang:element(2, Clock),
fun(Field@0) -> {get, Field@0} end,
10
).
-spec set_now(fake_clock(), birl:time()) -> nil.
set_now(Clock, Now) ->
gleam@erlang@process:send(erlang:element(2, Clock), {set, Now}).
-spec advance(fake_clock(), birl@duration:duration()) -> nil.
advance(Clock, Duration) ->
gleam@erlang@process:send(erlang:element(2, Clock), {advance, Duration}).
-spec handle_message(message(), birl:time()) -> gleam@otp@actor:next(any(), birl:time()).
handle_message(Message, State) ->
case Message of
{get, Client} ->
gleam@erlang@process:send(Client, State),
gleam@otp@actor:continue(State);
{set, Now} ->
gleam@otp@actor:continue(Now);
{advance, Duration} ->
gleam@otp@actor:continue(birl:add(State, Duration))
end.
-spec new_at(birl:time()) -> fake_clock().
new_at(Now) ->
_assert_subject = gleam@otp@actor:start(Now, fun handle_message/2),
{ok, Subject} = 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 => <<"bigben/fake_clock"/utf8>>,
function => <<"new_at"/utf8>>,
line => 22})
end,
{fake_clock, Subject}.
-spec new() -> fake_clock().
new() ->
new_at(birl:utc_now()).