summaryrefslogtreecommitdiffstats
path: root/src/icalwrap
diff options
context:
space:
mode:
Diffstat (limited to 'src/icalwrap')
-rw-r--r--src/icalwrap/icalcomponent.rs131
-rw-r--r--src/icalwrap/icalduration.rs177
-rw-r--r--src/icalwrap/icalproperty.rs60
-rw-r--r--src/icalwrap/icaltime.rs365
-rw-r--r--src/icalwrap/icaltimezone.rs153
-rw-r--r--src/icalwrap/icalvcalendar.rs670
-rw-r--r--src/icalwrap/icalvevent.rs394
-rw-r--r--src/icalwrap/mod.rs26
8 files changed, 0 insertions, 1976 deletions
diff --git a/src/icalwrap/icalcomponent.rs b/src/icalwrap/icalcomponent.rs
deleted file mode 100644
index 4da7eba..0000000
--- a/src/icalwrap/icalcomponent.rs
+++ /dev/null
@@ -1,131 +0,0 @@
-use std::ffi::CString;
-
-use super::IcalProperty;
-use crate::ical;
-
-pub trait IcalComponent {
- fn get_ptr(&self) -> *mut ical::icalcomponent;
- fn as_component(&self) -> &dyn IcalComponent;
-
- fn get_property(&self, property_kind: ical::icalproperty_kind) -> Option<IcalProperty<'_>> {
- let property = unsafe {
- ical::icalcomponent_get_first_property(self.get_ptr(), property_kind)
- };
- if !property.is_null() {
- Some(IcalProperty::from_ptr(property, self.as_component()))
- } else {
- None
- }
- }
-
- fn get_properties(self: &Self, property_kind: ical::icalproperty_kind) -> Vec<IcalProperty<'_>> {
- let mut properties = Vec::new();
- unsafe {
- let mut property_ptr = ical::icalcomponent_get_first_property(self.get_ptr(), property_kind);
- while !property_ptr.is_null() {
- let property = IcalProperty::from_ptr(property_ptr, self.as_component());
- properties.push(property);
- property_ptr = ical::icalcomponent_get_next_property(self.get_ptr(), property_kind);
- }
- }
- properties
- }
-
- fn get_properties_all(&self) -> Vec<IcalProperty<'_>> {
- self.get_properties(ical::icalproperty_kind_ICAL_ANY_PROPERTY)
- }
-
- fn get_properties_by_name(&self, property_name: &str) -> Vec<IcalProperty> {
- let property_kind = unsafe {
- let c_str = CString::new(property_name).unwrap();
- ical::icalproperty_string_to_kind(c_str.as_ptr())
- };
- self.get_properties(property_kind)
- }
-
- fn get_property_by_name(&self, property_name: &str) -> Option<IcalProperty> {
- let property_kind = unsafe {
- let c_str = CString::new(property_name).unwrap();
- ical::icalproperty_string_to_kind(c_str.as_ptr())
- };
- self.get_property(property_kind)
- }
-
- unsafe fn remove_property_all(&self, kind: ical::icalproperty_kind) -> usize {
-
- unsafe fn remove_property_inner(comp: *mut ical::icalcomponent, kind: ical::icalproperty_kind) -> usize {
- let mut count = 0;
- let mut prop = ical::icalcomponent_get_first_property(comp, kind);
- while !prop.is_null() {
- ical::icalcomponent_remove_property(comp, prop);
- count += 1;
- prop = ical::icalcomponent_get_current_property(comp);
- }
- let mut inner_comp = ical::icalcomponent_get_first_component(comp, ical::icalcomponent_kind_ICAL_ANY_COMPONENT);
- while !inner_comp.is_null() {
- count += remove_property_inner(inner_comp, kind);
- inner_comp = ical::icalcomponent_get_next_component(comp, ical::icalcomponent_kind_ICAL_ANY_COMPONENT)
- }
- count
- }
-
- let comp = self.get_ptr();
- remove_property_inner(comp, kind)
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::testdata;
- use crate::icalwrap::IcalVCalendar;
-
- #[test]
- fn get_property_test() {
- let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_MULTIDAY, None).unwrap();
- let event = cal.get_principal_event();
- let prop_name = "SUMMARY";
- let prop_value: String = event.get_property_by_name(prop_name).unwrap().get_value();
-
- assert_eq!("Festival International de Jazz de Montreal".to_string(), prop_value);
- }
-
- #[test]
- fn get_property_test_lastmodified() {
- let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_MULTIDAY_LASTMODIFIED, None).unwrap();
- let event = cal.get_principal_event();
- let prop_name = "LAST-MODIFIED";
- let prop_value: String = event.get_property_by_name(prop_name).unwrap().get_value();
-
- assert_eq!("20070423T123432Z".to_string(), prop_value);
- }
-
- #[test]
- fn get_property_test_cal() {
- let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_MULTIDAY, None).unwrap();
- let prop_name = "PRODID";
- let prop_value: String = cal.get_property_by_name(prop_name).unwrap().get_value();
-
- assert_eq!("-//ABC Corporation//NONSGML My Product//EN".to_string(), prop_value);
- }
-
- #[test]
- fn get_property_test_negative() {
- let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_MULTIDAY, None).unwrap();
- let event = cal.get_principal_event();
- let prop_name = "DESCRIPTION";
- let prop = event.get_property_by_name(prop_name);
-
- assert!(prop.is_none());
- }
-
- #[test]
- fn get_property_by_name_test() {
- let cal = IcalVCalendar::from_str(testdata::TEST_EVENT_MULTIDAY, None).unwrap();
- let event = cal.get_principal_event();
- let prop_name = "NONSENSE";
- let prop = event.get_property_by_name(prop_name);
-
- assert!(prop.is_none());
- }
-}
diff --git a/src/icalwrap/icalduration.rs b/src/icalwrap/icalduration.rs
deleted file mode 100644
index 7ad1d13..0000000
--- a/src/icalwrap/icalduration.rs
+++ /dev/null
@@ -1,177 +0,0 @@
-use std::ops::{Deref,Add};
-use std::ffi::{CStr,CString};
-use crate::ical;
-use std::fmt::{Error,Display,Formatter};
-use std::str::FromStr;
-use std::cmp::Ordering;
-
-
-#[derive(Clone,Debug)]
-pub struct IcalDuration {
- duration: ical::icaldurationtype,
-}
-
-impl IcalDuration {
- pub fn from_seconds(seconds: i32) -> IcalDuration {
- let duration = unsafe { ical::icaldurationtype_from_int(seconds) };
- IcalDuration{ duration }
- }
-
- pub fn to_seconds(&self) -> i32 {
- unsafe { ical::icaldurationtype_as_int(self.duration) }
- }
-}
-
-impl Deref for IcalDuration {
- type Target = ical::icaldurationtype;
-
- fn deref(&self) -> &ical::icaldurationtype {
- &self.duration
- }
-}
-
-impl Display for IcalDuration {
- fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
- let cstr = unsafe {
- CStr::from_ptr(ical::icaldurationtype_as_ical_string(self.duration))
- };
- let string = cstr.to_string_lossy();
- write!(f, "{}", string)
- }
-}
-
-impl FromStr for IcalDuration {
- type Err = String;
-
- fn from_str(s: &str) -> Result<Self, Self::Err> {
- let c_str = CString::new(s).unwrap();
- let duration = unsafe {
- let duration = ical::icaldurationtype_from_string(c_str.as_ptr());
- if ical::icaldurationtype_is_null_duration(duration) == 0 {
- Some(duration)
- } else {
- None
- }
- };
- if let Some(duration) = duration {
- Ok(IcalDuration { duration })
- } else {
- return Err(format!("Could not parse duration {}", s));
- }
- }
-}
-
-impl PartialEq<IcalDuration> for IcalDuration {
- fn eq(&self, rhs: &IcalDuration) -> bool {
- self.to_seconds() == rhs.to_seconds()
- }
-}
-
-impl Eq for IcalDuration {}
-
-impl PartialOrd for IcalDuration {
- fn partial_cmp(&self, rhs: &IcalDuration) -> Option<Ordering> {
- Some(self.cmp(rhs))
- }
-}
-
-impl Ord for IcalDuration {
- fn cmp(&self, rhs: &IcalDuration) -> Ordering {
- let left = self.to_seconds();
- let right = rhs.to_seconds();
- if left == right {
- Ordering::Equal
- } else if left < right {
- Ordering::Less
- } else {
- Ordering::Greater
- }
- }
-}
-
-impl From<ical::icaldurationtype> for IcalDuration {
- fn from(duration: ical::icaldurationtype) -> IcalDuration {
- IcalDuration { duration }
- }
-}
-
-impl From<IcalDuration> for chrono::Duration {
- fn from(duration: IcalDuration) -> chrono::Duration {
- chrono::Duration::seconds(i64::from(duration.to_seconds()))
- }
-}
-
-impl From<chrono::Duration> for IcalDuration {
- fn from(duration: chrono::Duration) -> IcalDuration {
- IcalDuration::from_seconds(duration.num_seconds() as i32)
- }
-}
-impl Add for IcalDuration {
- type Output = IcalDuration;
-
- fn add(self, other: IcalDuration) -> IcalDuration {
- let seconds = self.to_seconds() + other.to_seconds();
- IcalDuration::from_seconds(seconds)
- }
-}
-
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn test_parse() {
- let duration = "PT86400S".parse::<IcalDuration>().unwrap();
- assert_eq!(IcalDuration::from_seconds(24*60*60), duration);
- assert_eq!(86400, duration.to_seconds());
- }
-
- #[test]
- fn test_parse_fail() {
- let duration = "swag".parse::<IcalDuration>();
- assert!(duration.is_err());
- }
-
- #[test]
- fn test_display() {
- let duration = IcalDuration::from_seconds(5*24*60*60 + 22*60*60 + 33*60 + 33);
- assert_eq!("P5DT22H33M33S", duration.to_string());
- }
-
- #[test]
- fn test_to_chrono() {
- let from_duration = IcalDuration::from_seconds(5*24*60*60 + 22*60*60 + 33*60 + 33);
- let duration: chrono::Duration = from_duration.into();
- assert_eq!(chrono::Duration::seconds(5*24*60*60 + 22*60*60 + 33*60 + 33), duration);
- }
-
- #[test]
- fn test_from_chrono() {
- let from_duration = chrono::Duration::seconds(5*24*60*60 + 22*60*60 + 33*60 + 33);
- let duration: IcalDuration = from_duration.into();
- assert_eq!(IcalDuration::from_seconds(5*24*60*60 + 22*60*60 + 33*60 + 33), duration);
- }
-
- #[test]
- fn test_add() {
- let fst = IcalDuration::from_seconds(123);
- let snd = IcalDuration::from_seconds(4567);
-
- let sum = fst + snd;
-
- assert_eq!(IcalDuration::from_seconds(123+4567), sum);
- }
-
- #[test]
- fn test_cmp() {
- let more = IcalDuration::from_seconds(49128);
- let less = IcalDuration::from_seconds(5);
-
- assert!(less == less);
- assert!(more == more);
- assert!(less < more);
- assert!(!(more < less));
- assert!(!(more == less));
- }
-}
diff --git a/src/icalwrap/icalproperty.rs b/src/icalwrap/icalproperty.rs
deleted file mode 100644
index ad903c1..0000000
--- a/src/icalwrap/icalproperty.rs
+++ /dev/null
@@ -1,60 +0,0 @@
-use chrono::NaiveDate;
-use std::ffi::CStr;
-use std::fmt;
-
-use super::icalcomponent::IcalComponent;
-use crate::ical;
-
-pub struct IcalProperty<'a> {
- pub ptr: *mut ical::icalproperty,
- _parent: &'a dyn IcalComponent,
-}
-
-impl<'a> Drop for IcalProperty<'a> {
- fn drop(&mut self) {
- unsafe {
- ical::icalproperty_free(self.ptr);
- }
- }
-}
-
-impl<'a> fmt::Debug for IcalProperty<'a> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}", self.as_ical_string())
- }
-}
-
-impl<'a> IcalProperty<'a> {
- pub fn from_ptr(ptr: *mut ical::icalproperty, parent: &'a dyn IcalComponent) -> Self {
- IcalProperty { ptr, _parent: parent }
- }
-
- pub fn get_name(&self) -> String {
- unsafe {
- let cstr = CStr::from_ptr(ical::icalproperty_get_property_name(self.ptr));
- cstr.to_string_lossy().into_owned()
- }
- }
-
- pub fn get_value(&self) -> String {
- unsafe {
- let cstr = CStr::from_ptr(ical::icalproperty_get_value_as_string(self.ptr));
- cstr.to_string_lossy().into_owned()
- }
- }
-
- pub fn as_ical_string(&self) -> String {
- unsafe {
- let cstr = CStr::from_ptr(ical::icalproperty_as_ical_string(self.ptr));
- cstr.to_string_lossy().trim().to_owned()
- }
- }
-
- pub fn get_value_as_date(&self) -> Option<NaiveDate> {
- unsafe {
- let date = ical::icaltime_from_string(ical::icalproperty_get_value_as_string(self.ptr));
- NaiveDate::from_ymd_opt(date.year, date.month as u32, date.day as u32)
- }
- }
-}
-
diff --git a/src/icalwrap/icaltime.rs b/src/icalwrap/icaltime.rs
deleted file mode 100644
index 18a2b80..0000000
--- a/src/icalwrap/icaltime.rs
+++ /dev/null
@@ -1,365 +0,0 @@
-use std::ops::{Add,Deref};
-use std::ffi::{CStr,CString};
-use chrono::{Date,DateTime,TimeZone,Utc,Local};
-use crate::ical;
-use crate::utils::dateutil;
-use super::IcalTimeZone;
-use super::IcalDuration;
-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 utc() -> Self {
- dateutil::now().into()
- }
-
- pub fn local() -> Self {
- dateutil::now().with_timezone(&Local).into()
- }
-
- pub fn floating_ymd(year: i32, month: i32, day: i32) -> Self {
- let time = ical::icaltimetype{
- year, month, day,
- hour: 0, minute: 0, second: 0,
- is_date: 1,
- is_daylight: 0,
- zone: ::std::ptr::null(),
- };
- IcalTime{ time }
- }
-
- pub fn and_hms(&self, hour: i32, minute: i32, second: i32) -> Self {
- let mut time = self.time;
- time.hour = hour;
- time.minute = minute;
- time.second = second;
- time.is_date = 0;
-
- IcalTime{ time }
- }
-
- pub fn from_timestamp(timestamp: i64) -> Self {
- let _lock = TZ_MUTEX.lock();
- let utc = IcalTimeZone::utc();
- let is_date = 0;
- let time = unsafe {
- ical::icaltime_from_timet_with_zone(timestamp, is_date, *utc)
- };
- IcalTime{ time }
- }
-
- 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;
- time.is_date = 1;
- IcalTime{ time }
- }
-
- pub fn get_timezone(&self) -> Option<IcalTimeZone> {
- if self.time.zone.is_null() {
- return None;
- }
- let tz_ptr = unsafe {
- ical::icaltime_get_timezone(self.time)
- };
- Some(IcalTimeZone::from_ptr_copy(tz_ptr))
- }
-
- pub fn with_timezone(&self, timezone: &IcalTimeZone) -> IcalTime {
- let _lock = TZ_MUTEX.lock();
- let mut time = unsafe {
- ical::icaltime_convert_to_zone(self.time, **timezone)
- };
- //icaltime_convert_to_zone does nothing if is_date == 1
- time.zone = **timezone;
- IcalTime { time }
- }
-
- 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 {
- type Target = ical::icaltimetype;
-
- fn deref(&self) -> &ical::icaltimetype {
- &self.time
- }
-}
-
-impl Display for IcalTime {
- fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
- let cstr = unsafe {
- CStr::from_ptr(ical::icaltime_as_ical_string(self.time))
- };
- let string = cstr.to_string_lossy();
- write!(f, "{}", string)
- }
-}
-
-impl FromStr for IcalTime {
- type Err = String;
-
- fn from_str(s: &str) -> Result<Self, Self::Err> {
- unsafe {
- let c_str = CString::new(s).unwrap();
- let time = ical::icaltime_from_string(c_str.as_ptr());
- if ical::icaltime_is_null_time(time) == 0 {
- Ok(IcalTime { time })
- } else {
- Err(format!("Could not parse time {}", s))
- }
- }
- }
-}
-
-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 }
- }
-}
-
-impl Add<IcalDuration> for IcalTime {
- type Output = IcalTime;
-
- fn add(self, other: IcalDuration) -> IcalTime {
- let time = unsafe { ical::icaltime_add(self.time, *other) };
- IcalTime { time }
- }
-}
-
-impl<T: Into<IcalTime> + Clone> From<&T> for IcalTime {
- fn from(time: &T) -> IcalTime {
- time.clone().into()
- }
-}
-
-impl From<DateTime<Local>> for IcalTime {
- fn from(time: DateTime<Local>) -> IcalTime {
- let timestamp = time.timestamp();
- let local = IcalTimeZone::local();
- IcalTime::from_timestamp(timestamp).with_timezone(&local)
- }
-}
-
-impl From<DateTime<Utc>> for IcalTime {
- fn from(time: DateTime<Utc>) -> IcalTime {
- let timestamp = time.timestamp();
- IcalTime::from_timestamp(timestamp)
- }
-}
-
-impl From<Date<Local>> for IcalTime {
- fn from(date: Date<Local>) -> IcalTime {
- let timestamp = date.with_timezone(&Utc).and_hms(0, 0, 0).timestamp();
- let timezone = IcalTimeZone::local();
- IcalTime::from_timestamp(timestamp).with_timezone(&timezone).as_date()
- }
-}
-
-impl From<Date<Utc>> for IcalTime {
- fn from(date: Date<Utc>) -> IcalTime {
- let timestamp = date.and_hms(0, 0, 0).timestamp();
- IcalTime::from_timestamp(timestamp).as_date()
- }
-}
-
-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::*;
-
- use crate::testdata;
-
- #[test]
- fn test_now() {
- let now = IcalTime::utc();
-
- assert_eq!("20130101T010203Z", now.to_string());
- assert_eq!(1357002123, now.timestamp());
- }
-
- #[test]
- fn test_from_local() {
- testdata::setup();
- let local_time = Local.ymd(2014, 01, 01).and_hms(01, 02, 03);
- let time = IcalTime::from(local_time);
-
- assert_eq!("Europe/Berlin", time.get_timezone().unwrap().get_name());
- assert_eq!(1388534523, time.timestamp());
- }
-
- #[test]
- fn test_local() {
- testdata::setup();
- let time = IcalTime::local();
- assert_eq!("20130101T020203", time.to_string());
- }
-
- #[test]
- fn test_parse() {
- let time = "20130101T010203Z".parse::<IcalTime>().unwrap();
- assert_eq!("20130101T010203Z", time.to_string());
- }
-
- #[test]
- fn test_parse_negative() {
- let time = "201XXX01T010203Z".parse::<IcalTime>();
- assert!(time.is_err());
- }
-
- #[test]
- fn test_with_timezone() {
- 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().unwrap().get_name());
- assert_eq!("20121231T200203", time.to_string());
- assert_eq!(1357002123, time.timestamp());
- }
-
- #[test]
- fn test_get_timezone_negative() {
- let time = IcalTime::floating_ymd(2018, 02, 03);
- assert!(time.get_timezone().is_none());
- }
-
- #[test]
- fn test_from_local_date() {
- testdata::setup();
- let local_date = Local.ymd(2014, 01, 01);
- let time = IcalTime::from(local_date);
-
- assert_eq!("Europe/Berlin", time.get_timezone().unwrap().get_name());
- assert_eq!("20140101", time.to_string());
- }
-
- #[test]
- fn test_from_utc_date() {
- let utc_date = Utc.ymd(2014, 01, 01);
- let time = IcalTime::from(utc_date);
-
- assert_eq!("UTC", time.get_timezone().unwrap().get_name());
- assert_eq!("20140101", time.to_string());
- }
-
- #[test]
- fn test_into_utc_date() {
- let time = IcalTimeZone::utc().ymd(2014, 02, 02);
- let date: Date<Utc> = time.into();
- assert_eq!(Utc.ymd(2014, 02, 02), date);
- }
-
- #[test]
- fn test_into_utc_datetime() {
- let time = IcalTimeZone::utc().ymd(2014, 02, 02).and_hms(13, 37, 00);
- let datetime: DateTime<Utc> = time.into();
- assert_eq!(Utc.ymd(2014, 02, 02).and_hms(13, 37, 00), datetime);
- }
-
- #[test]
- fn test_into_local_date() {
- testdata::setup();
- let time = IcalTimeZone::local().ymd(2014, 02, 02);
- let date: Date<Local> = time.into();
- assert_eq!(Local.ymd(2014, 02, 02), date);
- }
-
- #[test]
- fn test_into_local_datetime() {
- testdata::setup();
- let time = IcalTimeZone::local().ymd(2014, 02, 02).and_hms(13, 37, 00);
- let datetime: DateTime<Local> = time.into();
- assert_eq!(Local.ymd(2014, 02, 02).and_hms(13, 37, 00), datetime);
- }
-
- #[test]
- fn test_into_local_datetime_utc() {
- testdata::setup();
- let time = IcalTimeZone::utc().ymd(2014, 02, 02).and_hms(13, 37, 00);
- let datetime: DateTime<Local> = time.into();
- assert_eq!(Local.ymd(2014, 02, 02).and_hms(14, 37, 00), datetime);
- }
-
- #[test]
- fn test_add() {
- let now = IcalTime::utc();
- let duration = IcalDuration::from_seconds(123);
-
- let sum = now + duration;
-
- assert_eq!(1357002123 + 123, sum.timestamp());
- }
-
- #[test]
- fn test_pred() {
- let time = IcalTime::utc();
- assert_eq!("20121231T010203Z", time.pred().to_string());
- }
-
- #[test]
- fn test_succ() {
- let time = IcalTime::utc();
- assert_eq!("20130102T010203Z", time.succ().to_string());
- }
-}
diff --git a/src/icalwrap/icaltimezone.rs b/src/icalwrap/icaltimezone.rs
deleted file mode 100644
index 90fe4cf..0000000
--- a/src/icalwrap/icaltimezone.rs
+++ /dev/null
@@ -1,153 +0,0 @@
-use std::ops::Deref;
-use std::ffi::{CString,CStr};
-use crate::ical;
-
-use crate::utils::dateutil;
-use super::IcalTime;
-
-pub struct IcalTimeZone {
- timezone: *mut ical::icaltimezone,
-}
-
-impl Deref for IcalTimeZone {
- type Target = *mut ical::icaltimezone;
-
- fn deref(&self) -> &*mut ical::icaltimezone {
- &self.timezone
- }
-}
-
-
-impl IcalTimeZone {
- pub fn from_ptr_copy(ptr: *const ical::icaltimezone) -> Self {
- let timezone = unsafe {
- // unsafe, but we know icaltimezone_copy doesn't actually mutate
- ical::icaltimezone_copy(ptr as *mut ical::icaltimezone)
- };
- IcalTimeZone{ timezone }
- }
-
- pub fn from_name(tz_name: &str) -> Result<Self,String> {
- let tz_cstr = CString::new(tz_name).unwrap();
- let builtin = unsafe { ical::icaltimezone_get_builtin_timezone(tz_cstr.as_ptr()) };
- if !builtin.is_null() {
- // need to copy here to guarantee we don't touch the builtin zones
- let timezone = unsafe { ical::icaltimezone_copy(builtin) };
- Ok(IcalTimeZone{ timezone })
- } else {
- Err(format!("Unknown timezone: {}", tz_name))
- }
- }
-
- pub fn local() -> Self {
- let tz_name = dateutil::find_local_timezone();
- IcalTimeZone::from_name(&tz_name).unwrap()
- }
-
- pub fn utc() -> Self {
- let timezone = unsafe { ical::icaltimezone_get_utc_timezone() };
- IcalTimeZone{ timezone }
- }
-
- pub fn get_name(&self) -> String {
- unsafe {
- let name = ical::icaltimezone_get_display_name(self.timezone);
- CStr::from_ptr(name).to_string_lossy().trim().to_string()
- }
- }
-
- pub fn get_offset_at_time(&self, time: &IcalTime) -> i32 {
- let mut icaltime = **time;
- let mut is_dst = 0;
- unsafe {
- ical::icaltimezone_get_utc_offset(self.timezone, &mut icaltime , &mut is_dst)
- }
- }
-
- pub fn ymd(&self, year: i32, month: i32, day: i32) -> IcalTime {
- IcalTime::floating_ymd(year, month, day).with_timezone(&self)
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- use crate::testdata;
-
- #[test]
- fn test_utc() {
- let tz = IcalTimeZone::utc();
- assert_eq!("UTC", tz.get_name());
- }
-
- #[test]
- fn test_local() {
- testdata::setup();
- let tz = IcalTimeZone::local();
- assert_eq!("Europe/Berlin", tz.get_name());
- }
-
- #[test]
- fn test_get_offset_utc() {
- testdata::setup();
- let tz = IcalTimeZone::utc();
- let time = IcalTime::utc();
-
- let offset = tz.get_offset_at_time(&time);
-
- assert_eq!(0, offset);
- }
-
- #[test]
- fn test_get_offset_local() {
- testdata::setup();
- let time = IcalTime::utc();
- let tz = IcalTimeZone::local();
-
- let offset = tz.get_offset_at_time(&time);
-
- assert_eq!(60*60, offset);
- }
-
- #[test]
- fn test_ymd() {
- let tz = IcalTimeZone::from_name("US/Eastern").unwrap();
- let date = tz.ymd(2014,3,1);
- assert_eq!(IcalTime::floating_ymd(2014,3,1), date);
- assert_eq!(1393650000, date.timestamp());
- assert_eq!("US/Eastern", date.get_timezone().unwrap().get_name());
- }
-
- #[test]
- fn test_ymd_and_hms() {
- let tz = IcalTimeZone::from_name("US/Eastern").unwrap();
- let date = tz.ymd(2014,3,1).and_hms(17, 20, 0);
- assert_eq!(IcalTime::floating_ymd(2014,3,1).and_hms(17, 20, 0), date);
- assert_eq!(1393712400, date.timestamp());
- assert_eq!("US/Eastern", date.get_timezone().unwrap().get_name());
- }
-
- #[test]
- fn test_from_name() {
- let tz = IcalTimeZone::from_name("US/Eastern").unwrap();
- assert_eq!("US/Eastern", tz.get_name());
- }
-
- #[test]
- fn test_from_name_fail() {
- let tz = IcalTimeZone::from_name("lulz");
- assert!(tz.is_err());
- }
-
- #[test]
- fn test_get_offset_eastern() {
- let time = IcalTime::utc();
- let tz = IcalTimeZone::from_name("US/Eastern").unwrap();
-
- let offset = tz.get_offset_at_time(&time);
-
- assert_eq!(-5*60*60, offset);
- }
-
-}
diff --git a/src/icalwrap/icalvcalendar.rs b/src/icalwrap/icalvcalendar.rs
deleted file mode 100644
index ced299a..0000000
--- a/src/icalwrap/icalvcalendar.rs
+++ /dev/null
@@ -1,670 +0,0 @@
-use std::ffi::{CStr, CString};
-use std::io;
-use std::path::{Path, PathBuf};
-use std::rc::Rc;
-
-use super::IcalComponent;
-use super::IcalTime;
-use super::IcalVEvent;
-use crate::ical;
-use crate::khevent::KhEvent;
-
-pub struct IcalVCalendar {
- comp: Rc<IcalComponentOwner>,
- path: Option<PathBuf>,
- instance_timestamp: Option<IcalTime>,
-}
-
-pub struct IcalEventIter<'a> {
- iter: ical::icalcompiter,
- parent: &'a IcalVCalendar,
-}
-
-impl IcalComponent for IcalVCalendar {
- fn get_ptr(&self) -> *mut ical::icalcomponent {
- self.comp.ptr
- }
-
- fn as_component(&self) -> &dyn IcalComponent {
- self
- }
-}
-
-impl Clone for IcalVCalendar {
- 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.clone();
- new_calendar
- }
-}
-
-impl IcalVCalendar {
- fn from_ptr(ptr: *mut ical::icalcomponent) -> Self {
- IcalVCalendar {
- comp: Rc::new(IcalComponentOwner { ptr }),
- path: None,
- instance_timestamp: None,
- }
- }
-
- pub fn shallow_copy(&self) -> Self {
- IcalVCalendar {
- comp: self.comp.clone(),
- path: self.path.clone(),
- instance_timestamp: self.instance_timestamp.clone(),
- }
- }
-
- //pub fn with_internal_timestamp(mut self, datetime: &IcalTime) -> IcalVCalendar {
- //self.instance_timestamp = Some(datetime.clone());
- //self
- //}
-
- pub fn with_path(mut self, path: &Path) -> IcalVCalendar {
- self.path = Some(path.to_path_buf());
- self
- }
-
- //TODO should probably be private
- pub fn from_str(str: &str, path: Option<&Path>) -> io::Result<Self> {
- unsafe {
- let c_str = CString::new(str).unwrap();
- let parsed_cal = ical::icalparser_parse_string(c_str.as_ptr());
- if parsed_cal.is_null() {
- return Err(io::Error::new(io::ErrorKind::Other, "calendar has no path"));
- }
-
- let kind = ical::icalcomponent_isa(parsed_cal);
- if kind != ical::icalcomponent_kind_ICAL_VCALENDAR_COMPONENT {
- let kind = CStr::from_ptr(ical::icalcomponent_kind_to_string(kind)).to_string_lossy();
- return Err(io::Error::new(
- io::ErrorKind::Other,
- format!("expected VCALENDAR component, got {}", kind),
- ));
- }
-
- let mut cal = IcalVCalendar::from_ptr(parsed_cal);
- cal.path = path.map(|path| path.to_path_buf());
-
- Ok(cal)
- }
- }
-
- pub fn with_normalize(self) -> Self {
- unsafe {
- ical::icalcomponent_normalize(self.get_ptr());
- }
- self
- }
-
- pub fn to_string(&self) -> String {
- unsafe {
- let ical_cstr = CStr::from_ptr(ical::icalcomponent_as_ical_string(self.get_ptr()));
- ical_cstr.to_string_lossy().into_owned()
- }
- }
-
- pub fn get_uid(&self) -> String {
- unsafe {
- let uid_cstr = CStr::from_ptr(ical::icalcomponent_get_uid(
- self.get_principal_event().get_ptr(),
- ));
- uid_cstr.to_string_lossy().into_owned()
- }
- }
-
- pub fn with_uid(mut self, uid: &str) -> Result<Self, String> {
- {
- let events = self.events_iter();
- if events.unique_uid_count() > 1 {
- return Err(format!(
- "More than one event in file: {}",
- self.get_path_as_string().unwrap_or_else(|| "".to_string())
- ));
- }
- let events = self.events_iter();
- let uid_cstr = CString::new(uid).unwrap();
- for event in events {
- unsafe {
- ical::icalcomponent_set_uid(event.get_ptr(), uid_cstr.as_ptr());
- }
- }
- }
- self.path = self
- .path
- .map(|path| path.with_file_name(uid.to_owned() + ".ics"));
- Ok(self)
- }
-
- pub fn with_dtstamp_now(self) -> Self {
- let dtstamp = IcalTime::utc();
- unsafe {
- ical::icalcomponent_set_dtstamp(self.get_ptr(), *dtstamp);
- }
- self
- }
-
- pub fn with_dtstart(self, dtstart: &IcalTime) -> Self {
- let event = self.get_principal_event();
- unsafe {
- let timezone = event.get_dtstart().and_then(|x| x.get_timezone());
- match timezone {
- Some(timezone) => {
- ical::icalcomponent_set_dtstart(event.get_ptr(), *dtstart.with_timezone(&timezone));
- }
- None => {
- ical::icalcomponent_set_dtstart(event.get_ptr(), **dtstart);
- }
- }
- }
- self
- }
-
- pub fn with_dtend(self, dtend: &IcalTime) -> Self {
- let event = self.get_principal_event();
- unsafe {
- let timezone = event.get_dtend().and_then(|x| x.get_timezone());
- match timezone {
- Some(timezone) => {
- ical::icalcomponent_set_dtend(event.get_ptr(), *dtend.with_timezone(&timezone));
- }
- None => {
- ical::icalcomponent_set_dtend(event.get_ptr(), **dtend);
- }
- }
- }
- self
- }
-
- pub fn with_location(self, location: &str) -> Self {
- let event = self.get_principal_event();
- unsafe {
- let c_str = CString::new(location).unwrap();
- ical::icalcomponent_set_location(event.get_ptr(), c_str.as_ptr());
- }
- self
- }
-
- pub fn with_summary(self, summary: &str) -> Self {
- let event = self.get_principal_event();
- unsafe {
- let c_str = CString::new(summary).unwrap();
- ical::icalcomponent_set_summary(event.get_ptr(), c_str.as_ptr());
- }
- self
- }
-
- pub fn with_last_modified_now(self) -> Self {
- let event = self.get_principal_event();
- unsafe {
- let now_icaltime = IcalTime::utc();
-
- let last_modified_kind = ic