mirror of
https://github.com/lennart-k/rustical.git
synced 2026-01-30 16:28:21 +00:00
Compare commits
2 Commits
v0.12.1
...
6a31d3000c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a31d3000c | ||
|
|
d5892ab56b |
47
Cargo.lock
generated
47
Cargo.lock
generated
@@ -565,6 +565,23 @@ version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
|
||||
|
||||
[[package]]
|
||||
name = "caldata"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55ae67018b0b95d01f20a5f6869810e83969baa94b2ff768de7f90a8a9e38efd"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"chrono-tz",
|
||||
"derive_more",
|
||||
"itertools 0.14.0",
|
||||
"lazy_static",
|
||||
"phf 0.13.1",
|
||||
"regex",
|
||||
"rrule",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cast"
|
||||
version = "0.3.0"
|
||||
@@ -1768,22 +1785,6 @@ dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ical"
|
||||
version = "0.12.0-dev"
|
||||
source = "git+https://github.com/lennart-k/ical-rs?rev=f1ad6456fd6cbd1e6da095297febddd2cfe61422#f1ad6456fd6cbd1e6da095297febddd2cfe61422"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"chrono-tz",
|
||||
"derive_more",
|
||||
"itertools 0.14.0",
|
||||
"lazy_static",
|
||||
"phf 0.13.1",
|
||||
"regex",
|
||||
"rrule",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_collections"
|
||||
version = "2.1.1"
|
||||
@@ -3324,11 +3325,11 @@ dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
"axum-extra",
|
||||
"caldata",
|
||||
"clap",
|
||||
"figment",
|
||||
"headers",
|
||||
"http",
|
||||
"ical",
|
||||
"insta",
|
||||
"opentelemetry",
|
||||
"opentelemetry-otlp",
|
||||
@@ -3371,13 +3372,13 @@ dependencies = [
|
||||
"axum",
|
||||
"axum-extra",
|
||||
"base64 0.22.1",
|
||||
"caldata",
|
||||
"chrono",
|
||||
"chrono-tz",
|
||||
"derive_more",
|
||||
"futures-util",
|
||||
"headers",
|
||||
"http",
|
||||
"ical",
|
||||
"insta",
|
||||
"percent-encoding",
|
||||
"quick-xml",
|
||||
@@ -3412,11 +3413,11 @@ dependencies = [
|
||||
"axum",
|
||||
"axum-extra",
|
||||
"base64 0.22.1",
|
||||
"caldata",
|
||||
"chrono",
|
||||
"derive_more",
|
||||
"futures-util",
|
||||
"http",
|
||||
"ical",
|
||||
"insta",
|
||||
"percent-encoding",
|
||||
"quick-xml",
|
||||
@@ -3445,11 +3446,11 @@ dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
"axum-extra",
|
||||
"caldata",
|
||||
"derive_more",
|
||||
"futures-util",
|
||||
"headers",
|
||||
"http",
|
||||
"ical",
|
||||
"itertools 0.14.0",
|
||||
"log",
|
||||
"matchit 0.9.1",
|
||||
@@ -3530,10 +3531,10 @@ name = "rustical_ical"
|
||||
version = "0.12.1"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"caldata",
|
||||
"chrono",
|
||||
"chrono-tz",
|
||||
"derive_more",
|
||||
"ical",
|
||||
"regex",
|
||||
"rrule",
|
||||
"rstest",
|
||||
@@ -3567,6 +3568,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"axum",
|
||||
"caldata",
|
||||
"chrono",
|
||||
"chrono-tz",
|
||||
"clap",
|
||||
@@ -3574,7 +3576,6 @@ dependencies = [
|
||||
"futures-core",
|
||||
"headers",
|
||||
"http",
|
||||
"ical",
|
||||
"regex",
|
||||
"rrule",
|
||||
"rstest",
|
||||
@@ -3598,10 +3599,10 @@ name = "rustical_store_sqlite"
|
||||
version = "0.12.1"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"caldata",
|
||||
"chrono",
|
||||
"criterion",
|
||||
"derive_more",
|
||||
"ical",
|
||||
"password-auth",
|
||||
"password-hash",
|
||||
"pbkdf2",
|
||||
|
||||
@@ -107,9 +107,7 @@ strum = "0.27"
|
||||
strum_macros = "0.27"
|
||||
serde_json = { version = "1.0", features = ["raw_value"] }
|
||||
sqlx-sqlite = { version = "0.8", features = ["bundled"] }
|
||||
ical = { git = "https://github.com/lennart-k/ical-rs", rev = "f1ad6456fd6cbd1e6da095297febddd2cfe61422", features = [
|
||||
"chrono-tz",
|
||||
] }
|
||||
caldata = { version = "0.12.1", features = ["chrono-tz"] }
|
||||
toml = "0.9"
|
||||
tower = "0.5"
|
||||
tower-http = { version = "0.6", features = [
|
||||
@@ -139,7 +137,7 @@ reqwest = { version = "0.12", features = [
|
||||
openidconnect = "4.0"
|
||||
clap = { version = "4.5", features = ["derive", "env"] }
|
||||
matchit-serde = { git = "https://github.com/lennart-k/matchit-serde", rev = "e18e65d7" }
|
||||
vtimezones-rs = "0.2"
|
||||
vtimezones-rs = "0.3"
|
||||
ece = { version = "2.3", default-features = false, features = [
|
||||
"backend-openssl",
|
||||
] }
|
||||
@@ -161,7 +159,7 @@ rustical_store_sqlite.workspace = true
|
||||
rustical_caldav.workspace = true
|
||||
rustical_carddav.workspace = true
|
||||
rustical_frontend.workspace = true
|
||||
ical.workspace = true
|
||||
caldata.workspace = true
|
||||
toml.workspace = true
|
||||
serde.workspace = true
|
||||
tokio.workspace = true
|
||||
|
||||
@@ -34,7 +34,7 @@ rustical_store.workspace = true
|
||||
chrono.workspace = true
|
||||
chrono-tz.workspace = true
|
||||
sha2.workspace = true
|
||||
ical.workspace = true
|
||||
caldata.workspace = true
|
||||
percent-encoding.workspace = true
|
||||
rustical_xml.workspace = true
|
||||
uuid.workspace = true
|
||||
|
||||
@@ -3,11 +3,11 @@ use crate::calendar::CalendarResourceService;
|
||||
use axum::body::Body;
|
||||
use axum::extract::State;
|
||||
use axum::{extract::Path, response::Response};
|
||||
use caldata::component::IcalCalendar;
|
||||
use caldata::generator::Emitter;
|
||||
use caldata::parser::ContentLine;
|
||||
use headers::{ContentType, HeaderMapExt};
|
||||
use http::{HeaderValue, Method, StatusCode, header};
|
||||
use ical::component::IcalCalendar;
|
||||
use ical::generator::Emitter;
|
||||
use ical::property::ContentLine;
|
||||
use percent_encoding::{CONTROLS, utf8_percent_encode};
|
||||
use rustical_store::{CalendarStore, SubscriptionStore, auth::Principal};
|
||||
use std::str::FromStr;
|
||||
|
||||
@@ -4,8 +4,9 @@ use axum::{
|
||||
extract::{Path, State},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use caldata::IcalParser;
|
||||
use caldata::component::{Component, ComponentMut};
|
||||
use http::StatusCode;
|
||||
use ical::parser::{Component, ComponentMut};
|
||||
use rustical_dav::header::Overwrite;
|
||||
use rustical_ical::CalendarObjectType;
|
||||
use rustical_store::{
|
||||
@@ -25,7 +26,7 @@ pub async fn route_import<C: CalendarStore, S: SubscriptionStore>(
|
||||
return Err(Error::Unauthorized);
|
||||
}
|
||||
|
||||
let parser = ical::IcalParser::from_slice(body.as_bytes());
|
||||
let parser = IcalParser::from_slice(body.as_bytes());
|
||||
let mut cal = match parser.expect_one() {
|
||||
Ok(cal) => cal.mutable(),
|
||||
Err(err) => return Ok((StatusCode::BAD_REQUEST, err.to_string()).into_response()),
|
||||
|
||||
@@ -6,8 +6,8 @@ use crate::calendar::prop::SupportedCalendarComponentSet;
|
||||
use crate::error::Precondition;
|
||||
use axum::extract::{Path, State};
|
||||
use axum::response::{IntoResponse, Response};
|
||||
use caldata::IcalParser;
|
||||
use http::{Method, StatusCode};
|
||||
use ical::IcalParser;
|
||||
use rustical_dav::xml::HrefElement;
|
||||
use rustical_ical::CalendarObjectType;
|
||||
use rustical_store::auth::Principal;
|
||||
|
||||
@@ -2,9 +2,12 @@ use crate::calendar::methods::report::calendar_query::{
|
||||
TimeRangeElement,
|
||||
prop_filter::{PropFilterElement, PropFilterable},
|
||||
};
|
||||
use ical::{
|
||||
component::{CalendarInnerData, IcalAlarm, IcalCalendarObject, IcalEvent, IcalTodo},
|
||||
parser::{Component, ical::component::IcalTimeZone},
|
||||
use caldata::{
|
||||
component::{
|
||||
CalendarInnerData, Component, IcalAlarm, IcalCalendarObject, IcalEvent, IcalTimeZone,
|
||||
IcalTodo,
|
||||
},
|
||||
parser::ContentLine,
|
||||
};
|
||||
use rustical_xml::XmlDeserialize;
|
||||
|
||||
@@ -112,10 +115,7 @@ impl CompFilterable for CalendarInnerData {
|
||||
}
|
||||
|
||||
impl PropFilterable for IcalAlarm {
|
||||
fn get_named_properties<'a>(
|
||||
&'a self,
|
||||
name: &'a str,
|
||||
) -> impl Iterator<Item = &'a ical::property::ContentLine> {
|
||||
fn get_named_properties<'a>(&'a self, name: &'a str) -> impl Iterator<Item = &'a ContentLine> {
|
||||
Component::get_named_properties(self, name)
|
||||
}
|
||||
}
|
||||
@@ -139,7 +139,7 @@ impl PropFilterable for CalendarInnerData {
|
||||
fn get_named_properties<'a>(
|
||||
&'a self,
|
||||
name: &'a str,
|
||||
) -> Box<dyn Iterator<Item = &'a ical::property::ContentLine> + 'a> {
|
||||
) -> Box<dyn Iterator<Item = &'a ContentLine> + 'a> {
|
||||
// TODO: If we were pedantic, we would have to do recurrence expansion first
|
||||
// and take into account the overrides :(
|
||||
match self {
|
||||
@@ -151,10 +151,7 @@ impl PropFilterable for CalendarInnerData {
|
||||
}
|
||||
|
||||
impl PropFilterable for IcalCalendarObject {
|
||||
fn get_named_properties<'a>(
|
||||
&'a self,
|
||||
name: &'a str,
|
||||
) -> impl Iterator<Item = &'a ical::property::ContentLine> {
|
||||
fn get_named_properties<'a>(&'a self, name: &'a str) -> impl Iterator<Item = &'a ContentLine> {
|
||||
Component::get_named_properties(self, name)
|
||||
}
|
||||
}
|
||||
@@ -185,10 +182,7 @@ impl CompFilterable for IcalCalendarObject {
|
||||
}
|
||||
|
||||
impl PropFilterable for IcalTimeZone {
|
||||
fn get_named_properties<'a>(
|
||||
&'a self,
|
||||
name: &'a str,
|
||||
) -> impl Iterator<Item = &'a ical::property::ContentLine> {
|
||||
fn get_named_properties<'a>(&'a self, name: &'a str) -> impl Iterator<Item = &'a ContentLine> {
|
||||
Component::get_named_properties(self, name)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::comp_filter::{CompFilterElement, CompFilterable};
|
||||
use crate::calendar_object::CalendarObjectPropWrapperName;
|
||||
use ical::{component::IcalCalendarObject, property::ContentLine};
|
||||
use caldata::{component::IcalCalendarObject, parser::ContentLine};
|
||||
use rustical_dav::xml::{PropfindType, TextMatchElement};
|
||||
use rustical_ical::UtcDateTime;
|
||||
use rustical_store::calendar_store::CalendarQuery;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::{ParamFilterElement, TimeRangeElement};
|
||||
use ical::{property::ContentLine, types::CalDateTime};
|
||||
use caldata::{parser::ContentLine, types::CalDateTime};
|
||||
use rustical_dav::xml::TextMatchElement;
|
||||
use rustical_ical::UtcDateTime;
|
||||
use rustical_xml::XmlDeserialize;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use super::prop::{SupportedCalendarComponentSet, SupportedCalendarData};
|
||||
use crate::Error;
|
||||
use crate::calendar::prop::{ReportMethod, SupportedCollationSet};
|
||||
use caldata::IcalParser;
|
||||
use caldata::types::CalDateTime;
|
||||
use chrono::{DateTime, Utc};
|
||||
use derive_more::derive::{From, Into};
|
||||
use ical::IcalParser;
|
||||
use ical::types::CalDateTime;
|
||||
use rustical_dav::extensions::{
|
||||
CommonPropertiesExtension, CommonPropertiesProp, SyncTokenExtension, SyncTokenExtensionProp,
|
||||
};
|
||||
|
||||
@@ -3,8 +3,8 @@ use super::prop::{
|
||||
CalendarObjectPropWrapperName,
|
||||
};
|
||||
use crate::Error;
|
||||
use caldata::generator::Emitter;
|
||||
use derive_more::derive::{From, Into};
|
||||
use ical::generator::Emitter;
|
||||
use rustical_dav::{
|
||||
extensions::CommonPropertiesExtension,
|
||||
privileges::UserPrivilegeSet,
|
||||
|
||||
@@ -32,7 +32,7 @@ rustical_ical.workspace = true
|
||||
http.workspace = true
|
||||
tower-http.workspace = true
|
||||
percent-encoding.workspace = true
|
||||
ical.workspace = true
|
||||
caldata.workspace = true
|
||||
strum.workspace = true
|
||||
strum_macros.workspace = true
|
||||
rstest.workspace = true
|
||||
|
||||
@@ -7,8 +7,8 @@ use crate::{
|
||||
AddressObjectPropWrapperName,
|
||||
},
|
||||
};
|
||||
use caldata::property::VcardFNProperty;
|
||||
use derive_more::derive::{From, Into};
|
||||
use ical::parser::VcardFNProperty;
|
||||
use rustical_dav::{
|
||||
extensions::CommonPropertiesExtension,
|
||||
privileges::UserPrivilegeSet,
|
||||
|
||||
@@ -4,11 +4,12 @@ use axum::{
|
||||
extract::{Path, State},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use http::StatusCode;
|
||||
use ical::{
|
||||
parser::{Component, ComponentMut, vcard},
|
||||
property::ContentLine,
|
||||
use caldata::{
|
||||
VcardParser,
|
||||
component::{Component, ComponentMut},
|
||||
parser::ContentLine,
|
||||
};
|
||||
use http::StatusCode;
|
||||
use rustical_store::{Addressbook, AddressbookStore, SubscriptionStore, auth::Principal};
|
||||
use tracing::instrument;
|
||||
|
||||
@@ -23,7 +24,7 @@ pub async fn route_import<AS: AddressbookStore, S: SubscriptionStore>(
|
||||
return Err(Error::Unauthorized);
|
||||
}
|
||||
|
||||
let parser = vcard::VcardParser::from_slice(body.as_bytes());
|
||||
let parser = VcardParser::from_slice(body.as_bytes());
|
||||
|
||||
let mut objects = vec![];
|
||||
for res in parser {
|
||||
|
||||
@@ -2,8 +2,8 @@ use crate::{
|
||||
address_object::AddressObjectPropWrapperName,
|
||||
addressbook::methods::report::addressbook_query::PropFilterElement,
|
||||
};
|
||||
use caldata::parser::ContentLine;
|
||||
use derive_more::{From, Into};
|
||||
use ical::property::ContentLine;
|
||||
use rustical_dav::xml::{PropfindType, TextMatchElement};
|
||||
use rustical_ical::{AddressObject, UtcDateTime};
|
||||
use rustical_xml::{ValueDeserialize, XmlDeserialize, XmlRootTag};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::{Allof, ParamFilterElement};
|
||||
use ical::{parser::Component, property::ContentLine};
|
||||
use caldata::{component::Component, parser::ContentLine};
|
||||
use rustical_dav::xml::TextMatchElement;
|
||||
use rustical_ical::AddressObject;
|
||||
use rustical_xml::XmlDeserialize;
|
||||
|
||||
@@ -28,7 +28,7 @@ headers.workspace = true
|
||||
strum.workspace = true
|
||||
matchit.workspace = true
|
||||
matchit-serde.workspace = true
|
||||
ical = { workspace = true, optional = true }
|
||||
caldata = { workspace = true, optional = true }
|
||||
|
||||
[features]
|
||||
ical = ["dep:ical"]
|
||||
ical = ["dep:caldata"]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use ical::property::ContentLine;
|
||||
use caldata::parser::ContentLine;
|
||||
use rustical_xml::{ValueDeserialize, XmlDeserialize};
|
||||
use std::borrow::Cow;
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ chrono-tz.workspace = true
|
||||
thiserror.workspace = true
|
||||
derive_more.workspace = true
|
||||
rustical_xml.workspace = true
|
||||
ical.workspace = true
|
||||
caldata.workspace = true
|
||||
regex.workspace = true
|
||||
rrule.workspace = true
|
||||
serde.workspace = true
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
use crate::{CalendarObject, Error};
|
||||
use caldata::{
|
||||
VcardParser,
|
||||
component::{
|
||||
CalendarInnerDataBuilder, ComponentMut, IcalAlarmBuilder, IcalCalendarObjectBuilder,
|
||||
IcalEventBuilder, VcardContact,
|
||||
},
|
||||
generator::Emitter,
|
||||
parser::ContentLine,
|
||||
property::{
|
||||
Calscale, IcalCALSCALEProperty, IcalDTENDProperty, IcalDTSTAMPProperty,
|
||||
IcalDTSTARTProperty, IcalPRODIDProperty, IcalRRULEProperty, IcalSUMMARYProperty,
|
||||
IcalUIDProperty, IcalVERSIONProperty, IcalVersion, VcardANNIVERSARYProperty,
|
||||
VcardBDAYProperty, VcardFNProperty,
|
||||
},
|
||||
types::{CalDate, PartialDate, Timezone},
|
||||
};
|
||||
use chrono::{NaiveDate, Utc};
|
||||
use ical::component::{
|
||||
CalendarInnerDataBuilder, IcalAlarmBuilder, IcalCalendarObjectBuilder, IcalEventBuilder,
|
||||
};
|
||||
use ical::generator::Emitter;
|
||||
use ical::parser::vcard::{self, component::VcardContact};
|
||||
use ical::parser::{
|
||||
Calscale, ComponentMut, IcalCALSCALEProperty, IcalDTENDProperty, IcalDTSTAMPProperty,
|
||||
IcalDTSTARTProperty, IcalPRODIDProperty, IcalRRULEProperty, IcalSUMMARYProperty,
|
||||
IcalUIDProperty, IcalVERSIONProperty, IcalVersion, VcardANNIVERSARYProperty, VcardBDAYProperty,
|
||||
VcardFNProperty,
|
||||
};
|
||||
use ical::property::ContentLine;
|
||||
use ical::types::{CalDate, PartialDate};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::collections::HashMap;
|
||||
use std::str::FromStr;
|
||||
@@ -32,7 +35,7 @@ impl From<VcardContact> for AddressObject {
|
||||
|
||||
impl AddressObject {
|
||||
pub fn from_vcf(vcf: String) -> Result<Self, Error> {
|
||||
let parser = vcard::VcardParser::from_slice(vcf.as_bytes());
|
||||
let parser = VcardParser::from_slice(vcf.as_bytes());
|
||||
let vcard = parser.expect_one()?;
|
||||
Ok(Self { vcf, vcard })
|
||||
}
|
||||
@@ -70,7 +73,7 @@ impl AddressObject {
|
||||
let Some(dtstart) = NaiveDate::from_ymd_opt(year.unwrap_or(1900), month, day) else {
|
||||
return Ok(None);
|
||||
};
|
||||
let start_date = CalDate(dtstart, ical::types::Timezone::Local);
|
||||
let start_date = CalDate(dtstart, Timezone::Local);
|
||||
let Some(end_date) = start_date.succ_opt() else {
|
||||
// start_date is MAX_DATE, this should never happen but FAPP also not raise an error
|
||||
return Ok(None);
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use crate::Error;
|
||||
use caldata::{
|
||||
IcalObjectParser,
|
||||
component::{CalendarInnerData, IcalCalendarObject},
|
||||
generator::Emitter,
|
||||
};
|
||||
use derive_more::Display;
|
||||
use ical::IcalObjectParser;
|
||||
use ical::component::CalendarInnerData;
|
||||
use ical::component::IcalCalendarObject;
|
||||
use ical::generator::Emitter;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
|
||||
#![allow(clippy::missing_errors_doc, clippy::missing_panics_doc)]
|
||||
mod timestamp;
|
||||
use ical::parser::ParserError;
|
||||
use caldata::parser::ParserError;
|
||||
pub use timestamp::*;
|
||||
|
||||
mod calendar_object;
|
||||
|
||||
@@ -13,7 +13,7 @@ anyhow.workspace = true
|
||||
async-trait.workspace = true
|
||||
serde.workspace = true
|
||||
sha2.workspace = true
|
||||
ical.workspace = true
|
||||
caldata.workspace = true
|
||||
chrono.workspace = true
|
||||
regex.workspace = true
|
||||
thiserror.workspace = true
|
||||
|
||||
@@ -26,7 +26,7 @@ pub enum Error {
|
||||
Other(#[from] anyhow::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
IcalError(#[from] ical::parser::ParserError),
|
||||
IcalError(#[from] caldata::parser::ParserError),
|
||||
}
|
||||
|
||||
impl Error {
|
||||
|
||||
@@ -20,7 +20,7 @@ rstest.workspace = true
|
||||
criterion.workspace = true
|
||||
|
||||
[dependencies]
|
||||
ical.workspace = true
|
||||
caldata.workspace = true
|
||||
tokio.workspace = true
|
||||
rustical_store.workspace = true
|
||||
async-trait.workspace = true
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use super::ChangeOperation;
|
||||
use crate::BEGIN_IMMEDIATE;
|
||||
use async_trait::async_trait;
|
||||
use caldata::parser::ParserError;
|
||||
use derive_more::derive::Constructor;
|
||||
use ical::parser::ParserError;
|
||||
use rustical_ical::AddressObject;
|
||||
use rustical_store::{
|
||||
Addressbook, AddressbookStore, CollectionMetadata, CollectionOperation,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use super::ChangeOperation;
|
||||
use crate::BEGIN_IMMEDIATE;
|
||||
use async_trait::async_trait;
|
||||
use caldata::parser::ParserError;
|
||||
use caldata::types::CalDateTime;
|
||||
use chrono::TimeDelta;
|
||||
use derive_more::derive::Constructor;
|
||||
use ical::parser::ParserError;
|
||||
use ical::types::CalDateTime;
|
||||
use regex::Regex;
|
||||
use rustical_ical::{CalendarObject, CalendarObjectType};
|
||||
use rustical_store::calendar_store::CalendarQuery;
|
||||
|
||||
Reference in New Issue
Block a user