use actix_web::HttpRequest; use rustical_dav::{ methods::propfind::{PropElement, PropfindType}, resource::HandlePropfind, xml::{multistatus::PropstatWrapper, MultistatusElement}, }; use rustical_store::{event::Event, CalendarStore}; use serde::Deserialize; use tokio::sync::RwLock; use crate::{ event::resource::{EventProp, EventResource}, Error, }; // TODO: Implement all the other filters #[derive(Deserialize, Clone, Debug)] #[serde(rename_all = "kebab-case")] #[allow(dead_code)] struct TimeRangeElement { #[serde(rename = "@start")] start: Option, #[serde(rename = "@end")] end: Option, } #[derive(Deserialize, Clone, Debug)] #[serde(rename_all = "kebab-case")] #[allow(dead_code)] struct ParamFilterElement { is_not_defined: Option<()>, text_match: Option, #[serde(rename = "@name")] name: String, } #[derive(Deserialize, Clone, Debug)] #[serde(rename_all = "kebab-case")] #[allow(dead_code)] struct TextMatchElement { #[serde(rename = "@collation")] collation: String, #[serde(rename = "@negate-collation")] negate_collation: String, } #[derive(Deserialize, Clone, Debug)] #[serde(rename_all = "kebab-case")] #[allow(dead_code)] struct PropFilterElement { is_not_defined: Option<()>, time_range: Option, text_match: Option, #[serde(default)] param_filter: Vec, } #[derive(Deserialize, Clone, Debug)] #[serde(rename_all = "kebab-case")] #[allow(dead_code)] struct CompFilterElement { is_not_defined: Option<()>, time_range: Option, #[serde(default)] prop_filter: Vec, #[serde(default)] comp_filter: Vec, #[serde(rename = "@name")] name: String, } #[derive(Deserialize, Clone, Debug)] #[serde(rename_all = "kebab-case")] #[allow(dead_code)] struct FilterElement { comp_filter: CompFilterElement, } #[derive(Deserialize, Clone, Debug)] #[serde(rename_all = "kebab-case")] #[allow(dead_code)] // pub struct CalendarQueryRequest { #[serde(flatten)] pub prop: PropfindType, filter: Option, timezone: Option, } pub async fn get_events_calendar_query( _cal_query: &CalendarQueryRequest, principal: &str, cid: &str, store: &RwLock, ) -> Result, Error> { // TODO: Implement filtering Ok(store.read().await.get_events(principal, cid).await?) } pub async fn handle_calendar_query( cal_query: CalendarQueryRequest, req: HttpRequest, prefix: &str, principal: &str, cid: &str, cal_store: &RwLock, ) -> Result, String>, Error> { let events = get_events_calendar_query(&cal_query, principal, cid, cal_store).await?; let props = match cal_query.prop { PropfindType::Allprop => { vec!["allprop".to_owned()] } PropfindType::Propname => { // TODO: Implement return Err(Error::NotImplemented); } PropfindType::Prop(PropElement { prop: prop_tags }) => prop_tags.into(), }; let props: Vec<&str> = props.iter().map(String::as_str).collect(); let mut responses = Vec::new(); for event in events { let path = format!("{}/{}", req.path(), event.get_uid()); responses.push( EventResource::from(event) .propfind(prefix, &path, props.clone()) .await?, ); } Ok(MultistatusElement { responses, ..Default::default() }) }