diff options
-rw-r--r-- | src/actions/agenda.rs | 20 | ||||
-rw-r--r-- | src/actions/index/bucketable.rs | 4 | ||||
-rw-r--r-- | src/actions/new.rs | 4 | ||||
-rw-r--r-- | src/icalwrap/icaltime.rs | 97 | ||||
-rw-r--r-- | src/icalwrap/icaltimezone.rs | 6 | ||||
-rw-r--r-- | src/icalwrap/icalvcalendar.rs | 34 | ||||
-rw-r--r-- | src/icalwrap/icalvevent.rs | 92 | ||||
-rw-r--r-- | src/icalwrap/mod.rs | 4 | ||||
-rw-r--r-- | src/khline.rs | 25 | ||||
-rw-r--r-- | src/selectors/mod.rs | 6 | ||||
-rw-r--r-- | src/utils/dateutil.rs | 4 |
11 files changed, 184 insertions, 112 deletions
diff --git a/src/actions/agenda.rs b/src/actions/agenda.rs index 3dd6ea4..b89b0a8 100644 --- a/src/actions/agenda.rs +++ b/src/actions/agenda.rs @@ -1,4 +1,4 @@ -use chrono::{Datelike, TimeZone, Local, Date}; +use chrono::{DateTime, Datelike, TimeZone, Local, Date}; use yansi::{Style}; use itertools::Itertools; @@ -38,6 +38,7 @@ pub fn show_events_cursor( Some((_, event, _)) => { event .get_dtstart() + .map(|dtstart| dtstart.into()) .unwrap_or_else(|| Local.timestamp(0, 0)) .date() } @@ -135,7 +136,7 @@ pub fn event_line( Ok(format!("{:3} {}", cursor_icon, summary)) } else { let mut time_sep = " "; - let dtstart = event.get_dtstart().ok_or("Invalid DTSTART")?; + let dtstart: DateTime<Local> = event.get_dtstart().ok_or("Invalid DTSTART")?.into(); let start_string = if dtstart.date() != cur_day { "".to_string() } else { @@ -143,7 +144,7 @@ pub fn event_line( format!("{}", dtstart.format("%H:%M")) }; - let dtend = event.get_dtend().ok_or("Invalid DTEND")?; + let dtend: DateTime<Local> = event.get_dtend().ok_or("Invalid DTEND")?.into(); let end_string = if dtend.date() != cur_day { "".to_string() } else { @@ -157,16 +158,21 @@ pub fn event_line( impl IcalVEvent { fn starts_on(&self, date: Date<Local>) -> bool { - self.get_dtstart().unwrap().date() == date + let dtstart: Date<Local> = self.get_dtstart().unwrap().into(); + dtstart == date } fn relevant_on(&self, date: Date<Local>) -> bool { - self.get_dtstart().map(|dtstart| dtstart.date() <= date).unwrap_or(false) && - self.get_last_relevant_date().map(|enddate| enddate >= date).unwrap_or(false) + let dtstart: Option<Date<Local>> = self.get_dtstart().map(|date| date.into()); + let last_relevant_date: Option<Date<Local>> = self.get_last_relevant_date().map(|date| date.into()); + + dtstart.map(|dtstart| dtstart <= date).unwrap_or(false) && + last_relevant_date.map(|enddate| enddate >= date).unwrap_or(false) } fn continues_after(&self, date: Date<Local>) -> bool { - self.get_last_relevant_date() + let last_relevant_date: Option<Date<Local>> = self.get_last_relevant_date().map(|date| date.into()); + last_relevant_date .map(|enddate| enddate > date) .unwrap_or(false) } diff --git a/src/actions/index/bucketable.rs b/src/actions/index/bucketable.rs index 0600b10..f292c98 100644 --- a/src/actions/index/bucketable.rs +++ b/src/actions/index/bucketable.rs @@ -25,8 +25,8 @@ impl Bucketable for IcalVEvent { fn get_buckets(&self) -> Result<HashMap<String, Vec<String>>, String> { let mut result: HashMap<String, Vec<String>> = HashMap::new(); - let start_date = self.get_dtstart_date().ok_or_else(|| format!("Invalid DTSTART in {}", self.get_uid()))?; - let mut end_date = self.get_dtend_date().unwrap_or(start_date); + let start_date: Date<Local> = self.get_dtstart().ok_or_else(|| format!("Invalid DTSTART in {}", self.get_uid()))?.into(); + let mut end_date: Date<Local> = self.get_dtend().map(|date| date.into()).unwrap_or(start_date); // end-dtimes are non-inclusive // so in case of date-only events, the last day of the event is dtend-1 diff --git a/src/actions/new.rs b/src/actions/new.rs index bf26ba2..4b0c93b 100644 --- a/src/actions/new.rs +++ b/src/actions/new.rs @@ -235,8 +235,8 @@ mod tests { .with_eventprops(&ep); let event = cal.get_principal_event(); - assert_eq!(from, event.get_dtstart().unwrap()); - assert_eq!(to, event.get_dtend().unwrap()); + assert_eq!(from, Into::<DateTime<Local>>::into(event.get_dtstart().unwrap())); + assert_eq!(to, Into::<DateTime<Local>>::into(event.get_dtend().unwrap())); assert_eq!(summary, event.get_summary().unwrap()); assert_eq!(location, event.get_location().unwrap()); } diff --git a/src/icalwrap/icaltime.rs b/src/icalwrap/icaltime.rs index 72aa533..e62df1e 100644 --- a/src/icalwrap/icaltime.rs +++ b/src/icalwrap/icaltime.rs @@ -1,6 +1,6 @@ use std::ops::Deref; use std::ffi::{CStr,CString}; -use chrono::prelude::*; +use chrono::{Date,DateTime,TimeZone,Utc,Local}; use ical; use utils::dateutil; use super::IcalTimeZone; @@ -8,15 +8,44 @@ use super::TZ_MUTEX; use std::fmt::{Error,Display,Formatter}; use std::str::FromStr; +#[derive(Clone,Debug)] pub struct IcalTime { time: ical::icaltimetype, } impl IcalTime { - pub fn now() -> Self { + pub fn utc() -> Self { dateutil::now().into() } + pub fn local() -> Self { + dateutil::now().with_timezone(&Local).into() + } + + pub fn from_ymd(year: i32, month: i32, day: i32) -> Self { + let utc = IcalTimeZone::utc(); + let time = ical::icaltimetype{ + year, month, day, + hour: 0, minute: 0, second: 0, + is_date: 1, + is_daylight: 0, + zone: *utc + }; + IcalTime{ time } + } + + pub fn from_ymdhms(year: i32, month: i32, day: i32, hour: i32, minute: i32, second: i32) -> Self { + let utc = IcalTimeZone::utc(); + let time = ical::icaltimetype{ + year, month, day, + hour, minute, second, + is_date: 0, + is_daylight: 0, + zone: *utc + }; + IcalTime{ time } + } + pub fn from_timestamp(timestamp: i64) -> Self { let _lock = TZ_MUTEX.lock(); let utc = IcalTimeZone::utc(); @@ -27,11 +56,15 @@ impl IcalTime { IcalTime{ time } } - pub fn get_timestamp(&self) -> i64 { + pub fn timestamp(&self) -> i64 { let _lock = TZ_MUTEX.lock(); unsafe { ical::icaltime_as_timet_with_zone(self.time, self.time.zone) } } + pub fn is_date(&self) -> bool { + self.time.is_date != 0 + } + pub fn as_date(&self) -> IcalTime { let mut time = self.time.clone(); time.is_date = 1; @@ -53,6 +86,20 @@ impl IcalTime { let result = IcalTime { time }; result } + + pub fn pred(&self) -> IcalTime { + let mut time = self.time; + time.day -= 1; + let time = unsafe { ical::icaltime_normalize(time) }; + IcalTime{ time } + } + + pub fn succ(&self) -> IcalTime { + let mut time = self.time; + time.day += 1; + let time = unsafe { ical::icaltime_normalize(time) }; + IcalTime{ time } + } } impl Deref for IcalTime { @@ -94,6 +141,16 @@ impl FromStr for IcalTime { } } +impl PartialEq<IcalTime> for IcalTime { + fn eq(&self, rhs: &IcalTime) -> bool { + let _lock = TZ_MUTEX.lock(); + let cmp = unsafe { ical::icaltime_compare(self.time, rhs.time) }; + cmp == 0 + } +} + +impl Eq for IcalTime {} + impl From<ical::icaltimetype> for IcalTime { fn from(time: ical::icaltimetype) -> IcalTime { IcalTime { time } @@ -136,6 +193,30 @@ impl From<Date<Utc>> for IcalTime { } } +impl From<IcalTime> for Date<Local> { + fn from(time: IcalTime) -> Date<Local> { + Local.timestamp(time.timestamp(), 0).date() + } +} + +impl From<IcalTime> for DateTime<Local> { + fn from(time: IcalTime) -> DateTime<Local> { + Local.timestamp(time.timestamp(), 0) + } +} + +impl From<IcalTime> for Date<Utc> { + fn from(time: IcalTime) -> Date<Utc> { + Utc.timestamp(time.timestamp(), 0).date() + } +} + +impl From<IcalTime> for DateTime<Utc> { + fn from(time: IcalTime) -> DateTime<Utc> { + Utc.timestamp(time.timestamp(), 0) + } +} + #[cfg(test)] mod tests { use super::*; @@ -144,10 +225,10 @@ mod tests { #[test] fn test_now() { - let now = IcalTime::now(); + let now = IcalTime::utc(); assert_eq!("20130101T010203Z", now.to_string()); - assert_eq!(1357002123, now.get_timestamp()); + assert_eq!(1357002123, now.timestamp()); } #[test] @@ -157,19 +238,19 @@ mod tests { let time = IcalTime::from(local_time); assert_eq!("Europe/Berlin", time.get_timezone().get_name()); - assert_eq!(1388534523, time.get_timestamp()); + assert_eq!(1388534523, time.timestamp()); } #[test] fn test_with_timezone_xxx() { - let utc = IcalTime::now(); + let utc = IcalTime::utc(); let tz = IcalTimeZone::from_name("US/Eastern").unwrap(); let time = utc.with_timezone(&tz); assert_eq!("US/Eastern", time.get_timezone().get_name()); assert_eq!("20121231T200203", time.to_string()); - assert_eq!(1357002123, time.get_timestamp()); + assert_eq!(1357002123, time.timestamp()); } #[test] diff --git a/src/icalwrap/icaltimezone.rs b/src/icalwrap/icaltimezone.rs index 5395a33..1354fa1 100644 --- a/src/icalwrap/icaltimezone.rs +++ b/src/icalwrap/icaltimezone.rs @@ -88,7 +88,7 @@ mod tests { fn test_get_offset_utc() { testdata::setup(); let tz = IcalTimeZone::utc(); - let time = IcalTime::now(); + let time = IcalTime::utc(); let offset = tz.get_offset_at_time(&time); @@ -98,7 +98,7 @@ mod tests { #[test] fn test_get_offset_local() { testdata::setup(); - let time = IcalTime::now(); + let time = IcalTime::utc(); let tz = IcalTimeZone::local(); let offset = tz.get_offset_at_time(&time); @@ -120,7 +120,7 @@ mod tests { #[test] fn test_get_offset_eastern() { - let time = IcalTime::now(); + let time = IcalTime::utc(); let tz = IcalTimeZone::from_name("US/Eastern").unwrap(); let offset = tz.get_offset_at_time(&time); diff --git a/src/icalwrap/icalvcalendar.rs b/src/icalwrap/icalvcalendar.rs index 774ee28..36eafc1 100644 --- a/src/icalwrap/icalvcalendar.rs +++ b/src/icalwrap/icalvcalendar.rs @@ -1,4 +1,3 @@ -use chrono::{DateTime, Local}; use std::ffi::{CStr, CString}; use std::path::{PathBuf,Path}; use std::rc::Rc; @@ -12,7 +11,7 @@ use ical; pub struct IcalVCalendar { comp: Rc<IcalComponentOwner>, path: Option<PathBuf>, - instance_timestamp: Option<DateTime<Local>>, + instance_timestamp: Option<IcalTime>, } pub struct IcalEventIter<'a> { @@ -31,13 +30,13 @@ impl IcalComponent for IcalVCalendar { } impl Clone for IcalVCalendar { - fn clone (&self) -> Self { + fn clone(&self) -> Self { let new_comp_ptr = unsafe { ical::icalcomponent_new_clone(self.comp.ptr) }; let mut new_calendar = IcalVCalendar::from_ptr(new_comp_ptr); new_calendar.path = self.path.clone(); - new_calendar.instance_timestamp = self.instance_timestamp; + new_calendar.instance_timestamp = self.instance_timestamp.clone(); new_calendar } } @@ -55,12 +54,12 @@ impl IcalVCalendar { IcalVCalendar { comp: self.comp.clone(), path: self.path.clone(), - instance_timestamp: self.instance_timestamp, + instance_timestamp: self.instance_timestamp.clone(), } } - pub fn with_internal_timestamp(mut self, datetime: DateTime<Local>) -> IcalVCalendar { - self.instance_timestamp = Some(datetime); + pub fn with_internal_timestamp(mut self, datetime: &IcalTime) -> IcalVCalendar { + self.instance_timestamp = Some(datetime.clone()); self } @@ -130,7 +129,7 @@ impl IcalVCalendar { } pub fn with_dtstamp_now(self) -> Self { - let dtstamp = IcalTime::now(); + let dtstamp = IcalTime::utc(); unsafe { ical::icalcomponent_set_dtstamp(self.get_ptr(), *dtstamp); } @@ -174,7 +173,7 @@ impl IcalVCalendar { pub fn with_last_modified_now(self) -> Self { let event = self.get_principal_event(); unsafe { - let now_icaltime = IcalTime::now(); + let now_icaltime = IcalTime::utc(); let last_modified_kind = ical::icalproperty_kind_ICAL_LASTMODIFIED_PROPERTY; if let Some(prop) = event.get_property(last_modified_kind) { @@ -256,7 +255,7 @@ impl IcalVCalendar { pub fn get_principal_event(&self) -> IcalVEvent { let mut event = self.get_first_event(); - if let Some(timestamp) = self.instance_timestamp { + if let Some(ref timestamp) = self.instance_timestamp { event = event.with_internal_timestamp(timestamp) } event @@ -369,7 +368,6 @@ impl Drop for IcalComponentOwner { mod tests { use super::*; use testdata; - use chrono::{Local, TimeZone}; #[test] fn test_from_str_empty() { @@ -509,8 +507,8 @@ mod tests { testdata::setup(); let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_MULTIDAY, None).unwrap(); - let timestamp = Local.ymd(2018, 1, 1).and_hms(11, 30, 20); - let new_cal = cal.with_dtend(×tamp.into()); + let timestamp = IcalTime::from_ymdhms(2018, 1, 1, 11, 30, 20); + let new_cal = cal.with_dtend(×tamp); let event = new_cal.get_principal_event(); assert_eq!(timestamp, event.get_dtend().unwrap()) @@ -521,8 +519,8 @@ mod tests { testdata::setup(); let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_MULTIDAY, None).unwrap(); - let timestamp = Local.ymd(2018, 1, 1).and_hms(11, 30, 20); - let new_cal = cal.with_dtstart(×tamp.into()); + let timestamp = IcalTime::from_ymdhms(2018, 1, 1, 11, 30, 20); + let new_cal = cal.with_dtstart(×tamp); let event = new_cal.get_principal_event(); assert_eq!(timestamp, event.get_dtstart().unwrap()) @@ -532,11 +530,11 @@ mod tests { fn test_with_internal_timestamp() { let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_MULTIDAY, None).unwrap(); - let timestamp = Local.ymd(2018, 1, 1).and_hms(11, 30, 20); - let new_cal = cal.with_internal_timestamp(timestamp); + let timestamp = IcalTime::from_ymdhms(2018, 1, 1, 11, 30, 20); + let new_cal = cal.with_internal_timestamp(×tamp); let event = new_cal.get_principal_event(); - assert_eq!(timestamp.with_timezone(&Local), event.get_dtstart().unwrap()); + assert_eq!(timestamp, event.get_dtstart().unwrap()); } #[test] 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()); } diff --git a/src/icalwrap/mod.rs b/src/icalwrap/mod.rs index ca0e0da..b8b6fb9 100644 --- a/src/icalwrap/mod.rs +++ b/src/icalwrap/mod.rs @@ -20,5 +20,5 @@ pub use self::icalvcalendar::IcalEventIter; pub use self::icalvevent::IcalVEvent; pub use self::icalproperty::IcalProperty; pub use self::icalcomponent::IcalComponent; -use self::icaltime::IcalTime; -use self::icaltimezone::IcalTimeZone; +pub use self::icaltime::IcalTime; +pub use self::icaltimezone::IcalTimeZone; diff --git a/src/khline.rs b/src/khline.rs index e2bf87c..24cd052 100644 --- a/src/khline.rs +++ b/src/khline.rs @@ -2,20 +2,19 @@ use std::fmt; use std::io; use std::path::{PathBuf,Path}; use std::str::FromStr; -use chrono::prelude::*; -use icalwrap::{IcalVCalendar,IcalVEvent}; +use icalwrap::{IcalVCalendar,IcalVEvent,IcalTime}; use utils::{fileutil,dateutil}; use defaults; #[derive(PartialEq,Eq)] pub struct KhLine { pub path: PathBuf, - time: Option<DateTime<Local>>, + time: Option<IcalTime>, } impl KhLine { - pub fn new(path: &Path, time: Option<DateTime<Local>>) -> Self { + pub fn new(path: &Path, time: Option<IcalTime>) -> Self { let path = if path.is_relative() { defaults::get_caldir().join(path) } else { @@ -33,7 +32,7 @@ impl KhLine { pub fn to_event(&self) -> io::Result<IcalVEvent> { let calendar = self.to_cal()?; let mut event = calendar.get_first_event(); - if let Some(time) = self.time { + if let Some(ref time) = self.time { event = event.with_internal_timestamp(time); } Ok(event) @@ -47,6 +46,10 @@ impl KhLine { &self.path } + pub fn get_time(&self) -> Option<&IcalTime> { + self.time.as_ref() + } + pub fn get_normalized_path(&self) -> &Path { self.path .strip_prefix(defaults::get_caldir()) @@ -73,7 +76,7 @@ impl fmt::Display for KhLine { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let path_string = self.get_normalized_path().to_string_lossy(); match self.time { - Some(time) => { + Some(ref time) => { let time_string = format!("{:010}", time.timestamp()); write!(f, "{} {}", time_string, path_string) } @@ -89,7 +92,7 @@ impl FromStr for KhLine { let parts: Vec<&str> = s.splitn(2, ' ').collect(); if let Some(time) = dateutil::datetime_from_timestamp(parts[0]) { let path = PathBuf::from(parts[1]); - Ok(Self::new(&path, Some(time))) + Ok(Self::new(&path, Some(time.into()))) } else { let path = PathBuf::from(parts[0]); Ok(Self::new(&path, None)) @@ -114,7 +117,7 @@ mod tests { let khline = khline_str.parse::<KhLine>().unwrap(); assert_eq!(PathBuf::from("/x/y/z.ics"), khline.path); - assert_eq!(1182988800, khline.time.unwrap().timestamp()); + assert_eq!(1182988800, khline.get_time().unwrap().timestamp()); assert_eq!(khline_str, khline.to_string()); } @@ -149,7 +152,7 @@ mod tests { let khline = khline_str.parse::<KhLine>().unwrap(); assert_eq!(testdir.child(".khaleesi/cal/x/y.ics").path(), khline.path); - assert_eq!(1182988800, khline.time.unwrap().timestamp()); + assert_eq!(1182988800, khline.get_time().unwrap().timestamp()); assert_eq!(khline_str, khline.to_string()); } @@ -209,8 +212,8 @@ mod tests { event.get_parent().unwrap().get_path().unwrap() ); assert_eq!( - Utc.ymd(2018, 12, 13).and_hms(22, 30, 00), - event.get_dtstart().unwrap().with_timezone(&Utc) + IcalTime::from_ymdhms(2018, 12, 13, 22, 30, 00), + event.get_dtstart().unwrap() ); } } diff --git a/src/selectors/mod.rs b/src/selectors/mod.rs index db003db..afadf82 100644 --- a/src/selectors/mod.rs +++ b/src/selectors/mod.rs @@ -90,13 +90,13 @@ impl SelectFilters { } fn line_is_from(&self, event: &IcalVEvent) -> bool { - let starts_after = self.from.includes_date(event.get_dtstart().unwrap()); - let ends_after = self.from.includes_date(event.get_dtend().unwrap()); + let starts_after = self.from.includes_date(event.get_dtstart().unwrap().into()); + let ends_after = self.from.includes_date(event.get_dtend().unwrap().into()); starts_after || ends_after } fn line_is_to(&self, event: &IcalVEvent) -> bool { - self.to.includes_date(event.get_dtstart().unwrap()) + self.to.includes_date(event.get_dtstart().unwrap().into()) } fn filter_index(&self, index: usize) -> bool { diff --git a/src/utils/dateutil.rs b/src/utils/dateutil.rs index c07b602..6dc9730 100644 --- a/src/utils/dateutil.rs +++ b/src/utils/dateutil.rs @@ -39,10 +39,10 @@ pub fn find_local_timezone() -> String { return candidate; } if let Ok(candidate) = fileutil::read_file_to_string(&PathBuf::from("/etc/timezone")) { - return candidate; + return candidate.trim().to_owned(); } if let Ok(candidate) = fileutil::read_file_to_string(&PathBuf::from("/etc/localtime")) { - return candidate; + return candidate.trim().to_owned(); } "UTC".to_owned() } |