summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Breitmoser <look@my.amazin.horse>2019-01-23 12:29:44 +0100
committerVincent Breitmoser <look@my.amazin.horse>2019-01-23 12:29:44 +0100
commit10e0eb12817b67b3d1765ee7ef7eebbecaa0d03e (patch)
tree3c25a26cc2cf01ae3e27514c85deda845c7882fc
parentfdcfacf7183dd5460ac265060f7c626e303e1a08 (diff)
use IcalTime instead of chrono times for most time operations
-rw-r--r--src/actions/agenda.rs20
-rw-r--r--src/actions/index/bucketable.rs4
-rw-r--r--src/actions/new.rs4
-rw-r--r--src/icalwrap/icaltime.rs97
-rw-r--r--src/icalwrap/icaltimezone.rs6
-rw-r--r--src/icalwrap/icalvcalendar.rs34
-rw-r--r--src/icalwrap/icalvevent.rs92
-rw-r--r--src/icalwrap/mod.rs4
-rw-r--r--src/khline.rs25
-rw-r--r--src/selectors/mod.rs6
-rw-r--r--src/utils/dateutil.rs4
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(&timestamp.into());
+ let timestamp = IcalTime::from_ymdhms(2018, 1, 1, 11, 30, 20);
+ let new_cal = cal.with_dtend(&timestamp);
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(&timestamp.into());
+ let timestamp = IcalTime::from_ymdhms(2018, 1, 1, 11, 30, 20);
+ let new_cal = cal.with_dtstart(&timestamp);
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(&timestamp);
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(&timestamp.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()
}