clean up ical-related stuff

This commit is contained in:
Lennart K
2026-01-08 14:31:28 +01:00
parent 7a1ec3e351
commit f4de80c6b9
5 changed files with 23 additions and 179 deletions

32
Cargo.lock generated
View File

@@ -1494,7 +1494,7 @@ dependencies = [
"futures-core",
"futures-sink",
"http",
"indexmap 2.12.1",
"indexmap 2.13.0",
"slab",
"tokio",
"tokio-util",
@@ -1771,7 +1771,7 @@ dependencies = [
[[package]]
name = "ical"
version = "0.11.0"
source = "git+https://github.com/lennart-k/ical-rs?branch=dev#5525818e2fca0fc99cbe0b0c0fb260d0d790f43f"
source = "git+https://github.com/lennart-k/ical-rs?branch=dev#0a50f3998b8ae104642cceb9d974e99b78838b14"
dependencies = [
"chrono",
"chrono-tz",
@@ -1905,9 +1905,9 @@ dependencies = [
[[package]]
name = "indexmap"
version = "2.12.1"
version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2"
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
dependencies = [
"equivalent",
"hashbrown 0.16.1",
@@ -2019,9 +2019,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.179"
version = "0.2.180"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5a2d376baa530d1238d133232d15e239abad80d05838b4b59354e5268af431f"
checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
[[package]]
name = "libm"
@@ -3856,7 +3856,7 @@ dependencies = [
"chrono",
"hex",
"indexmap 1.9.3",
"indexmap 2.12.1",
"indexmap 2.13.0",
"schemars 0.9.0",
"schemars 1.2.0",
"serde_core",
@@ -4036,7 +4036,7 @@ dependencies = [
"futures-util",
"hashbrown 0.15.5",
"hashlink",
"indexmap 2.12.1",
"indexmap 2.13.0",
"log",
"memchr",
"once_cell",
@@ -4498,7 +4498,7 @@ version = "0.9.10+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0825052159284a1a8b4d6c0c86cbc801f2da5afd2b225fa548c72f2e74002f48"
dependencies = [
"indexmap 2.12.1",
"indexmap 2.13.0",
"serde_core",
"serde_spanned 1.0.4",
"toml_datetime 0.7.5+spec-1.1.0",
@@ -4531,7 +4531,7 @@ version = "0.22.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
dependencies = [
"indexmap 2.12.1",
"indexmap 2.13.0",
"serde",
"serde_spanned 0.6.9",
"toml_datetime 0.6.11",
@@ -4545,7 +4545,7 @@ version = "0.23.10+spec-1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269"
dependencies = [
"indexmap 2.12.1",
"indexmap 2.13.0",
"toml_datetime 0.7.5+spec-1.1.0",
"toml_parser",
"winnow",
@@ -4617,7 +4617,7 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
dependencies = [
"futures-core",
"futures-util",
"indexmap 2.12.1",
"indexmap 2.13.0",
"pin-project-lite",
"slab",
"sync_wrapper",
@@ -5482,18 +5482,18 @@ dependencies = [
[[package]]
name = "zerocopy"
version = "0.8.32"
version = "0.8.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fabae64378cb18147bb18bca364e63bdbe72a0ffe4adf0addfec8aa166b2c56"
checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.32"
version = "0.8.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9c2d862265a8bb4471d87e033e730f536e2a285cc7cb05dbce09a2a97075f90"
checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1"
dependencies = [
"proc-macro2",
"quote",

View File

@@ -70,7 +70,8 @@ impl Resource for AddressObjectResource {
}
fn get_displayname(&self) -> Option<&str> {
self.object.get_full_name()
todo!()
// self.object.get_full_name()
}
fn get_owner(&self) -> Option<&str> {

View File

@@ -1,9 +1,6 @@
use crate::{CalendarObject, Error};
use ical::generator::Emitter;
use ical::parser::{
Component,
vcard::{self, component::VcardContact},
};
use ical::parser::vcard::{self, component::VcardContact};
use sha2::{Digest, Sha256};
use std::{collections::HashMap, io::BufReader};
@@ -22,13 +19,8 @@ impl From<VcardContact> for AddressObject {
impl AddressObject {
pub fn from_vcf(vcf: String) -> Result<Self, Error> {
let mut parser = vcard::VcardParser::new(BufReader::new(vcf.as_bytes()));
let vcard = parser.next().ok_or(Error::MissingContact)??;
if parser.next().is_some() {
return Err(Error::InvalidData(
"multiple vcards, only one allowed".to_owned(),
));
}
let parser = vcard::VcardParser::new(BufReader::new(vcf.as_bytes()));
let vcard = parser.expect_one()?;
Ok(Self { vcf, vcard })
}
@@ -44,12 +36,6 @@ impl AddressObject {
&self.vcf
}
#[must_use]
pub fn get_full_name(&self) -> Option<&str> {
let prop = self.vcard.get_property("FN")?;
prop.value.as_deref()
}
pub fn get_anniversary_object(&self) -> Result<Option<CalendarObject>, Error> {
todo!();
}

View File

@@ -68,14 +68,8 @@ pub struct CalendarObject {
impl CalendarObject {
pub fn from_ics(ics: String) -> Result<Self, Error> {
let mut parser: ComponentParser<_, IcalCalendarObject> =
ComponentParser::new(ics.as_bytes());
let inner = parser.next().ok_or(Error::MissingCalendar)??;
if parser.next().is_some() {
return Err(Error::InvalidData(
"multiple calendars, only one allowed".to_owned(),
));
}
let parser: ComponentParser<_, IcalCalendarObject> = ComponentParser::new(ics.as_bytes());
let inner = parser.expect_one()?;
Ok(Self { inner, ics })
}

View File

@@ -1,137 +0,0 @@
use crate::Error;
use chrono::DateTime;
use chrono::Utc;
use derive_more::Display;
use ical::component::CalendarInnerData;
use ical::component::IcalCalendarObject;
use ical::parser::ComponentParser;
use ical::types::CalDateTime;
use serde::Deserialize;
use serde::Serialize;
use sha2::{Digest, Sha256};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Display)]
// specified in https://datatracker.ietf.org/doc/html/rfc5545#section-3.6
pub enum CalendarObjectType {
#[serde(rename = "VEVENT")]
Event = 0,
#[serde(rename = "VTODO")]
Todo = 1,
#[serde(rename = "VJOURNAL")]
Journal = 2,
}
impl From<&IcalCalendarObject> for CalendarObjectType {
fn from(value: &IcalCalendarObject) -> Self {
match value.get_inner() {
CalendarInnerData::Event(_, _) => Self::Event,
CalendarInnerData::Todo(_, _) => Self::Todo,
CalendarInnerData::Journal(_, _) => Self::Journal,
}
}
}
impl CalendarObjectType {
#[must_use]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Event => "VEVENT",
Self::Todo => "VTODO",
Self::Journal => "VJOURNAL",
}
}
}
impl rustical_xml::ValueSerialize for CalendarObjectType {
fn serialize(&self) -> String {
self.as_str().to_owned()
}
}
impl rustical_xml::ValueDeserialize for CalendarObjectType {
fn deserialize(val: &str) -> std::result::Result<Self, rustical_xml::XmlError> {
match <String as rustical_xml::ValueDeserialize>::deserialize(val)?.as_str() {
"VEVENT" => Ok(Self::Event),
"VTODO" => Ok(Self::Todo),
"VJOURNAL" => Ok(Self::Journal),
_ => Err(rustical_xml::XmlError::InvalidValue(
rustical_xml::ParseValueError::Other(format!(
"Invalid value '{val}', must be VEVENT, VTODO, or VJOURNAL"
)),
)),
}
}
}
#[derive(Debug, Clone)]
pub struct CalendarObject {
id: String,
inner: IcalCalendarObject,
ics: String,
}
impl CalendarObject {
pub fn from_ics(ics: String, id: Option<String>) -> Result<Self, Error> {
let mut parser: ComponentParser<_, IcalCalendarObject> =
ComponentParser::new(ics.as_bytes());
let inner = parser.next().ok_or(Error::MissingCalendar)??;
if parser.next().is_some() {
return Err(Error::InvalidData(
"multiple calendars, only one allowed".to_owned(),
));
}
Ok(Self {
id: id.unwrap_or_else(|| inner.get_uid().to_owned()),
inner,
ics,
})
}
#[must_use]
pub const fn get_inner(&self) -> &IcalCalendarObject {
&self.inner
}
#[must_use]
pub fn get_uid(&self) -> &str {
self.inner.get_uid()
}
#[must_use]
pub fn get_id(&self) -> &str {
&self.id
}
#[must_use]
pub fn get_etag(&self) -> String {
let mut hasher = Sha256::new();
hasher.update(self.get_uid());
hasher.update(self.get_ics());
format!("\"{:x}\"", hasher.finalize())
}
#[must_use]
pub fn get_ics(&self) -> &str {
&self.ics
}
#[must_use]
pub fn get_component_name(&self) -> &str {
self.get_object_type().as_str()
}
#[must_use]
pub fn get_object_type(&self) -> CalendarObjectType {
(&self.inner).into()
}
pub fn expand_recurrence(
&self,
start: Option<DateTime<Utc>>,
end: Option<DateTime<Utc>>,
) -> Result<String, Error> {
// Ok(self.inner.expand_recurrence(start, end)?)
todo!()
}
}