From 196cfae94fbb89c1b820c0291e046cad230077ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20V=C3=B6gele?= Date: Thu, 9 May 2024 16:13:35 +0200 Subject: [PATCH] Properly handle moved appointments instead of just defining an exclusion date and a new date (this fixes edge cases where an appointment has been moved to the same date) --- src/appointment.rs | 65 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 7 deletions(-) diff --git a/src/appointment.rs b/src/appointment.rs index f648d4e..85bab95 100644 --- a/src/appointment.rs +++ b/src/appointment.rs @@ -8,6 +8,51 @@ use log::warn; use reqwest::IntoUrl; use rrule::{RRule, RRuleSet, RRuleSetIter, Tz, Unvalidated}; +#[derive(Debug, Clone)] +struct RRuleWithReplacements { + rrule_set: RRuleSet, + replacements: HashMap, DateTime>, +} + +struct RRuleWithReplacementsIter<'a> { + inner: RRuleSetIter<'a>, + rrule_set: &'a RRuleWithReplacements, +} + +impl<'a> Iterator for RRuleWithReplacementsIter<'a> { + type Item = as IntoIterator>::Item; + + fn next(&mut self) -> Option { + self.inner.next().map(|mut next_appointment| { + if let Some(replacement) = self.rrule_set.replacements.get(&next_appointment) { + next_appointment = *replacement; + } + next_appointment + }) + } +} + +impl<'a> IntoIterator for &'a RRuleWithReplacements { + type Item = as IntoIterator>::Item; + type IntoIter = RRuleWithReplacementsIter<'a>; + + fn into_iter(self) -> Self::IntoIter { + Self::IntoIter { + inner: self.rrule_set.into_iter(), + rrule_set: self, + } + } +} + +impl RRuleWithReplacements { + fn new(rrule_set: RRuleSet) -> Self { + Self { + rrule_set, + replacements: HashMap::new(), + } + } +} + pub async fn fetch_next_appointment(url: U) -> Result>> { let response = reqwest::get(url).await?.bytes().await?; @@ -25,6 +70,7 @@ pub async fn fetch_next_appointment(url: U) -> Result(url: U) -> Result(url: U) -> Result { - inner: Vec<(&'a String, DateTime, RRuleSetIter<'a>)>, + inner: Vec<(&'a String, DateTime, RRuleWithReplacementsIter<'a>)>, } impl<'a> Iterator for AppointmentsIterator<'a> { @@ -92,7 +143,7 @@ trait IterAppointments { fn iter_appointments(&self) -> AppointmentsIterator<'_>; } -impl IterAppointments for HashMap { +impl IterAppointments for HashMap { fn iter_appointments(&self) -> AppointmentsIterator { let mut inner = vec![]; for (uid, rrule_set) in self {