src/automata@retry@ast.erl

-module(automata@retry@ast).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/automata/retry/ast.gleam").
-export([duration_milliseconds/1, duration_seconds/1, duration_to_string/1, unsafe_milliseconds/1, from_seconds/1, from_minutes/1, from_milliseconds/1]).
-export_type([failure_kind/0, give_up_reason/0, retry_error/0, duration/0, jitter/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.

-type failure_kind() :: transient | permanent.

-type give_up_reason() :: policy_disallows_retry |
    {max_attempts_reached, integer(), integer()} |
    {permanent_failure_signaled, integer()} |
    {delay_overflow, integer()}.

-type retry_error() :: {negative_duration, binary(), integer()} |
    {duration_overflow, binary(), integer()} |
    {max_attempts_must_be_positive, integer()} |
    {multiplier_must_be_at_least_two, integer()} |
    {initial_delay_must_be_positive, integer()} |
    {cap_must_not_be_less_than_initial, integer(), integer()}.

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

-type jitter() :: no_jitter | full_jitter | equal_jitter.

-file("src/automata/retry/ast.gleam", 102).
?DOC(" Recover the raw millisecond value from a duration.\n").
-spec duration_milliseconds(duration()) -> integer().
duration_milliseconds(Duration) ->
    erlang:element(2, Duration).

-file("src/automata/retry/ast.gleam", 108).
?DOC(
    " Recover the duration in whole seconds, truncating any sub-second\n"
    " remainder.\n"
).
-spec duration_seconds(duration()) -> integer().
duration_seconds(Duration) ->
    erlang:element(2, Duration) div 1000.

-file("src/automata/retry/ast.gleam", 113).
?DOC(" Render a duration as `\"<n>ms\"`.\n").
-spec duration_to_string(duration()) -> binary().
duration_to_string(Duration) ->
    <<(erlang:integer_to_binary(erlang:element(2, Duration)))/binary,
        "ms"/utf8>>.

-file("src/automata/retry/ast.gleam", 122).
?DOC(false).
-spec unsafe_milliseconds(integer()) -> duration().
unsafe_milliseconds(Value) ->
    {duration, Value}.

-file("src/automata/retry/ast.gleam", 141).
-spec validate_unit(binary(), integer(), integer()) -> {ok, nil} |
    {error, retry_error()}.
validate_unit(Unit, Value, Upper_bound) ->
    case Value < 0 of
        true ->
            {error, {negative_duration, Unit, Value}};

        false ->
            case Value > Upper_bound of
                true ->
                    {error, {duration_overflow, Unit, Value}};

                false ->
                    {ok, nil}
            end
    end.

-file("src/automata/retry/ast.gleam", 86).
?DOC(" Build a duration from seconds.\n").
-spec from_seconds(integer()) -> {ok, duration()} | {error, retry_error()}.
from_seconds(Seconds) ->
    case validate_unit(<<"seconds"/utf8>>, Seconds, 9007199254740991 div 1000) of
        {error, Error} ->
            {error, Error};

        {ok, _} ->
            {ok, {duration, Seconds * 1000}}
    end.

-file("src/automata/retry/ast.gleam", 94).
?DOC(" Build a duration from minutes.\n").
-spec from_minutes(integer()) -> {ok, duration()} | {error, retry_error()}.
from_minutes(Minutes) ->
    case validate_unit(<<"minutes"/utf8>>, Minutes, 9007199254740991 div 60000) of
        {error, Error} ->
            {error, Error};

        {ok, _} ->
            {ok, {duration, Minutes * 60000}}
    end.

-file("src/automata/retry/ast.gleam", 126).
-spec guard_duration(binary(), integer(), integer()) -> {ok, duration()} |
    {error, retry_error()}.
guard_duration(Unit, Raw, Millis) ->
    case Raw < 0 of
        true ->
            {error, {negative_duration, Unit, Raw}};

        false ->
            case Millis > 9007199254740991 of
                true ->
                    {error, {duration_overflow, Unit, Raw}};

                false ->
                    {ok, {duration, Millis}}
            end
    end.

-file("src/automata/retry/ast.gleam", 79).
?DOC(" Build a duration from milliseconds.\n").
-spec from_milliseconds(integer()) -> {ok, duration()} | {error, retry_error()}.
from_milliseconds(Milliseconds) ->
    guard_duration(<<"milliseconds"/utf8>>, Milliseconds, Milliseconds).