From c14f98a4324d54185cbcd97aa9a7cb01a6e00f2d Mon Sep 17 00:00:00 2001 From: Lennart <18233294+lennart-k@users.noreply.github.com> Date: Tue, 3 Jun 2025 23:06:00 +0200 Subject: [PATCH] slight report refactoring --- .../methods/report/calendar_multiget.rs | 58 +---------- .../calendar/methods/report/calendar_query.rs | 46 +-------- .../caldav/src/calendar/methods/report/mod.rs | 98 +++++++++++++++---- crates/ical/src/timestamp.rs | 2 +- 4 files changed, 86 insertions(+), 118 deletions(-) diff --git a/crates/caldav/src/calendar/methods/report/calendar_multiget.rs b/crates/caldav/src/calendar/methods/report/calendar_multiget.rs index a62334a..43ffc5f 100644 --- a/crates/caldav/src/calendar/methods/report/calendar_multiget.rs +++ b/crates/caldav/src/calendar/methods/report/calendar_multiget.rs @@ -1,18 +1,9 @@ use super::ReportPropName; -use crate::{ - Error, - calendar_object::resource::{CalendarObjectPropWrapper, CalendarObjectResource}, -}; -use actix_web::{ - dev::{Path, ResourceDef}, - http::StatusCode, -}; -use rustical_dav::{ - resource::{PrincipalUri, Resource}, - xml::{MultistatusElement, PropfindType, multistatus::ResponseElement}, -}; +use crate::Error; +use actix_web::dev::{Path, ResourceDef}; +use rustical_dav::xml::PropfindType; use rustical_ical::CalendarObject; -use rustical_store::{CalendarStore, auth::User}; +use rustical_store::CalendarStore; use rustical_xml::XmlDeserialize; #[derive(XmlDeserialize, Clone, Debug, PartialEq)] @@ -54,44 +45,3 @@ pub async fn get_objects_calendar_multiget( Ok((result, not_found)) } - -pub async fn handle_calendar_multiget( - cal_multiget: &CalendarMultigetRequest, - props: &[&str], - path: &str, - puri: &impl PrincipalUri, - user: &User, - principal: &str, - cal_id: &str, - cal_store: &C, -) -> Result, Error> { - let (objects, not_found) = - get_objects_calendar_multiget(cal_multiget, path, principal, cal_id, cal_store).await?; - - let mut responses = Vec::new(); - for object in objects { - let path = format!("{}/{}.ics", path, object.get_id()); - responses.push( - CalendarObjectResource { - object, - principal: principal.to_owned(), - } - .propfind(&path, props, puri, user)?, - ); - } - - let not_found_responses = not_found - .into_iter() - .map(|path| ResponseElement { - href: path, - status: Some(StatusCode::NOT_FOUND), - ..Default::default() - }) - .collect(); - - Ok(MultistatusElement { - responses, - member_responses: not_found_responses, - ..Default::default() - }) -} diff --git a/crates/caldav/src/calendar/methods/report/calendar_query.rs b/crates/caldav/src/calendar/methods/report/calendar_query.rs index 18802bd..46e6242 100644 --- a/crates/caldav/src/calendar/methods/report/calendar_query.rs +++ b/crates/caldav/src/calendar/methods/report/calendar_query.rs @@ -1,19 +1,11 @@ -use rustical_dav::{ - resource::{PrincipalUri, Resource}, - xml::{MultistatusElement, PropfindType}, -}; +use super::ReportPropName; +use crate::Error; +use rustical_dav::xml::PropfindType; use rustical_ical::{CalendarObject, UtcDateTime}; -use rustical_store::{CalendarStore, auth::User, calendar_store::CalendarQuery}; +use rustical_store::{CalendarStore, calendar_store::CalendarQuery}; use rustical_xml::XmlDeserialize; use std::ops::Deref; -use crate::{ - Error, - calendar_object::resource::{CalendarObjectPropWrapper, CalendarObjectResource}, -}; - -use super::ReportPropName; - #[derive(XmlDeserialize, Clone, Debug, PartialEq)] #[allow(dead_code)] pub(crate) struct TimeRangeElement { @@ -212,33 +204,3 @@ pub async fn get_objects_calendar_query( } Ok(objects) } - -pub async fn handle_calendar_query( - cal_query: &CalendarQueryRequest, - props: &[&str], - path: &str, - puri: &impl PrincipalUri, - user: &User, - principal: &str, - cal_id: &str, - cal_store: &C, -) -> Result, Error> { - let objects = get_objects_calendar_query(cal_query, principal, cal_id, cal_store).await?; - - let mut responses = Vec::new(); - for object in objects { - let path = format!("{}/{}.ics", path, object.get_id()); - responses.push( - CalendarObjectResource { - object, - principal: principal.to_owned(), - } - .propfind(&path, props, puri, user)?, - ); - } - - Ok(MultistatusElement { - responses, - ..Default::default() - }) -} diff --git a/crates/caldav/src/calendar/methods/report/mod.rs b/crates/caldav/src/calendar/methods/report/mod.rs index 5006da6..510b268 100644 --- a/crates/caldav/src/calendar/methods/report/mod.rs +++ b/crates/caldav/src/calendar/methods/report/mod.rs @@ -1,13 +1,22 @@ -use crate::{CalDavPrincipalUri, Error}; +use crate::{ + CalDavPrincipalUri, Error, + calendar_object::resource::{CalendarObjectPropWrapper, CalendarObjectResource}, +}; use actix_web::{ HttpRequest, Responder, + http::StatusCode, web::{Data, Path}, }; -use calendar_multiget::{CalendarMultigetRequest, handle_calendar_multiget}; -use calendar_query::{CalendarQueryRequest, handle_calendar_query}; -use rustical_dav::xml::{ - PropElement, PropfindType, Propname, sync_collection::SyncCollectionRequest, +use calendar_multiget::{CalendarMultigetRequest, get_objects_calendar_multiget}; +use calendar_query::{CalendarQueryRequest, get_objects_calendar_query}; +use rustical_dav::{ + resource::{PrincipalUri, Resource}, + xml::{ + MultistatusElement, PropElement, PropfindType, Propname, multistatus::ResponseElement, + sync_collection::SyncCollectionRequest, + }, }; +use rustical_ical::{CalendarObject, UtcDateTime}; use rustical_store::{CalendarStore, auth::User}; use rustical_xml::{XmlDeserialize, XmlDocument}; use sync_collection::handle_sync_collection; @@ -20,9 +29,9 @@ mod sync_collection; #[derive(XmlDeserialize, Clone, Debug, PartialEq)] pub(crate) struct ExpandElement { #[xml(ty = "attr")] - start: String, + start: UtcDateTime, #[xml(ty = "attr")] - end: String, + end: UtcDateTime, } #[derive(XmlDeserialize, Clone, Debug, PartialEq)] @@ -81,6 +90,43 @@ impl ReportRequest { } } +fn objects_response( + objects: Vec, + not_found: Vec, + path: &str, + principal: &str, + puri: &impl PrincipalUri, + user: &User, + props: &[&str], +) -> Result, Error> { + let mut responses = Vec::new(); + for object in objects { + let path = format!("{}/{}.ics", path, object.get_id()); + responses.push( + CalendarObjectResource { + object, + principal: principal.to_owned(), + } + .propfind(&path, props, puri, user)?, + ); + } + + let not_found_responses = not_found + .into_iter() + .map(|path| ResponseElement { + href: path, + status: Some(StatusCode::NOT_FOUND), + ..Default::default() + }) + .collect(); + + Ok(MultistatusElement { + responses, + member_responses: not_found_responses, + ..Default::default() + }) +} + #[instrument(skip(req, cal_store))] pub async fn route_report_calendar( path: Path<(String, String)>, @@ -100,30 +146,37 @@ pub async fn route_report_calendar( Ok(match &request { ReportRequest::CalendarQuery(cal_query) => { - handle_calendar_query( - cal_query, - &props, + let objects = + get_objects_calendar_query(cal_query, &principal, &cal_id, cal_store.as_ref()) + .await?; + objects_response( + objects, + vec![], req.path(), + &principal, puri.as_ref(), &user, - &principal, - &cal_id, - cal_store.as_ref(), - ) - .await? + &props, + )? } ReportRequest::CalendarMultiget(cal_multiget) => { - handle_calendar_multiget( + let (objects, not_found) = get_objects_calendar_multiget( cal_multiget, - &props, req.path(), - puri.as_ref(), - &user, &principal, &cal_id, cal_store.as_ref(), ) - .await? + .await?; + objects_response( + objects, + not_found, + req.path(), + &principal, + puri.as_ref(), + &user, + &props, + )? } ReportRequest::SyncCollection(sync_collection) => { handle_sync_collection( @@ -171,7 +224,10 @@ mod tests { prop: rustical_dav::xml::PropfindType::Prop(PropElement(vec![ ReportPropName::Propname(Propname{name: "getetag".to_owned(), ns: Some("DAV:".into())}), ReportPropName::Propname(Propname{name: "displayname".to_owned(), ns: Some("DAV:".into())}), - ReportPropName::CalendarData(CalendarData { comp: None, expand: Some(ExpandElement { start: "20250426T220000Z".to_owned(), end: "20250503T220000Z".to_owned() }), limit_recurrence_set: None, limit_freebusy_set: None }) + ReportPropName::CalendarData(CalendarData { comp: None, expand: Some(ExpandElement { + start: ::deserialize("20250426T220000Z").unwrap(), + end: ::deserialize("20250503T220000Z").unwrap(), + }), limit_recurrence_set: None, limit_freebusy_set: None }) ])), href: vec![ "/caldav/user/user/6f787542-5256-401a-8db97003260da/ae7a998fdfd1d84a20391168962c62b".to_owned() diff --git a/crates/ical/src/timestamp.rs b/crates/ical/src/timestamp.rs index 78896a1..d6fecd1 100644 --- a/crates/ical/src/timestamp.rs +++ b/crates/ical/src/timestamp.rs @@ -39,7 +39,7 @@ pub enum CalDateTimeError { } #[derive(Debug, Clone, Deref, PartialEq)] -pub struct UtcDateTime(DateTime); +pub struct UtcDateTime(pub DateTime); impl ValueDeserialize for UtcDateTime { fn deserialize(val: &str) -> Result {