diff --git a/Cargo.lock b/Cargo.lock index c6f7088..9f1dc22 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3050,6 +3050,7 @@ dependencies = [ "quick-xml", "rustical_dav", "rustical_dav_push", + "rustical_ical", "rustical_store", "rustical_xml", "serde", @@ -3154,6 +3155,22 @@ dependencies = [ "uuid", ] +[[package]] +name = "rustical_ical" +version = "0.1.0" +dependencies = [ + "chrono", + "chrono-tz", + "derive_more 2.0.1", + "ical", + "lazy_static", + "regex", + "rustical_xml", + "strum", + "strum_macros", + "thiserror 2.0.12", +] + [[package]] name = "rustical_oidc" version = "0.1.0" @@ -3187,6 +3204,7 @@ dependencies = [ "rstest", "rstest_reuse", "rustical_dav", + "rustical_ical", "rustical_store_sqlite", "rustical_xml", "serde", @@ -3210,6 +3228,7 @@ dependencies = [ "password-hash", "pbkdf2", "rand 0.8.5", + "rustical_ical", "rustical_store", "serde", "sqlx", diff --git a/Cargo.toml b/Cargo.toml index a108e72..4d52f9b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -100,6 +100,7 @@ rustical_carddav = { path = "./crates/carddav/" } rustical_frontend = { path = "./crates/frontend/" } rustical_xml = { path = "./crates/xml/" } rustical_oidc = { path = "./crates/oidc/" } +rustical_ical = { path = "./crates/ical/" } chrono-tz = "0.10" chrono-humanize = "0.2" rand = "0.8" diff --git a/crates/caldav/Cargo.toml b/crates/caldav/Cargo.toml index ac4990f..366a60c 100644 --- a/crates/caldav/Cargo.toml +++ b/crates/caldav/Cargo.toml @@ -28,3 +28,4 @@ sha2 = { workspace = true } rustical_xml.workspace = true uuid.workspace = true rustical_dav_push.workspace = true +rustical_ical.workspace = true diff --git a/crates/caldav/src/calendar/methods/report/calendar_query.rs b/crates/caldav/src/calendar/methods/report/calendar_query.rs index 78f62fe..916a14e 100644 --- a/crates/caldav/src/calendar/methods/report/calendar_query.rs +++ b/crates/caldav/src/calendar/methods/report/calendar_query.rs @@ -3,9 +3,8 @@ use rustical_dav::{ resource::Resource, xml::{MultistatusElement, PropfindType}, }; -use rustical_store::{ - CalendarObject, CalendarStore, auth::User, calendar::UtcDateTime, calendar_store::CalendarQuery, -}; +use rustical_ical::UtcDateTime; +use rustical_store::{CalendarObject, CalendarStore, auth::User, calendar_store::CalendarQuery}; use rustical_xml::XmlDeserialize; use std::ops::Deref; diff --git a/crates/caldav/src/calendar/methods/report/mod.rs b/crates/caldav/src/calendar/methods/report/mod.rs index b9e2e8f..e7713da 100644 --- a/crates/caldav/src/calendar/methods/report/mod.rs +++ b/crates/caldav/src/calendar/methods/report/mod.rs @@ -142,7 +142,7 @@ mod tests { use super::*; use calendar_query::{CompFilterElement, FilterElement, TimeRangeElement}; use rustical_dav::xml::{PropElement, PropfindType, Propname}; - use rustical_store::calendar::UtcDateTime; + use rustical_ical::UtcDateTime; use rustical_xml::ValueDeserialize; #[test] diff --git a/crates/caldav/src/calendar/resource.rs b/crates/caldav/src/calendar/resource.rs index 4165593..473ab39 100644 --- a/crates/caldav/src/calendar/resource.rs +++ b/crates/caldav/src/calendar/resource.rs @@ -18,8 +18,8 @@ use rustical_dav::privileges::UserPrivilegeSet; use rustical_dav::resource::{Resource, ResourceService}; use rustical_dav::xml::{HrefElement, Resourcetype, ResourcetypeInner}; use rustical_dav_push::{DavPushExtension, DavPushExtensionProp}; +use rustical_ical::CalDateTime; use rustical_store::auth::User; -use rustical_store::calendar::CalDateTime; use rustical_store::{Calendar, CalendarStore, SubscriptionStore}; use rustical_xml::{EnumUnitVariants, EnumVariants}; use rustical_xml::{XmlDeserialize, XmlSerialize}; @@ -170,10 +170,10 @@ impl Resource for CalendarResource { self.cal.subscription_url.to_owned().map(HrefElement::from), ), CalendarPropName::MinDateTime => { - CalendarProp::MinDateTime(CalDateTime::Utc(DateTime::::MIN_UTC).format()) + CalendarProp::MinDateTime(CalDateTime::from(DateTime::::MIN_UTC).format()) } CalendarPropName::MaxDateTime => { - CalendarProp::MaxDateTime(CalDateTime::Utc(DateTime::::MAX_UTC).format()) + CalendarProp::MaxDateTime(CalDateTime::from(DateTime::::MAX_UTC).format()) } }), CalendarPropWrapperName::SyncToken(prop) => { diff --git a/crates/ical/Cargo.toml b/crates/ical/Cargo.toml new file mode 100644 index 0000000..e8d047d --- /dev/null +++ b/crates/ical/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "rustical_ical" +version.workspace = true +edition.workspace = true +description.workspace = true +repository.workspace = true + +[dependencies] +chrono.workspace = true +chrono-tz.workspace = true +thiserror.workspace = true +derive_more.workspace = true +rustical_xml.workspace = true +ical.workspace = true +lazy_static.workspace = true +regex.workspace = true +strum.workspace = true +strum_macros.workspace = true diff --git a/crates/ical/src/lib.rs b/crates/ical/src/lib.rs new file mode 100644 index 0000000..2591a14 --- /dev/null +++ b/crates/ical/src/lib.rs @@ -0,0 +1,9 @@ +pub mod rrule; + +mod property_ext; +pub use property_ext::*; + +mod timestamp; +mod timezone; +pub use timestamp::*; +pub use timezone::*; diff --git a/crates/store/src/calendar/ical.rs b/crates/ical/src/property_ext.rs similarity index 100% rename from crates/store/src/calendar/ical.rs rename to crates/ical/src/property_ext.rs diff --git a/crates/store/src/calendar/rrule/iter.rs b/crates/ical/src/rrule/iter.rs similarity index 52% rename from crates/store/src/calendar/rrule/iter.rs rename to crates/ical/src/rrule/iter.rs index c4495a0..af6cc39 100644 --- a/crates/store/src/calendar/rrule/iter.rs +++ b/crates/ical/src/rrule/iter.rs @@ -1,4 +1,4 @@ -use crate::calendar::CalDateTime; +use crate::CalDateTime; use super::{RecurrenceLimit, RecurrenceRule}; @@ -7,23 +7,26 @@ impl RecurrenceRule { &self, start: CalDateTime, end: Option, - ) -> impl IntoIterator { - let start = start.cal_utc(); + limit: Option, + ) -> Vec { + let start = start; // Terrible code, should clean this up later. - let mut end = end.map(|end| CalDateTime::cal_utc(&end)); + let mut end = end; if let Some(RecurrenceLimit::Until(until)) = &self.limit { - let until = until.cal_utc(); let mut _end = end.unwrap_or(until.clone()); if until.utc() < _end.utc() { - _end = until; + _end = until.clone(); } end = Some(_end); } - let count = if let Some(RecurrenceLimit::Count(count)) = &self.limit { + let mut count = if let Some(RecurrenceLimit::Count(count)) = &self.limit { *count } else { 2048 }; + if let Some(limit) = limit { + count = count.min(limit) + } let mut datetimes = vec![start.clone()]; let mut datetime_utc = start.utc(); @@ -32,10 +35,22 @@ impl RecurrenceRule { if datetime_utc > end.utc() { break; } - datetimes.push(CalDateTime::Utc(datetime_utc)); } + datetimes.push(datetime_utc.into()); } datetimes } } + +#[cfg(test)] +mod tests { + use crate::{CalDateTime, rrule::RecurrenceRule}; + + #[test] + fn test_between() { + let rrule = RecurrenceRule::parse("FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1").unwrap(); + let start = CalDateTime::parse("20250516T133000Z", None).unwrap(); + assert_eq!(rrule.between(start, None, Some(4)), vec![]); + } +} diff --git a/crates/store/src/calendar/rrule/mod.rs b/crates/ical/src/rrule/mod.rs similarity index 97% rename from crates/store/src/calendar/rrule/mod.rs rename to crates/ical/src/rrule/mod.rs index 33968e6..f025439 100644 --- a/crates/store/src/calendar/rrule/mod.rs +++ b/crates/ical/src/rrule/mod.rs @@ -55,7 +55,7 @@ pub struct RecurrenceRule { pub frequency: RecurrenceFrequency, pub limit: Option, // Repeat every n-th time - pub interval: Option, + pub interval: usize, pub bysecond: Option>, pub byminute: Option>, @@ -74,7 +74,7 @@ impl RecurrenceRule { pub fn parse(rule: &str) -> Result { let mut frequency = None; let mut limit = None; - let mut interval = None; + let mut interval = 1; let mut bysecond = None; let mut byminute = None; let mut byhour = None; @@ -98,7 +98,7 @@ impl RecurrenceRule { ("UNTIL", val) => { limit = Some(RecurrenceLimit::Until(CalDateTime::parse(val, None)?)) } - ("INTERVAL", val) => interval = Some(val.parse()?), + ("INTERVAL", val) => interval = val.parse()?, ("BYSECOND", val) => { bysecond = Some( val.split(',') @@ -196,7 +196,7 @@ impl RecurrenceRule { #[cfg(test)] mod tests { - use crate::calendar::{ + use crate::{ CalDateTime, rrule::{RecurrenceFrequency, RecurrenceLimit, Weekday}, }; @@ -212,7 +212,7 @@ mod tests { limit: Some(RecurrenceLimit::Until( CalDateTime::parse("20250516T133000Z", None).unwrap() )), - interval: Some(3), + interval: 3, ..Default::default() } ); @@ -221,7 +221,7 @@ mod tests { RecurrenceRule { frequency: RecurrenceFrequency::Weekly, limit: Some(RecurrenceLimit::Count(4)), - interval: Some(2), + interval: 2, byday: Some(vec![ (None, Weekday::Tu), (None, Weekday::Th), diff --git a/crates/store/src/calendar/timestamp.rs b/crates/ical/src/timestamp.rs similarity index 75% rename from crates/store/src/calendar/timestamp.rs rename to crates/ical/src/timestamp.rs index 57ea375..7be9aa0 100644 --- a/crates/store/src/calendar/timestamp.rs +++ b/crates/ical/src/timestamp.rs @@ -1,4 +1,6 @@ -use super::IcalProperty; +use crate::IcalProperty; + +use super::timezone::CalTimezone; use chrono::{DateTime, Duration, Local, NaiveDate, NaiveDateTime, NaiveTime, Utc}; use chrono_tz::Tz; use derive_more::derive::Deref; @@ -65,27 +67,35 @@ impl ValueSerialize for UtcDateTime { #[derive(Debug, Clone, PartialEq)] pub enum CalDateTime { - // Form 1, example: 19980118T230000 - Local(DateTime), - // Form 2, example: 19980119T070000Z - Utc(DateTime), - // Form 3, example: TZID=America/New_York:19980119T020000 + // Form 1, example: 19980118T230000 -> Local + // Form 2, example: 19980119T070000Z -> UTC + // Form 3, example: TZID=America/New_York:19980119T020000 -> Olson // https://en.wikipedia.org/wiki/Tz_database - OlsonTZ(DateTime), + DateTime(DateTime), Date(NaiveDate), } +impl From> for CalDateTime { + fn from(value: DateTime) -> Self { + CalDateTime::DateTime(value.with_timezone(&CalTimezone::Local)) + } +} + +impl From> for CalDateTime { + fn from(value: DateTime) -> Self { + CalDateTime::DateTime(value.with_timezone(&CalTimezone::Utc)) + } +} + impl Add for CalDateTime { type Output = Self; fn add(self, duration: Duration) -> Self::Output { match self { - Self::Local(datetime) => Self::Local(datetime + duration), - Self::Utc(datetime) => Self::Utc(datetime + duration), - Self::OlsonTZ(datetime) => Self::OlsonTZ(datetime + duration), - Self::Date(date) => Self::Local( + Self::DateTime(datetime) => Self::DateTime(datetime + duration), + Self::Date(date) => Self::DateTime( date.and_time(NaiveTime::default()) - .and_local_timezone(Local) + .and_local_timezone(CalTimezone::Local) .earliest() .expect("Local timezone has constant offset") + duration, @@ -142,42 +152,41 @@ impl CalDateTime { pub fn format(&self) -> String { match self { - Self::Utc(utc) => utc.format(UTC_DATE_TIME).to_string(), + Self::DateTime(datetime) => match datetime.timezone() { + CalTimezone::Utc => datetime.format(UTC_DATE_TIME).to_string(), + _ => datetime.format(LOCAL_DATE_TIME).to_string(), + }, Self::Date(date) => date.format(LOCAL_DATE).to_string(), - Self::Local(datetime) => datetime.format(LOCAL_DATE_TIME).to_string(), - Self::OlsonTZ(datetime) => datetime.format(LOCAL_DATE_TIME).to_string(), } } pub fn date(&self) -> NaiveDate { match self { - Self::Utc(utc) => utc.date_naive(), + Self::DateTime(datetime) => datetime.date_naive(), Self::Date(date) => date.to_owned(), - Self::Local(datetime) => datetime.date_naive(), - Self::OlsonTZ(datetime) => datetime.date_naive(), } } pub fn parse(value: &str, timezone: Option) -> Result { if let Ok(datetime) = NaiveDateTime::parse_from_str(value, LOCAL_DATE_TIME) { if let Some(timezone) = timezone { - return Ok(CalDateTime::OlsonTZ( + return Ok(CalDateTime::DateTime( datetime - .and_local_timezone(timezone) + .and_local_timezone(timezone.into()) .earliest() .ok_or(CalDateTimeError::LocalTimeGap)?, )); } - return Ok(CalDateTime::Local( + return Ok(CalDateTime::DateTime( datetime - .and_local_timezone(chrono::Local) + .and_local_timezone(CalTimezone::Local) .earliest() .ok_or(CalDateTimeError::LocalTimeGap)?, )); } if let Ok(datetime) = NaiveDateTime::parse_from_str(value, UTC_DATE_TIME) { - return Ok(CalDateTime::Utc(datetime.and_utc())); + return Ok(datetime.and_utc().into()); } if let Ok(date) = NaiveDate::parse_from_str(value, LOCAL_DATE) { return Ok(CalDateTime::Date(date)); @@ -207,16 +216,10 @@ impl CalDateTime { pub fn utc(&self) -> DateTime { match &self { - CalDateTime::Local(local_datetime) => local_datetime.to_utc(), - CalDateTime::Utc(utc_datetime) => utc_datetime.to_owned(), - CalDateTime::OlsonTZ(datetime) => datetime.to_utc(), + CalDateTime::DateTime(datetime) => datetime.to_utc(), CalDateTime::Date(date) => date.and_time(NaiveTime::default()).and_utc(), } } - - pub fn cal_utc(&self) -> Self { - Self::Utc(self.utc()) - } } impl From for DateTime { @@ -255,27 +258,33 @@ pub fn parse_duration(string: &str) -> Result { Ok(duration) } -#[test] -fn test_parse_duration() { - assert_eq!(parse_duration("P12W").unwrap(), Duration::weeks(12)); - assert_eq!(parse_duration("P12D").unwrap(), Duration::days(12)); - assert_eq!(parse_duration("PT12H").unwrap(), Duration::hours(12)); - assert_eq!(parse_duration("PT12M").unwrap(), Duration::minutes(12)); - assert_eq!(parse_duration("PT12S").unwrap(), Duration::seconds(12)); -} +#[cfg(test)] +mod tests { + use crate::{CalDateTime, parse_duration}; + use chrono::{Duration, NaiveDate}; -#[test] -fn test_vcard_date() { - assert_eq!( - CalDateTime::parse("19850412", None).unwrap(), - CalDateTime::Date(NaiveDate::from_ymd_opt(1985, 4, 12).unwrap()) - ); - assert_eq!( - CalDateTime::parse("1985-04-12", None).unwrap(), - CalDateTime::Date(NaiveDate::from_ymd_opt(1985, 4, 12).unwrap()) - ); - assert_eq!( - CalDateTime::parse("--0412", None).unwrap(), - CalDateTime::Date(NaiveDate::from_ymd_opt(1972, 4, 12).unwrap()) - ); + #[test] + fn test_parse_duration() { + assert_eq!(parse_duration("P12W").unwrap(), Duration::weeks(12)); + assert_eq!(parse_duration("P12D").unwrap(), Duration::days(12)); + assert_eq!(parse_duration("PT12H").unwrap(), Duration::hours(12)); + assert_eq!(parse_duration("PT12M").unwrap(), Duration::minutes(12)); + assert_eq!(parse_duration("PT12S").unwrap(), Duration::seconds(12)); + } + + #[test] + fn test_vcard_date() { + assert_eq!( + CalDateTime::parse("19850412", None).unwrap(), + CalDateTime::Date(NaiveDate::from_ymd_opt(1985, 4, 12).unwrap()) + ); + assert_eq!( + CalDateTime::parse("1985-04-12", None).unwrap(), + CalDateTime::Date(NaiveDate::from_ymd_opt(1985, 4, 12).unwrap()) + ); + assert_eq!( + CalDateTime::parse("--0412", None).unwrap(), + CalDateTime::Date(NaiveDate::from_ymd_opt(1972, 4, 12).unwrap()) + ); + } } diff --git a/crates/ical/src/timezone.rs b/crates/ical/src/timezone.rs new file mode 100644 index 0000000..ca9cec2 --- /dev/null +++ b/crates/ical/src/timezone.rs @@ -0,0 +1,86 @@ +use chrono::{Local, NaiveDate, NaiveDateTime, TimeZone, Utc}; +use chrono_tz::Tz; +use derive_more::{Display, From}; + +#[derive(Debug, Clone, From)] +pub enum CalTimezone { + Local, + Utc, + Olson(Tz), +} + +#[derive(Debug, Clone, PartialEq, Display)] +pub enum CalTimezoneOffset { + Local(chrono::FixedOffset), + Utc(chrono::Utc), + Olson(chrono_tz::TzOffset), +} + +impl chrono::Offset for CalTimezoneOffset { + fn fix(&self) -> chrono::FixedOffset { + match self { + Self::Local(local) => local.fix(), + Self::Utc(utc) => utc.fix(), + Self::Olson(olson) => olson.fix(), + } + } +} + +impl TimeZone for CalTimezone { + type Offset = CalTimezoneOffset; + + fn from_offset(offset: &Self::Offset) -> Self { + match offset { + CalTimezoneOffset::Local(_) => Self::Local, + CalTimezoneOffset::Utc(_) => Self::Utc, + CalTimezoneOffset::Olson(offset) => Self::Olson(Tz::from_offset(offset)), + } + } + + fn offset_from_local_date(&self, local: &NaiveDate) -> chrono::MappedLocalTime { + match self { + Self::Local => Local + .offset_from_local_date(local) + .map(CalTimezoneOffset::Local), + Self::Utc => Utc + .offset_from_local_date(local) + .map(CalTimezoneOffset::Utc), + Self::Olson(tz) => tz + .offset_from_local_date(local) + .map(CalTimezoneOffset::Olson), + } + } + + fn offset_from_local_datetime( + &self, + local: &NaiveDateTime, + ) -> chrono::MappedLocalTime { + match self { + Self::Local => Local + .offset_from_local_datetime(local) + .map(CalTimezoneOffset::Local), + Self::Utc => Utc + .offset_from_local_datetime(local) + .map(CalTimezoneOffset::Utc), + Self::Olson(tz) => tz + .offset_from_local_datetime(local) + .map(CalTimezoneOffset::Olson), + } + } + + fn offset_from_utc_datetime(&self, utc: &NaiveDateTime) -> Self::Offset { + match self { + Self::Local => CalTimezoneOffset::Local(Local.offset_from_utc_datetime(utc)), + Self::Utc => CalTimezoneOffset::Utc(Utc.offset_from_utc_datetime(utc)), + Self::Olson(tz) => CalTimezoneOffset::Olson(tz.offset_from_utc_datetime(utc)), + } + } + + fn offset_from_utc_date(&self, utc: &NaiveDate) -> Self::Offset { + match self { + Self::Local => CalTimezoneOffset::Local(Local.offset_from_utc_date(utc)), + Self::Utc => CalTimezoneOffset::Utc(Utc.offset_from_utc_date(utc)), + Self::Olson(tz) => CalTimezoneOffset::Olson(tz.offset_from_utc_date(utc)), + } + } +} diff --git a/crates/store/Cargo.toml b/crates/store/Cargo.toml index 05b663f..cb26605 100644 --- a/crates/store/Cargo.toml +++ b/crates/store/Cargo.toml @@ -30,6 +30,7 @@ clap.workspace = true rustical_dav.workspace = true strum.workspace = true strum_macros.workspace = true +rustical_ical.workspace = true [dev-dependencies] rstest = { workspace = true } diff --git a/crates/store/src/addressbook/address_object.rs b/crates/store/src/addressbook/address_object.rs index 7225a87..84881f0 100644 --- a/crates/store/src/addressbook/address_object.rs +++ b/crates/store/src/addressbook/address_object.rs @@ -1,15 +1,12 @@ -use std::{collections::HashMap, io::BufReader}; - -use crate::{ - calendar::{CalDateTime, LOCAL_DATE}, - CalendarObject, Error, -}; +use crate::{CalendarObject, Error}; use chrono::Datelike; use ical::parser::{ - vcard::{self, component::VcardContact}, Component, + vcard::{self, component::VcardContact}, }; +use rustical_ical::{CalDateTime, LOCAL_DATE}; use sha2::{Digest, Sha256}; +use std::{collections::HashMap, io::BufReader}; #[derive(Debug, Clone)] pub struct AddressObject { diff --git a/crates/store/src/calendar/event.rs b/crates/store/src/calendar/event.rs index 1523f64..2bbec76 100644 --- a/crates/store/src/calendar/event.rs +++ b/crates/store/src/calendar/event.rs @@ -1,14 +1,14 @@ -use super::{ - CalDateTime, parse_duration, - rrule::{ParserError, RecurrenceRule}, -}; -use crate::{Error, calendar::ComponentMut}; +use crate::Error; use chrono::Duration; use ical::{ generator::IcalEvent, parser::{Component, ical::component::IcalTimeZone}, property::Property, }; +use rustical_ical::{ + CalDateTime, ComponentMut, parse_duration, + rrule::{ParserError, RecurrenceRule}, +}; use std::collections::HashMap; #[derive(Debug, Clone)] @@ -71,10 +71,10 @@ impl EventObject { if let Some(rrule) = self.recurrence_rule()? { let mut events = vec![]; let first_occurence = self.get_first_occurence()?.unwrap(); - let dates = rrule.between(first_occurence, None); + let dates = rrule.between(first_occurence, None, None); for date in dates { - let dtstart_utc = date.cal_utc(); + let dtstart_utc = date; let mut ev = self.event.clone(); ev.remove_property("RRULE"); ev.set_property(Property { diff --git a/crates/store/src/calendar/mod.rs b/crates/store/src/calendar/mod.rs index 7c5c4e6..81c2d9a 100644 --- a/crates/store/src/calendar/mod.rs +++ b/crates/store/src/calendar/mod.rs @@ -1,16 +1,11 @@ mod calendar; mod event; -mod ical; mod journal; mod object; -pub mod rrule; -mod timestamp; mod todo; pub use calendar::*; pub use event::*; -pub use ical::*; pub use journal::*; pub use object::*; -pub use timestamp::*; pub use todo::*; diff --git a/crates/store/src/calendar/object.rs b/crates/store/src/calendar/object.rs index 1617feb..4fb7e5b 100644 --- a/crates/store/src/calendar/object.rs +++ b/crates/store/src/calendar/object.rs @@ -1,9 +1,10 @@ -use super::{CalDateTime, EventObject, JournalObject, TodoObject}; +use super::{EventObject, JournalObject, TodoObject}; use crate::Error; use ical::{ generator::{Emitter, IcalCalendar}, parser::{Component, ical::component::IcalTimeZone}, }; +use rustical_ical::CalDateTime; use serde::Serialize; use sha2::{Digest, Sha256}; use std::{collections::HashMap, io::BufReader}; diff --git a/crates/store/src/error.rs b/crates/store/src/error.rs index 4b741e9..947974b 100644 --- a/crates/store/src/error.rs +++ b/crates/store/src/error.rs @@ -1,6 +1,5 @@ use actix_web::{ResponseError, http::StatusCode}; - -use crate::calendar::CalDateTimeError; +use rustical_ical::CalDateTimeError; #[derive(Debug, thiserror::Error)] pub enum Error { @@ -14,7 +13,7 @@ pub enum Error { InvalidData(String), #[error(transparent)] - RRuleParserError(#[from] crate::calendar::rrule::ParserError), + RRuleParserError(#[from] rustical_ical::rrule::ParserError), #[error("Read-only")] ReadOnly, diff --git a/crates/store_sqlite/Cargo.toml b/crates/store_sqlite/Cargo.toml index c1afd17..542b65f 100644 --- a/crates/store_sqlite/Cargo.toml +++ b/crates/store_sqlite/Cargo.toml @@ -21,3 +21,4 @@ password-hash.workspace = true uuid.workspace = true rand.workspace = true pbkdf2.workspace = true +rustical_ical.workspace = true diff --git a/crates/store_sqlite/src/calendar_store.rs b/crates/store_sqlite/src/calendar_store.rs index 3ff4d60..a608b01 100644 --- a/crates/store_sqlite/src/calendar_store.rs +++ b/crates/store_sqlite/src/calendar_store.rs @@ -2,7 +2,8 @@ use super::ChangeOperation; use async_trait::async_trait; use chrono::TimeDelta; use derive_more::derive::Constructor; -use rustical_store::calendar::{CalDateTime, CalendarObjectType}; +use rustical_ical::CalDateTime; +use rustical_store::calendar::CalendarObjectType; use rustical_store::calendar_store::CalendarQuery; use rustical_store::synctoken::format_synctoken; use rustical_store::{Calendar, CalendarObject, CalendarStore, Error};