src/automata@retry@internal@prng.erl

-module(automata@retry@internal@prng).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/automata/retry/internal/prng.gleam").
-export([new/1, next_u32/1, bounded/2]).
-export_type([prng_state/0]).

-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.

-opaque prng_state() :: {prng_state, integer()}.

-file("src/automata/retry/internal/prng.gleam", 74).
-spec mask32(integer()) -> integer().
mask32(Value) ->
    erlang:'band'(Value, 16#FFFFFFFF).

-file("src/automata/retry/internal/prng.gleam", 29).
?DOC(false).
-spec new(integer()) -> prng_state().
new(Seed) ->
    case mask32(Seed) of
        0 ->
            {prng_state, 1};

        Masked ->
            {prng_state, Masked}
    end.

-file("src/automata/retry/internal/prng.gleam", 39).
?DOC(false).
-spec next_u32(prng_state()) -> {integer(), prng_state()}.
next_u32(State) ->
    X0 = erlang:element(2, State),
    X1 = mask32(erlang:'bxor'(X0, erlang:'bsl'(X0, 13))),
    X2 = erlang:'bxor'(X1, erlang:'bsr'(X1, 17)),
    X3 = mask32(erlang:'bxor'(X2, erlang:'bsl'(X2, 5))),
    {X3, {prng_state, X3}}.

-file("src/automata/retry/internal/prng.gleam", 58).
?DOC(false).
-spec bounded(prng_state(), integer()) -> {integer(), prng_state()}.
bounded(State, Max_inclusive) ->
    {Raw, Next} = next_u32(State),
    case Max_inclusive =< 0 of
        true ->
            {0, Next};

        false ->
            Value = begin
                _pipe = gleam@int:modulo(Raw, Max_inclusive + 1),
                gleam@result:unwrap(_pipe, 0)
            end,
            {Value, Next}
    end.