Skip to content

Instantly share code, notes, and snippets.

@linse
Last active August 16, 2018 22:32
Show Gist options
  • Save linse/794f15af4a387b5027764cc7d2801a61 to your computer and use it in GitHub Desktop.
Save linse/794f15af4a387b5027764cc7d2801a61 to your computer and use it in GitHub Desktop.
let expand_event range exceptions timezones ((props: Icalendar.eventprop list), alarms) =
let f acc dtstart =
let recur_id : Icalendar.eventprop = match List.find_opt (function `Dtstart (prop, v) -> true | _ -> false) props with
| None -> assert false
| Some (`Dtstart (props', v)) ->
let props'', v' = normalize_date_or_datetime props' timezones (`Datetime (dtstart, false)) in
let id = function
| `Iana_param (a, b) -> `Iana_param (a, b)
| `Tzid (a, b) -> `Tzid (a, b)
| `Valuetype v -> `Valuetype v
| `Xparam ((a, b), c) -> `Xparam ((a, b), c)
in
`Recur_id (List.map id props'', v') in
let props' = List.map (function
| `Dtstart (props', `Datetime (_, utc)) ->
let props'', dtstart' = normalize_tz dtstart props' timezones in
`Dtstart (props'', `Datetime (dtstart', utc))
| `Dtstart (props', `Date _) ->
let props'', dtstart' = normalize_tz dtstart props' timezones in
`Dtstart (props'', `Date (ptime_to_date dtstart))
| `Rrule _ -> recur_id
| `Recur_id (props', `Datetime (dtstart, utc)) ->
let is_tzid = function `Tzid _ -> true | _ -> false in
let tzid = List.find_opt is_tzid props' in
begin
match tzid with
| None -> `Recur_id (props', `Datetime (dtstart, utc))
| Some (`Tzid tzid) ->
let props'' = List.filter (fun p -> not (is_tzid p)) props' in
let dtstart' = Icalendar.normalize_timezone dtstart (`Tzid tzid) timezones in
`Recur_id (props'', `Datetime (dtstart', utc))
| _ -> assert false (* without this line, the type of props' is too small - why does this solution also solve the following match case though? *)
end
| `Recur_id (props', `Date date) ->
begin
let is_tzid = function `Tzid _ -> true | _ -> false in
match List.find_opt is_tzid props' with
| None -> `Recur_id (props', `Date date)
| Some (`Tzid tzid) ->
let dtstart = date_to_ptime date in
let props'' = List.filter (fun p -> not (is_tzid p)) props' in
let dtstart' = Icalendar.normalize_timezone dtstart (`Tzid tzid) timezones in
`Recur_id (props'', `Date (ptime_to_date dtstart'))
end
| x -> x) props in
`Event (props', alarms) :: acc
in
fold_event f [] range exceptions (`Event (props, alarms))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment