ical_rust 0.8.12

A lightweight, efficient, and robust iCalendar (ics) parser and recurrence expander library
Documentation

ical_rust ๐Ÿ“…

Crates.io Documentation License: MIT

ical_rust is a lightweight, efficient, and robust Rust library for parsing iCalendar (.ics) files and dynamically expanding recurring events. It simplifies scheduling logic by fully evaluating complex recurrence rules (RRULE) and exclusion dates (EXDATE) to calculate concrete event occurrences.


๐Ÿš€ Features

  • iCalendar Parser: Robust parsing of .ics file streams, automatically handling folded lines and block structures.
  • Recurrence Expansion: Comprehensive support for recurring events (RRULE), supporting YEARLY, MONTHLY, WEEKLY, and DAILY frequencies, intervals, count limiters, until dates, specific weekdays (BYDAY), and day of month (BYMONTHDAY).
  • Exclusion Dates (EXDATE): Supports exclusion lists to accurately skip specified recurrence dates.
  • Timezone Integration: High-fidelity timezone management backed by the robust chrono and chrono-tz libraries.
  • Collision & Overlap Queries: Evaluate active events or find next occurrences with simple APIs.

๐Ÿ“ฆ Installation

Add ical_rust to your Cargo.toml:

[dependencies]
ical_rust = "0.8.12"

๐Ÿ› ๏ธ Quick Start

Here is a simple example showing how to parse an iCalendar string, access an event, and expand its recurring occurrences:

use ical_rust::VCalendar;

fn main() {
    // A sample ICS payload containing a recurring event
    let ics_content = "BEGIN:VCALENDAR\r\n\
BEGIN:VEVENT\r\n\
DTSTART;TZID=Europe/Rome:20230101T090000\r\n\
LAST-MODIFIED:20230101T170000Z\r\n\
CREATED:20230101T170000Z\r\n\
DTSTAMP:20230101T170000Z\r\n\
SUMMARY:Rust Pair Programming\r\n\
SEQUENCE:0\r\n\
RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR;COUNT=10\r\n\
END:VEVENT\r\n\
END:VCALENDAR";

    // 1. Parse the iCalendar content
    let cal = VCalendar::try_from(ics_content).expect("Failed to parse calendar");

    // 2. Access the parsed event
    let event = &cal.events[0];
    println!("Calendar Event Found: {}", event.summary);

    // 3. Iterate over the calculated occurrences
    println!("\nExpanding Recurrence Rule ({}):", event.rrule.as_ref().unwrap());
    for (i, occurrence) in event.into_iter().enumerate() {
        println!("  Occurrence #{}:", i + 1);
        println!("    Start: {:?}", occurrence.start);
        println!("    End:   {:?}", occurrence.end);
    }
}

๐Ÿ” Core Architecture

VCalendar

The main entrance point and container for parsed iCalendar information. It manages parsed VTimezone collections and lists of VEvent records.

  • Implementations of TryFrom<&str> and FromStr allow direct instantiation from file-read contents.
  • occurrences_between(start, end): Returns all (event, occurrence) pairs across the calendar overlapping [start, end], sorted chronologically.
  • next_occurrences_since(dt): Returns the next active or upcoming occurrence for each event in the calendar, sorted chronologically.

VEvent

Represents an individual event block (VEVENT). Contains standard properties:

  • dt_start / dt_end: Event lifetime boundaries as DateOrDateTime.
  • summary / description: Metadata explaining the event (with RFC 5545 text unescaping).
  • rrule: Optional composable RRule recurrence rule.
  • exdates: Optional list of excluded DateOrDateTime values.

You can query individual events using:

  • into_iter(): Returns a VEventIterator that generates each concrete recurrence instance of the event as a Range<DateOrDateTime>.
  • occurrences_between(start, end): Collects all occurrences of the event overlapping [start, end].
  • next_occurrence_since(dt): Finds the next occurrence of the event that is active or starts after a specified time.

DateOrDateTime

A custom enum handling both single full-day bounds and precise timezone-associated date-times:

  • DateOrDateTime::WholeDay(NaiveDate)
  • DateOrDateTime::DateTime { utc: DateTime<Utc>, tz: Option<Tz> }

Provides support for calculations, incrementing components safely (e.g. leap years, variable-length months), and testing for intersection overlapping (intersects).

โš ๏ธ Error Handling

Since version 0.6.0, all parsing and domain-specific errors are centralized under the ical_rust::errors module for type safety and consistent error reporting. Key error types include:

  • BlockParseError: Errors parsing folded lines and block structures.
  • VCalendarParseError: Failures specific to calendar blocks.
  • VEventParseError: Failures when parsing events.
  • TzIdDateTimeParseError: Timezone and date-time format errors.

All error types implement std::error::Error and utilize the thiserror crate to format informative error messages.


๐Ÿงช Running Tests

The library contains a robust test suite covering edge cases in timezone calculation, rule iteration, and parser syntax. You can run them locally using:

cargo test

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.