src/automata@rrule@iterator.erl

-module(automata@rrule@iterator).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/automata/rrule/iterator.gleam").
-export([step/1, 'after'/2]).
-export_type([r_rule_iterator/0, step/0]).

-opaque r_rule_iterator() :: {r_rule_iterator,
        automata@rrule@normalize:r_rule_plan(),
        automata@schedule@ast:date_time(),
        integer()}.

-type step() :: {yield,
        automata@schedule@ast:valid_date_time(),
        r_rule_iterator()} |
    done.

-file("src/automata/rrule/iterator.gleam", 42).
-spec yield_next(r_rule_iterator()) -> step().
yield_next(Iterator) ->
    case automata@rrule@evaluator:next_occurrence(
        erlang:element(2, Iterator),
        erlang:element(3, Iterator),
        0
    ) of
        {some, At} ->
            {yield,
                automata@schedule@ast:unsafe_assume_valid(At),
                {r_rule_iterator,
                    erlang:element(2, Iterator),
                    automata@internal@calendar:add_seconds(At, 1),
                    erlang:element(4, Iterator) + 1}};

        none ->
            done
    end.

-file("src/automata/rrule/iterator.gleam", 31).
-spec step(r_rule_iterator()) -> step().
step(Iterator) ->
    case erlang:element(5, erlang:element(2, Iterator)) of
        {count, Limit} ->
            case erlang:element(4, Iterator) >= Limit of
                true ->
                    done;

                false ->
                    yield_next(Iterator)
            end;

        _ ->
            yield_next(Iterator)
    end.

-file("src/automata/rrule/iterator.gleam", 57).
-spec start_cursor(
    automata@rrule@normalize:r_rule_plan(),
    automata@schedule@ast:boundary()
) -> automata@schedule@ast:date_time().
start_cursor(Plan, Boundary) ->
    case Boundary of
        {inclusive, Valid} ->
            Datetime = automata@schedule@ast:valid_datetime_value(Valid),
            case automata@internal@calendar:less_than(
                Datetime,
                erlang:element(2, Plan)
            ) of
                true ->
                    erlang:element(2, Plan);

                false ->
                    Datetime
            end;

        {exclusive, Valid@1} ->
            Datetime@1 = automata@schedule@ast:valid_datetime_value(Valid@1),
            case automata@internal@calendar:less_than(
                Datetime@1,
                erlang:element(2, Plan)
            ) of
                true ->
                    erlang:element(2, Plan);

                false ->
                    automata@internal@calendar:add_seconds(Datetime@1, 1)
            end
    end.

-file("src/automata/rrule/iterator.gleam", 22).
-spec 'after'(
    automata@rrule@normalize:r_rule_plan(),
    automata@schedule@ast:boundary()
) -> r_rule_iterator().
'after'(Plan, Boundary) ->
    Cursor = start_cursor(Plan, Boundary),
    {r_rule_iterator,
        Plan,
        Cursor,
        automata@rrule@evaluator:yielded_before(Plan, Cursor)}.