rrule-rust
Version:
RRule implementation for browsers and Node.js written in Rust
428 lines (427 loc) • 15 kB
TypeScript
import { RRule, type RRuleLike } from './rrule';
import { type Time, DateTime, type DateTimeLike, type DateLike } from './datetime';
import { DtStart, type DtStartLike } from './dtstart';
import { ExDate, type ExDateLike } from './exdate';
import { RDate, type RDateLike } from './rdate';
/**
* Interface for controlling caching behavior of RRuleSet operations.
*
* Caching is enabled by default and significantly improves performance when repeatedly
* calling methods like `all()`, `between()`, or iterating over the same RRuleSet instance.
* However, it may consume additional memory for large recurrence sets.
*
* @example
* ```typescript
* const rruleSet = new RRuleSet({
* dtstart: new DtStart(DateTime.local(2024, 1, 1, 9, 0, 0)),
* rrules: [new RRule({ frequency: Frequency.Daily, count: 100 })]
* });
*
* // Disable caching if memory is a concern
* rruleSet.cache.disable();
*
* // Enable caching for better performance
* rruleSet.cache.enable();
*
* // Clear cached results
* rruleSet.cache.clear();
* ```
*/
export interface RRuleSetCache {
/**
* Indicates whether caching is currently disabled.
* When `true`, all operations compute results fresh without storing them.
*/
disabled: boolean;
/**
* Clears all cached results.
* Use this method when you want to free memory while keeping caching enabled.
*/
clear(): void;
/**
* Disables caching for all subsequent operations.
* Existing cached results are preserved but not used. New operations will not cache results.
*/
disable(): void;
/**
* Enables caching for all subsequent operations.
* Operations will store and reuse results to improve performance.
*/
enable(): void;
}
/**
* Options for creating an RRuleSet instance.
*/
export interface RRuleSetOptions<DT extends DateTime<Time> | DateTime<undefined>, RRDT extends DT | undefined = DT | undefined, ERDT extends DT | undefined = DT | undefined> {
/** The start date/time for the recurrence set */
readonly dtstart: DtStart<DT>;
/** Array of recurrence rules to include */
readonly rrules?: readonly RRule<RRDT>[];
/** Array of recurrence rules to exclude */
readonly exrules?: readonly RRule<ERDT>[];
/** Array of exception dates to exclude */
readonly exdates?: readonly ExDate<DT>[];
/** Array of recurrence dates to include */
readonly rdates?: readonly RDate<DT>[];
}
/**
* Plain object representation of RRuleSet.
*/
export interface RRuleSetLike<DT extends DateTimeLike | DateLike> {
/** The start date/time for the recurrence set */
readonly dtstart: DtStartLike<DT>;
/** Array of recurrence rules to include */
readonly rrules: readonly RRuleLike<DT>[];
/** Array of recurrence rules to exclude */
readonly exrules: readonly RRuleLike<DT>[];
/** Array of exception dates to exclude */
readonly exdates: readonly ExDateLike<DT>[];
/** Array of recurrence dates to include */
readonly rdates: readonly RDateLike<DT>[];
}
/**
* Represents a set of recurrence rules (RRuleSet) according to RFC 5545.
*
* RRuleSet combines multiple recurrence components:
* - DTSTART: The start date/time
* - RRULE: Rules for generating occurrences
* - EXRULE: Rules for excluding occurrences
* - RDATE: Additional dates to include
* - EXDATE: Specific dates to exclude
*
* @example
* ```typescript
* // Weekly meeting on Mondays, excluding holidays
* const rruleSet = new RRuleSet({
* dtstart: new DtStart(DateTime.local(2024, 1, 15, 9, 0, 0)),
* rrules: [
* new RRule({
* frequency: Frequency.Weekly,
* byWeekday: [Weekday.Monday]
* })
* ],
* exdates: [
* new ExDate([
* DateTime.date(2024, 1, 1), // New Year
* DateTime.date(2024, 12, 25) // Christmas
* ])
* ]
* });
*
* // Get first 10 occurrences
* const occurrences = rruleSet.all(10);
* ```
*/
export declare class RRuleSet<DT extends DateTime<Time> | DateTime<undefined>, RRDT extends DT | undefined = DT | undefined, ERDT extends DT | undefined = DT | undefined> implements Iterable<DateTime<Time> | DateTime<undefined>> {
/** The start date/time for the recurrence set */
readonly dtstart: DtStart<DT>;
/** Array of recurrence rules to include */
readonly rrules: readonly RRule<RRDT>[];
/** Array of recurrence rules to exclude */
readonly exrules: readonly RRule<ERDT>[];
/** Array of exception dates to exclude */
readonly exdates: readonly ExDate<DT>[];
/** Array of recurrence dates to include */
readonly rdates: readonly RDate<DT>[];
private _cache;
constructor(dtstart: DtStart<DT>);
constructor(options: RRuleSetOptions<DT, RRDT, ERDT>);
/**
* Provides access to cache control for this RRuleSet instance.
*
* By default, caching is enabled to optimize repeated calls to methods like `all()`,
* `between()`, and iteration. Use this property to control caching behavior based on
* your performance and memory requirements.
*
* @example
* ```typescript
* const rruleSet = new RRuleSet({
* dtstart: new DtStart(DateTime.local(2024, 1, 1, 9, 0, 0)),
* rrules: [new RRule({ frequency: Frequency.Daily })]
* });
*
* // Check if caching is disabled
* console.log(rruleSet.cache.disabled); // false
*
* // Disable caching for memory-constrained environments
* rruleSet.cache.disable();
*
* // Clear cached data to free memory
* rruleSet.cache.clear();
* ```
*/
get cache(): RRuleSetCache;
/**
* Parses an RFC 5545 formatted string into an RRuleSet.
*
* @param str - RFC 5545 formatted string containing DTSTART, RRULE, etc.
* @returns A new RRuleSet instance
*
* @example
* ```typescript
* const str = `DTSTART:20240115T090000
* RRULE:FREQ=WEEKLY;BYDAY=MO
* EXDATE:20240101,20241225`;
* const rruleSet = RRuleSet.fromString(str);
* ```
*/
static fromString<DT extends DateTime<Time> | DateTime<undefined>>(str: string): RRuleSet<DT>;
/**
* Creates an RRuleSet from a plain object representation.
*
* @param plain - Plain object with recurrence set properties
* @returns A new RRuleSet instance
*
* @example
* ```typescript
* const plain = {
* dtstart: { value: { year: 2024, month: 1, day: 15, hour: 9, minute: 0, second: 0, utc: false } },
* rrules: [{ frequency: Frequency.Weekly, byWeekday: [Weekday.Monday], ... }],
* exrules: [],
* exdates: [],
* rdates: []
* };
* const rruleSet = RRuleSet.fromPlain(plain);
* ```
*/
static fromPlain(plain: RRuleSetLike<DateTimeLike>): RRuleSet<DateTime<Time>>;
static fromPlain(plain: RRuleSetLike<DateLike>): RRuleSet<DateTime<undefined>>;
/**
* Creates a new RRuleSet with a different start date/time.
*
* @param dtstart - The new start date/time
* @returns A new RRuleSet instance
*
* @example
* ```typescript
* const rruleSet = new RRuleSet(new DtStart(DateTime.date(2024, 1, 15)));
* const updated = rruleSet.setDtStart(new DtStart(DateTime.date(2024, 2, 1)));
* ```
*/
setDtStart(dtstart: DtStart<DT>): RRuleSet<DT>;
/**
* Creates a new RRuleSet with an additional recurrence rule.
*
* @param rrule - The recurrence rule to add
* @returns A new RRuleSet instance
*
* @example
* ```typescript
* const rruleSet = new RRuleSet(new DtStart(DateTime.date(2024, 1, 15)));
* const withRule = rruleSet.addRRule(new RRule(Frequency.Weekly));
* ```
*/
addRRule<NRRDT extends DT | undefined>(rrule: RRule<NRRDT>): RRuleSet<DT, RRDT | NRRDT, ERDT>;
/**
* Creates a new RRuleSet with a different set of recurrence rules.
*
* @param rrules - The new array of recurrence rules
* @returns A new RRuleSet instance
*/
setRRules<NRDT extends DT | undefined>(rrules: readonly RRule<NRDT>[]): RRuleSet<DT, NRDT>;
/**
* Creates a new RRuleSet with an additional exclusion rule.
*
* @param rrule - The exclusion rule to add
* @returns A new RRuleSet instance
*
* @example
* ```typescript
* const rruleSet = new RRuleSet({
* dtstart: new DtStart(DateTime.date(2024, 1, 15)),
* rrules: [new RRule(Frequency.Daily)]
* });
* // Exclude weekends
* const noWeekends = rruleSet.addExRule(new RRule({
* frequency: Frequency.Weekly,
* byWeekday: [Weekday.Saturday, Weekday.Sunday]
* }));
* ```
*/
addExRule<NERDT extends DT | undefined>(rrule: RRule<NERDT>): RRuleSet<DT, RRDT, ERDT | NERDT>;
/**
* Creates a new RRuleSet with a different set of exclusion rules.
*
* @param rrules - The new array of exclusion rules
* @returns A new RRuleSet instance
*/
setExRules<ERDT extends DT | undefined>(rrules: readonly RRule<ERDT>[]): RRuleSet<DT, RRDT, ERDT>;
/**
* Creates a new RRuleSet with an additional exception date.
*
* @param exdate - The exception date(s) to add
* @returns A new RRuleSet instance
*
* @example
* ```typescript
* const rruleSet = new RRuleSet({
* dtstart: new DtStart(DateTime.date(2024, 1, 15)),
* rrules: [new RRule(Frequency.Daily)]
* });
* // Exclude specific holidays
* const withExceptions = rruleSet.addExDate(new ExDate([
* DateTime.date(2024, 1, 1),
* DateTime.date(2024, 12, 25)
* ]));
* ```
*/
addExDate(exdate: ExDate<DT>): RRuleSet<DT>;
/**
* Creates a new RRuleSet with a different set of exception dates.
*
* @param exdates - The new array of exception dates
* @returns A new RRuleSet instance
*/
setExDates(exdates: readonly ExDate<DT>[]): RRuleSet<DT>;
/**
* Creates a new RRuleSet with an additional recurrence date.
*
* @param datetime - The recurrence date(s) to add
* @returns A new RRuleSet instance
*
* @example
* ```typescript
* const rruleSet = new RRuleSet({
* dtstart: new DtStart(DateTime.date(2024, 1, 15)),
* rrules: [new RRule(Frequency.Weekly)]
* });
* // Add extra dates not covered by the rule
* const withExtras = rruleSet.addRDate(new RDate([
* DateTime.date(2024, 2, 14), // Valentine's Day special
* DateTime.date(2024, 3, 17) // St. Patrick's Day special
* ]));
* ```
*/
addRDate(datetime: RDate<DT>): RRuleSet<DT>;
/**
* Creates a new RRuleSet with a different set of recurrence dates.
*
* @param datetimes - The new array of recurrence dates
* @returns A new RRuleSet instance
*/
setRDates(datetimes: readonly RDate<DT>[]): RRuleSet<DT>;
/**
* Returns all the occurrences of the recurrence set.
*
* @param limit - Optional maximum number of occurrences to return
* @returns Array of date/time occurrences
*
* @example
* ```typescript
* const rruleSet = new RRuleSet({
* dtstart: new DtStart(DateTime.date(2024, 1, 15)),
* rrules: [new RRule({ frequency: Frequency.Daily, count: 5 })]
* });
*
* // Get all occurrences (limited by count in rule)
* const all = rruleSet.all();
*
* // Get first 10 occurrences
* const first10 = rruleSet.all(10);
* ```
*/
all(limit?: number): readonly DT[];
/**
* Returns all occurrences between two dates.
*
* @param after - The lower bound date (exclusive by default)
* @param before - The upper bound date (exclusive by default)
* @param inclusive - Whether to include the boundary dates in results
* @returns Array of date/time occurrences in the range
*
* @example
* ```typescript
* const rruleSet = new RRuleSet({
* dtstart: new DtStart(DateTime.date(2024, 1, 1)),
* rrules: [new RRule(Frequency.Daily)]
* });
*
* // Get occurrences in January 2024 (exclusive)
* const january = rruleSet.between(
* DateTime.date(2024, 1, 1),
* DateTime.date(2024, 2, 1)
* );
*
* // Get occurrences in January 2024 (inclusive)
* const januaryInclusive = rruleSet.between(
* DateTime.date(2024, 1, 1),
* DateTime.date(2024, 1, 31),
* true
* );
* ```
*/
between(after: DT, before: DT, inclusive?: boolean): readonly DT[];
/**
* Parses an RFC 5545 string and updates the RRuleSet.
*
* @param str - RFC 5545 formatted string
* @returns A new RRuleSet instance parsed from the string
*
* @example
* ```typescript
* const rruleSet = new RRuleSet(new DtStart(DateTime.date(2024, 1, 15)));
* const updated = rruleSet.setFromString(`DTSTART:20240201T090000
* RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR`);
* ```
*/
setFromString<NDT extends DateTime<Time> | DateTime<undefined> = DT>(str: string): RRuleSet<NDT>;
/**
* Converts the RRuleSet to an RFC 5545 formatted string.
*
* @returns RFC 5545 formatted string representation
*
* @example
* ```typescript
* const rruleSet = new RRuleSet({
* dtstart: new DtStart(DateTime.date(2024, 1, 15)),
* rrules: [new RRule({ frequency: Frequency.Weekly, byWeekday: [Weekday.Monday] })]
* });
* console.log(rruleSet.toString());
* // DTSTART:20240115
* // RRULE:FREQ=WEEKLY;BYDAY=MO
* ```
*/
toString(): string;
/**
* Converts the RRuleSet to a plain object representation.
*
* @returns A plain object with all RRuleSet properties
*
* @example
* ```typescript
* const rruleSet = new RRuleSet({
* dtstart: new DtStart(DateTime.date(2024, 1, 15)),
* rrules: [new RRule(Frequency.Weekly)]
* });
* const plain = rruleSet.toPlain();
* // Useful for serialization to JSON
* const json = JSON.stringify(plain);
* ```
*/
toPlain(): RRuleSetLike<DT extends DateTime<Time> ? DateTimeLike : DateLike>;
/**
* Returns an iterator for the recurrence set.
*
* This allows using RRuleSet with for-of loops and other iteration constructs.
*
* @returns An iterator over the occurrences
*
* @example
* ```typescript
* const rruleSet = new RRuleSet({
* dtstart: new DtStart(DateTime.date(2024, 1, 15)),
* rrules: [new RRule({ frequency: Frequency.Daily, count: 5 })]
* });
*
* // Iterate over occurrences
* for (const occurrence of rruleSet) {
* console.log(occurrence.toString());
* }
*
* // Use with spread operator
* const allOccurrences = [...rruleSet];
* ```
*/
[Symbol.iterator](): Iterator<DT, any, any>;
private toOptions;
}