feat(remind): add yearly simple date recurrence handling
Add `yearly_simple_date` collector that detects simple yearly recurrences (`RRULE:FREQ=YEARLY` with no extra constraints) and stores the month/day pair in a new `simple_yearly` field on `Remind.rem`. When rendering, events with `simple_yearly` set are emitted as `REM <Month> <Day> MSG <summary>` instead of the full dated form. Add `month_of_int` and `string_of_month` helpers in `Utils`, and update the RRULE dataset comment with UIDs for easier debugging.
This commit is contained in:
@@ -8,6 +8,7 @@ type rem = {
|
||||
end_date : Timedesc.Date.t option; (** Optional end date for a date range *)
|
||||
time : Timedesc.Time.t option; (** Optional time specification (hour, minute) *)
|
||||
duration : Timedesc.Span.t option; (** Optional duration for timed events *)
|
||||
simple_yearly : (int * int) option; (** Optional simple yearly recurrence (month, day) *)
|
||||
recurring : Icalendar.event list;
|
||||
(** List of events that are part of the same recurring series: these are only the overrides, not the master event
|
||||
*)
|
||||
@@ -23,30 +24,39 @@ let empty =
|
||||
end_date = None;
|
||||
time = None;
|
||||
duration = None;
|
||||
simple_yearly = None;
|
||||
recurring = [];
|
||||
}
|
||||
|
||||
let render_simple_yearly month day summary =
|
||||
let month_str = month_of_int month |> string_of_month in
|
||||
spf "REM %s %d MSG %s" month_str day summary
|
||||
|
||||
let string_of_rem rem =
|
||||
let b = Buffer.create 256 in
|
||||
Buffer.add_string b "REM ";
|
||||
Buffer.add_string b (spf "INFO \"UID: %s\" " rem.original_uuid);
|
||||
Buffer.add_string b (Timedesc.Date.to_rfc3339 rem.date);
|
||||
(match rem.time with
|
||||
| Some time ->
|
||||
Buffer.add_string b " AT ";
|
||||
Buffer.add_string b (string_of_time time)
|
||||
| None -> ());
|
||||
(match rem.duration with
|
||||
| Some duration ->
|
||||
Buffer.add_string b " DURATION ";
|
||||
Buffer.add_string b (string_of_span duration);
|
||||
Buffer.add_string b ""
|
||||
| None -> ());
|
||||
(match rem.end_date with
|
||||
| Some end_date ->
|
||||
Buffer.add_string b " THROUGH ";
|
||||
Buffer.add_string b (Timedesc.Date.to_rfc3339 end_date)
|
||||
| None -> ());
|
||||
Buffer.add_string b " MSG ";
|
||||
Buffer.add_string b rem.summary;
|
||||
Buffer.contents b
|
||||
match rem.simple_yearly with
|
||||
| Some (month, day) -> render_simple_yearly month day rem.summary
|
||||
| None -> begin
|
||||
let b = Buffer.create 256 in
|
||||
Buffer.add_string b "REM ";
|
||||
Buffer.add_string b (spf "INFO \"UID: %s\" " rem.original_uuid);
|
||||
Buffer.add_string b (Timedesc.Date.to_rfc3339 rem.date);
|
||||
(match rem.time with
|
||||
| Some time ->
|
||||
Buffer.add_string b " AT ";
|
||||
Buffer.add_string b (string_of_time time)
|
||||
| None -> ());
|
||||
(match rem.duration with
|
||||
| Some duration ->
|
||||
Buffer.add_string b " DURATION ";
|
||||
Buffer.add_string b (string_of_span duration);
|
||||
Buffer.add_string b ""
|
||||
| None -> ());
|
||||
(match rem.end_date with
|
||||
| Some end_date ->
|
||||
Buffer.add_string b " THROUGH ";
|
||||
Buffer.add_string b (Timedesc.Date.to_rfc3339 end_date)
|
||||
| None -> ());
|
||||
Buffer.add_string b " MSG ";
|
||||
Buffer.add_string b rem.summary;
|
||||
Buffer.contents b
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user