diff options
Diffstat (limited to 'src/icalwrap/icalvevent.rs')
-rw-r--r-- | src/icalwrap/icalvevent.rs | 92 |
1 files changed, 38 insertions, 54 deletions
diff --git a/src/icalwrap/icalvevent.rs b/src/icalwrap/icalvevent.rs index 126eb77..0e13718 100644 --- a/src/icalwrap/icalvevent.rs +++ b/src/icalwrap/icalvevent.rs @@ -1,15 +1,15 @@ -use chrono::{Duration, DateTime, Date, Utc, TimeZone, Local}; use std::ffi::CStr; use super::IcalComponent; use super::IcalVCalendar; use super::IcalTime; +use super::IcalTimeZone; use ical; pub struct IcalVEvent { ptr: *mut ical::icalcomponent, parent: Option<IcalVCalendar>, - instance_timestamp: Option<DateTime<Local>>, + instance_timestamp: Option<IcalTime>, } impl Drop for IcalVEvent { @@ -42,12 +42,12 @@ impl IcalVEvent { } } - pub fn get_dtend_unix(&self) -> Option<i64> { + pub fn get_dtend(&self) -> Option<IcalTime> { match self.instance_timestamp { - Some(timestamp) => unsafe { + Some(ref timestamp) => unsafe { let icalduration = ical::icalcomponent_get_duration(self.ptr); - let duration = Duration::seconds(i64::from(ical::icaldurationtype_as_int(icalduration))); - Some(timestamp.checked_add_signed(duration)?.timestamp()) + let dtend = ical::icaltime_add(**timestamp, icalduration); + Some(IcalTime::from(dtend)) }, None => unsafe { @@ -56,50 +56,31 @@ impl IcalVEvent { if ical::icaltime_is_null_time(dtend) == 1 { None } else { - Some(ical::icaltime_as_timet_with_zone(dtend, dtend.zone)) + Some(IcalTime::from(dtend)) } } } } - pub fn get_dtstart_ical(&self) -> Option<IcalTime> { + pub fn get_dtstart(&self) -> Option<IcalTime> { match self.instance_timestamp { - Some(timestamp) => Some(IcalTime::from_timestamp(timestamp.timestamp())), + Some(ref timestamp) => Some(timestamp.clone()), None => unsafe { let dtstart = ical::icalcomponent_get_dtstart(self.ptr); if ical::icaltime_is_null_time(dtstart) == 1 { None } else { - let icaltime = IcalTime::from(dtstart); - Some(icaltime) + Some(IcalTime::from(dtstart)) } } } } - pub fn get_dtend(&self) -> Option<DateTime<Local>> { - let dtend = self.get_dtend_unix()?; - Some(Local.timestamp(dtend, 0)) - } - - pub fn get_dtstart(&self) -> Option<DateTime<Local>> { - let dtstart = self.get_dtstart_ical()?.get_timestamp(); - Some(Local.timestamp(dtstart, 0)) - } - - pub fn get_dtstart_date(&self) -> Option<Date<Local>> { - Some(self.get_dtstart()?.date()) - } - - pub fn get_dtend_date(&self) -> Option<Date<Local>> { - Some(self.get_dtend()?.date()) - } - - pub fn get_last_relevant_date(&self) -> Option<Date<Local>> { + pub fn get_last_relevant_date(&self) -> Option<IcalTime> { if self.is_allday() { - self.get_dtend().map( |dtend| dtend.date().pred()) + self.get_dtend().map(|dtend| dtend.pred()) } else { - self.get_dtend().map( |dtend| dtend.date()) + self.get_dtend().map(|dtend| dtend) } } @@ -111,18 +92,22 @@ impl IcalVEvent { !self.get_properties(ical::icalproperty_kind_ICAL_RRULE_PROPERTY).is_empty() } - pub fn get_recur_datetimes(&self) -> Vec<DateTime<Utc>> { - let mut result = vec!(); + pub fn get_recur_datetimes(&self) -> Vec<IcalTime> { + let mut result: Vec<IcalTime> = vec!(); let result_ptr: *mut ::std::os::raw::c_void = &mut result as *mut _ as *mut ::std::os::raw::c_void; + let dtstart = self.get_dtstart().unwrap(); unsafe { - let dtstart = ical::icalcomponent_get_dtstart(self.ptr); let mut dtend = ical::icalcomponent_get_dtend(self.ptr); //unroll up to 1 year in the future dtend.year += 1; - ical::icalcomponent_foreach_recurrence(self.ptr, dtstart, dtend, Some(recur_callback), result_ptr); + ical::icalcomponent_foreach_recurrence(self.ptr, *dtstart, dtend, Some(recur_callback), result_ptr); + } + + if dtstart.is_date() { + result = result.into_iter().map(|time| time.as_date()).collect(); } result @@ -131,27 +116,26 @@ impl IcalVEvent { pub fn is_recur_valid(&self) -> bool { if self.is_recur_master() { true - } else if self.is_recur() { - let timestamp = self.instance_timestamp.unwrap(); + } else if let Some(ref timestamp) = self.instance_timestamp { let recur_times = self.get_recur_datetimes(); - recur_times.contains(×tamp.with_timezone(&Utc)) + recur_times.contains(timestamp) } else { self.instance_timestamp.is_none() } } - pub fn with_internal_timestamp(&self, datetime: DateTime<Local>) -> IcalVEvent { + pub fn with_internal_timestamp(&self, datetime: &IcalTime) -> IcalVEvent { IcalVEvent { ptr: self.ptr, parent: self.parent.as_ref().map(|parent| parent.shallow_copy()), - instance_timestamp: Some(datetime), + instance_timestamp: Some(datetime.clone()), } } pub fn get_recur_instances(&self) -> impl Iterator<Item = IcalVEvent> + '_ { self.get_recur_datetimes().into_iter() - .map(|recur_utc| recur_utc.with_timezone(&Local)) - .map(move |recur_local| self.with_internal_timestamp(recur_local)) + .map(|recur_utc| recur_utc.with_timezone(&IcalTimeZone::local())) + .map(move |recur_local| self.with_internal_timestamp(&recur_local)) } pub fn get_parent(&self) -> Option<&IcalVCalendar> { @@ -210,12 +194,11 @@ extern "C" fn recur_callback( _comp: *mut ical::icalcomponent, span: *mut ical::icaltime_span, data: *mut ::std::os::raw::c_void) { - let data: &mut Vec<DateTime<Utc>> = unsafe { &mut *(data as *mut Vec<DateTime<Utc>>) }; + let data: &mut Vec<IcalTime> = unsafe { &mut *(data as *mut Vec<IcalTime>) }; let spanstart = unsafe { - trace!("callback!, {:?}", *span); let start = (*span).start; - Utc.timestamp(start, 0) + IcalTime::from_timestamp(start) }; data.push(spanstart); @@ -232,8 +215,8 @@ mod tests { testdata::setup(); let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_RECUR, None).unwrap(); let event = cal.get_principal_event(); - assert_eq!(Local.ymd(2018, 10, 11), event.get_dtstart_date().unwrap()); - assert_eq!(Local.ymd(2018, 10, 13), event.get_dtend_date().unwrap()); + assert_eq!(IcalTime::from_ymd(2018, 10, 11), event.get_dtstart().unwrap()); + assert_eq!(IcalTime::from_ymd(2018, 10, 13), event.get_dtend().unwrap()); assert_eq!("RRULE:FREQ=WEEKLY;COUNT=10", event.get_property(ical::icalproperty_kind_ICAL_RRULE_PROPERTY).unwrap().as_ical_string()); assert_eq!(10, event.get_recur_datetimes().len()); assert_eq!(10, event.get_recur_instances().count()); @@ -328,7 +311,7 @@ mod tests { fn test_is_recur_master_instance() { let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_RECUR, None).unwrap(); let event = cal.get_principal_event(); - let event = event.with_internal_timestamp(Local.ymd(2018, 01, 01).and_hms(0, 0, 0)); + let event = event.with_internal_timestamp(&IcalTime::from_ymd(2018, 01, 01)); assert!(!event.is_recur_master()); } @@ -344,8 +327,9 @@ mod tests { let event = cal.get_principal_event(); let mut recur_instances = event.get_recur_instances(); - assert_eq!(Utc.ymd(2018, 10, 11).and_hms(0, 0, 0).with_timezone(&Local), recur_instances.next().unwrap().get_dtstart().unwrap()); - assert_eq!(Utc.ymd(2018, 10, 18).and_hms(0, 0, 0).with_timezone(&Local), recur_instances.next().unwrap().get_dtstart().unwrap()); + let local = IcalTimeZone::local(); + assert_eq!(IcalTime::from_ymd(2018, 10, 11).with_timezone(&local), recur_instances.next().unwrap().get_dtstart().unwrap()); + assert_eq!(IcalTime::from_ymd(2018, 10, 18).with_timezone(&local), recur_instances.next().unwrap().get_dtstart().unwrap()); } #[test] @@ -361,7 +345,7 @@ mod tests { let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_RECUR, None).unwrap(); let event = cal.get_principal_event(); - let event = event.with_internal_timestamp(event.get_dtstart().unwrap()); + let event = event.with_internal_timestamp(&event.get_dtstart().unwrap()); assert!(event.is_recur_valid()); } @@ -371,7 +355,7 @@ mod tests { let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_RECUR, None).unwrap(); let event = cal.get_principal_event(); - let event = event.with_internal_timestamp(Utc.ymd(2010, 01, 01).and_hms(0, 0, 0).with_timezone(&Local)); + let event = event.with_internal_timestamp(&IcalTime::from_ymd(2010, 01, 01)); assert!(!event.is_recur_valid()); } @@ -381,7 +365,7 @@ mod tests { let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_RECUR, None).unwrap(); let event = cal.get_principal_event(); - let event = event.with_internal_timestamp(Utc.ymd(2018, 10, 25).and_hms(0, 0, 0).with_timezone(&Local)); + let event = event.with_internal_timestamp(&IcalTime::from_ymd(2018, 10, 25)); assert!(event.is_recur_valid()); } |