Resolve RRULE BY* selection tokens during recurrence expansion.
Called from Tempo.to_interval/2's recurrence loop. Given a
candidate occurrence and a repeat_rule whose :time carries
a [{:selection, [...]}] keyword list (the shared AST produced
by Tempo.RRule.parse/2 and Tempo.RRule.Expander.to_ast/3),
decide whether the candidate is kept, dropped, or expanded into
multiple occurrences.
Implemented rules
Per RFC 5545 §3.3.10's EXPAND/LIMIT table:
| Part | Role and when |
|---|---|
BYMONTH | LIMIT — always. |
BYMONTHDAY | LIMIT — any FREQ except WEEKLY (forbidden). |
BYYEARDAY | LIMIT — any FREQ coarser than DAILY. |
BYWEEKNO | LIMIT — YEARLY only. |
BYDAY (no ordinal) | LIMIT for DAILY/HOURLY/MINUTELY/SECONDLY; |
| EXPAND within the enclosing week/month/year for | |
| WEEKLY, MONTHLY, YEARLY. | |
BYDAY (with ordinal) | EXPAND — pairs (ordinal, weekday) like |
1MO and -1FR pick the Nth / Nth-from-last | |
| matching weekday within the enclosing period | |
| (month for MONTHLY, year for YEARLY). Backed by | |
Calendrical.Kday.nth_kday/3. | |
BYHOUR | EXPAND when FREQ is coarser than hour; LIMIT |
| when FREQ is hour-or-finer. | |
BYMINUTE | Same pattern at the minute unit. |
BYSECOND | Same pattern at the second unit. |
BYSETPOS | LIMIT — applied last, across the post-filter |
| per-period candidate set. Negative values count | |
from the end (-1 = last). |
Tokens this module doesn't interpret pass through unchanged so partial support is correct for the partial inputs.
Summary
Functions
Apply a repeat_rule to one candidate occurrence and return the
resulting list of occurrences.
Functions
@spec apply(Tempo.Interval.t(), Tempo.t() | nil, atom()) :: [Tempo.Interval.t()]
Apply a repeat_rule to one candidate occurrence and return the
resulting list of occurrences.
Arguments
candidateis aTempo.Interval.t/0— the current occurrence under consideration.repeat_ruleis eithernil(no rule — passthrough) or a%Tempo{}whose:timeholds[selection: [...]].freqis the enclosingFREQatom (:second,:minute,:hour,:day,:week,:month,:year). Drives the EXPAND-vs-LIMIT dispatch for rules whose role depends on the enclosing frequency.
Returns
- A list of
Tempo.Interval.t/0occurrences —[]on LIMIT rejection,[candidate]on passthrough or LIMIT accept,[c1, c2, …]on EXPAND.
Examples
iex> candidate = %Tempo.Interval{from: ~o"2022-06-15", to: ~o"2022-06-16"}
iex> rule = %Tempo{time: [selection: [month: 6]], calendar: Calendrical.Gregorian}
iex> Tempo.RRule.Selection.apply(candidate, rule, :month)
[candidate]
iex> candidate = %Tempo.Interval{from: ~o"2022-07-15", to: ~o"2022-07-16"}
iex> rule = %Tempo{time: [selection: [month: 6]], calendar: Calendrical.Gregorian}
iex> Tempo.RRule.Selection.apply(candidate, rule, :month)
[]