Files
craft-libs/crates/ical/README.md
Dylan M. TaylorandMartin Ball ed16993b3b Add craft-ical: iCalendar lines, values, rules and VTIMEZONE from MailCraft (#966)
MailCraft crates/ical at a44a450: content lines, DATE/DATE-TIME values,
durations and text, the common subset of recurrence rules, and VTIMEZONE
definitions read and written, with their tests. Times are chrono values; the
zone database the writer needs is the caller's, through ZoneRules. The event
and to-do mapping onto MailCraft's model stays in MailCraft.

Co-authored-by: Martin Ball <98639962+benandez@users.noreply.github.com>
2026-11-11 19:30:23 -05:00

57 lines
3.2 KiB
Markdown

# craft-ical
iCalendar (RFC 5545) building blocks, read and written. Times are `chrono` values; instants are
`i64` seconds since 1970-01-01T00:00:00Z.
- **`lines`**: `Lines` unfolds a text (CRLF, LF or CR; a byte order mark is skipped);
`ContentLine::parse` splits `NAME;PARAM="quoted",x:value` into an upper-cased name,
parameters (RFC 6868 caret escapes undone) and the value as written; `fold` writes a line in
75-octet pieces without splitting a character; `param_value` quotes and escapes a parameter.
- **`values`**: `When` (`DATE`, floating or zoned `DATE-TIME`, UTC `DATE-TIME`, with the ISO 8601
punctuation some writers add), `parse_duration`, `escape_text` / `unescape_text`, `split_list`,
`format_date` / `format_local` / `format_utc`, and the wall-clock helpers they rest on.
- **`rrule`**: `Recurrence`, the subset of RRULE calendars show and edit (daily, weekly, monthly,
yearly; interval; weekdays; the nth or last weekday; count; until), `parse_rrule` and
`format_rrule`, and `format_for` / `format_zoned`, which spell out the start's weekday and
month and give `UNTIL` the start's value type. A rule outside the subset is read as the nearest
it holds.
- **`zones`**: `TimeZones::collect` reads a text's `VTIMEZONE`s (yearly rules by weekday or day
of the month, `UNTIL`, `COUNT`, `RDATE`s); a `VTimezone` answers `offset_at(instant)`,
`offset_for_wall(wall)` and `instant(wall)`, with RFC 5545's reading of skipped and repeated
hours. `write_vtimezone` writes a zone from the caller's `ZoneRules` (offset at an instant,
transitions): one `DAYLIGHT` and one `STANDARD` part with yearly rules where the zone keeps one
rule, else change by change.
No time-zone database is here: matching a `TZID` to an IANA or Windows zone, and which zone an
event is shown in, are the caller's. So is what events and to-dos mean: an app reads them from
`ContentLine`s with these values and maps them onto its own model.
## Hostile input
Nothing panics on any text.
| Limit | Value |
|---|---|
| unfolded line (`lines::MAX_LINE`) | 1 MiB |
| parameters on a line, values of a parameter | 64 each |
| recurrence rule | 4096 bytes, 64 parts |
| durations | about 10,000 years |
| zones per text (`zones::MAX_ZONES`) | 64 |
| parts per zone, dates per part | 64 each |
| `TZID` kept (`zones::MAX_TZID`) | 128 bytes |
| offsets | at most 18 hours |
| work on zone definitions per text (`zones::WORK_BUDGET`) | 20,000,000 units, spent by the caller through `TimeZones::spend` |
Every date and time written is in the years 1 to 9999; a value outside them is moved to the
nearest end.
## Origin
MailCraft `crates/ical` (`lines.rs`, `values.rs`, `rrule.rs`, `zones.rs`) at
[a44a450](https://github.com/UCS-Care-Group/mailcraft/commit/a44a45013d1c6396229c40ab60172d1882b368d5),
by Martin Ball and the MailCraft contributors (MIT OR Apache-2.0), with their tests. MailCraft's
own date types are replaced by `chrono`, its time-zone database by the `ZoneRules` trait (the
writer's tests use rule zones built in the test), and its recurrence model by `Recurrence`.
MailCraft's event and to-do reader and writer (`read.rs`, `write.rs`), and the matching of a
`TZID` against its zone database, stay in MailCraft as the mapping onto its model.