Switch event representation such that properties can be extracted

This commit is contained in:
Lennart
2023-09-20 16:40:38 +02:00
parent 94500d25d6
commit 0c71fec7fc
6 changed files with 63 additions and 13 deletions

View File

@@ -22,3 +22,6 @@ sqlx = { version = "0.7.1", features = [
] }
tokio = { version = "1.32.0", features = ["sync", "full"] }
toml = "0.7.6"
ical = { git = "https://github.com/Peltoche/ical-rs.git", rev = "4f7aeb0", features = [
"generator",
] }

View File

@@ -1,17 +1,63 @@
use anyhow::Result;
use std::io::BufReader;
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use ical::generator::{Emitter, IcalCalendar};
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
#[derive(Debug, Clone, Deserialize, Serialize)]
#[derive(Debug, Clone)]
pub struct Event {
uid: String,
ics: String,
cal: IcalCalendar,
}
// Custom implementation for Event (de)serialization
impl<'de> Deserialize<'de> for Event {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(Deserialize)]
struct Inner {
uid: String,
ics: String,
}
let Inner { uid, ics } = Inner::deserialize(deserializer)?;
Self::from_ics(uid, ics).map_err(serde::de::Error::custom)
}
}
impl Serialize for Event {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
#[derive(Serialize)]
struct Inner {
uid: String,
ics: String,
}
Inner::serialize(
&Inner {
uid: self.get_uid().to_string(),
ics: self.get_ics().to_string(),
},
serializer,
)
}
}
impl Event {
pub fn from_ics(uid: String, ics: String) -> Self {
Self { uid, ics }
pub fn from_ics(uid: String, ics: String) -> Result<Self> {
let mut parser = ical::IcalParser::new(BufReader::new(ics.as_bytes()));
let cal = parser.next().ok_or(anyhow!("no calendar :("))??;
if parser.next().is_some() {
return Err(anyhow!("multiple calendars!"));
}
if cal.events.len() == 2 {
return Err(anyhow!("multiple events"));
}
Ok(Self { uid, cal })
}
pub fn get_uid(&self) -> &str {
&self.uid
@@ -19,12 +65,12 @@ impl Event {
pub fn get_etag(&self) -> String {
let mut hasher = Sha256::new();
hasher.update(&self.uid);
hasher.update(self.as_ics());
hasher.update(self.get_ics());
format!("{:x}", hasher.finalize())
}
pub fn as_ics(&self) -> &str {
&self.ics
pub fn get_ics(&self) -> String {
self.cal.generate()
}
}
@@ -38,8 +84,6 @@ pub struct Calendar {
pub timezone: Option<String>,
}
impl Calendar {}
#[async_trait]
pub trait CalendarStore: Send + Sync + 'static {
async fn get_calendar(&self, id: &str) -> Result<Calendar>;

View File

@@ -70,7 +70,7 @@ impl CalendarStore for TomlCalendarStore {
async fn upsert_event(&mut self, cid: String, uid: String, ics: String) -> Result<()> {
let events = self.events.entry(cid).or_insert(HashMap::new());
events.insert(uid.clone(), Event::from_ics(uid, ics));
events.insert(uid.clone(), Event::from_ics(uid, ics)?);
self.save().await.unwrap();
Ok(())
}