caldav: refactor resource newtypes

This commit is contained in:
Lennart
2024-09-29 13:39:45 +02:00
parent 1b438ea98a
commit 7f164da438
7 changed files with 36 additions and 53 deletions

View File

@@ -24,3 +24,4 @@ tokio = { version = "1.40", features = ["sync", "full"] }
async-trait = "0.1" async-trait = "0.1"
thiserror = "1.0" thiserror = "1.0"
strum = { version = "0.26", features = ["strum_macros", "derive"] } strum = { version = "0.26", features = ["strum_macros", "derive"] }
derive_more = { version = "1.0", features = ["from", "into"] }

View File

@@ -87,7 +87,7 @@ pub async fn handle_calendar_multiget<C: CalendarStore + ?Sized>(
for event in events { for event in events {
let path = format!("{}/{}", req.path(), event.get_uid()); let path = format!("{}/{}", req.path(), event.get_uid());
responses.push( responses.push(
EventFile { event } EventFile::from(event)
.propfind(prefix, path, props.clone()) .propfind(prefix, path, props.clone())
.await?, .await?,
); );

View File

@@ -126,7 +126,7 @@ pub async fn handle_calendar_query<C: CalendarStore + ?Sized>(
for event in events { for event in events {
let path = format!("{}/{}", req.path(), event.get_uid()); let path = format!("{}/{}", req.path(), event.get_uid());
responses.push( responses.push(
EventFile { event } EventFile::from(event)
.propfind(prefix, path, props.clone()) .propfind(prefix, path, props.clone())
.await?, .await?,
); );

View File

@@ -73,7 +73,7 @@ pub async fn handle_sync_collection<C: CalendarStore + ?Sized>(
for event in new_events { for event in new_events {
let path = format!("{}/{}", req.path(), event.get_uid()); let path = format!("{}/{}", req.path(), event.get_uid());
responses.push( responses.push(
EventFile { event } EventFile::from(event)
.propfind(prefix, path, props.clone()) .propfind(prefix, path, props.clone())
.await?, .await?,
); );

View File

@@ -3,6 +3,7 @@ use crate::Error;
use actix_web::{web::Data, HttpRequest}; use actix_web::{web::Data, HttpRequest};
use anyhow::anyhow; use anyhow::anyhow;
use async_trait::async_trait; use async_trait::async_trait;
use derive_more::derive::{From, Into};
use rustical_auth::AuthInfo; use rustical_auth::AuthInfo;
use rustical_dav::resource::{InvalidProperty, Resource, ResourceService}; use rustical_dav::resource::{InvalidProperty, Resource, ResourceService};
use rustical_dav::xml::HrefElement; use rustical_dav::xml::HrefElement;
@@ -87,10 +88,8 @@ impl InvalidProperty for CalendarProp {
} }
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug, From, Into)]
pub struct CalendarFile { pub struct CalendarFile(Calendar);
pub calendar: Calendar,
}
impl Resource for CalendarFile { impl Resource for CalendarFile {
type PropName = CalendarPropName; type PropName = CalendarPropName;
@@ -101,26 +100,22 @@ impl Resource for CalendarFile {
Ok(match prop { Ok(match prop {
CalendarPropName::Resourcetype => CalendarProp::Resourcetype(Resourcetype::default()), CalendarPropName::Resourcetype => CalendarProp::Resourcetype(Resourcetype::default()),
CalendarPropName::CurrentUserPrincipal => CalendarProp::CurrentUserPrincipal( CalendarPropName::CurrentUserPrincipal => CalendarProp::CurrentUserPrincipal(
HrefElement::new(format!("{}/user/{}/", prefix, self.calendar.principal)), HrefElement::new(format!("{}/user/{}/", prefix, self.0.principal)),
), ),
CalendarPropName::Owner => CalendarProp::Owner(HrefElement::new(format!( CalendarPropName::Owner => CalendarProp::Owner(HrefElement::new(format!(
"{}/user/{}/", "{}/user/{}/",
prefix, self.calendar.principal prefix, self.0.principal
))), ))),
CalendarPropName::Displayname => { CalendarPropName::Displayname => CalendarProp::Displayname(self.0.displayname.clone()),
CalendarProp::Displayname(self.calendar.displayname.clone()) CalendarPropName::CalendarColor => CalendarProp::CalendarColor(self.0.color.clone()),
}
CalendarPropName::CalendarColor => {
CalendarProp::CalendarColor(self.calendar.color.clone())
}
CalendarPropName::CalendarDescription => { CalendarPropName::CalendarDescription => {
CalendarProp::CalendarDescription(self.calendar.description.clone()) CalendarProp::CalendarDescription(self.0.description.clone())
} }
CalendarPropName::CalendarTimezone => { CalendarPropName::CalendarTimezone => {
CalendarProp::CalendarTimezone(self.calendar.timezone.clone()) CalendarProp::CalendarTimezone(self.0.timezone.clone())
} }
CalendarPropName::CalendarOrder => { CalendarPropName::CalendarOrder => {
CalendarProp::CalendarOrder(format!("{}", self.calendar.order).into()) CalendarProp::CalendarOrder(format!("{}", self.0.order).into())
} }
CalendarPropName::SupportedCalendarComponentSet => { CalendarPropName::SupportedCalendarComponentSet => {
CalendarProp::SupportedCalendarComponentSet(SupportedCalendarComponentSet { CalendarProp::SupportedCalendarComponentSet(SupportedCalendarComponentSet {
@@ -144,10 +139,8 @@ impl Resource for CalendarFile {
CalendarPropName::SupportedReportSet => { CalendarPropName::SupportedReportSet => {
CalendarProp::SupportedReportSet(SupportedReportSet::default()) CalendarProp::SupportedReportSet(SupportedReportSet::default())
} }
CalendarPropName::SyncToken => { CalendarPropName::SyncToken => CalendarProp::SyncToken(self.0.format_synctoken()),
CalendarProp::SyncToken(self.calendar.format_synctoken()) CalendarPropName::Getctag => CalendarProp::Getctag(self.0.format_synctoken()),
}
CalendarPropName::Getctag => CalendarProp::Getctag(self.calendar.format_synctoken()),
}) })
} }
@@ -157,23 +150,23 @@ impl Resource for CalendarFile {
CalendarProp::CurrentUserPrincipal(_) => Err(rustical_dav::Error::PropReadOnly), CalendarProp::CurrentUserPrincipal(_) => Err(rustical_dav::Error::PropReadOnly),
CalendarProp::Owner(_) => Err(rustical_dav::Error::PropReadOnly), CalendarProp::Owner(_) => Err(rustical_dav::Error::PropReadOnly),
CalendarProp::Displayname(displayname) => { CalendarProp::Displayname(displayname) => {
self.calendar.displayname = displayname; self.0.displayname = displayname;
Ok(()) Ok(())
} }
CalendarProp::CalendarColor(color) => { CalendarProp::CalendarColor(color) => {
self.calendar.color = color; self.0.color = color;
Ok(()) Ok(())
} }
CalendarProp::CalendarDescription(description) => { CalendarProp::CalendarDescription(description) => {
self.calendar.description = description; self.0.description = description;
Ok(()) Ok(())
} }
CalendarProp::CalendarTimezone(timezone) => { CalendarProp::CalendarTimezone(timezone) => {
self.calendar.timezone = timezone; self.0.timezone = timezone;
Ok(()) Ok(())
} }
CalendarProp::CalendarOrder(order) => { CalendarProp::CalendarOrder(order) => {
self.calendar.order = match order { self.0.order = match order {
Some(order) => order.parse().map_err(|_e| anyhow!("invalid order"))?, Some(order) => order.parse().map_err(|_e| anyhow!("invalid order"))?,
None => 0, None => 0,
}; };
@@ -199,23 +192,23 @@ impl Resource for CalendarFile {
CalendarPropName::CurrentUserPrincipal => Err(rustical_dav::Error::PropReadOnly), CalendarPropName::CurrentUserPrincipal => Err(rustical_dav::Error::PropReadOnly),
CalendarPropName::Owner => Err(rustical_dav::Error::PropReadOnly), CalendarPropName::Owner => Err(rustical_dav::Error::PropReadOnly),
CalendarPropName::Displayname => { CalendarPropName::Displayname => {
self.calendar.displayname = None; self.0.displayname = None;
Ok(()) Ok(())
} }
CalendarPropName::CalendarColor => { CalendarPropName::CalendarColor => {
self.calendar.color = None; self.0.color = None;
Ok(()) Ok(())
} }
CalendarPropName::CalendarDescription => { CalendarPropName::CalendarDescription => {
self.calendar.description = None; self.0.description = None;
Ok(()) Ok(())
} }
CalendarPropName::CalendarTimezone => { CalendarPropName::CalendarTimezone => {
self.calendar.timezone = None; self.0.timezone = None;
Ok(()) Ok(())
} }
CalendarPropName::CalendarOrder => { CalendarPropName::CalendarOrder => {
self.calendar.order = 0; self.0.order = 0;
Ok(()) Ok(())
} }
CalendarPropName::SupportedCalendarComponentSet => { CalendarPropName::SupportedCalendarComponentSet => {
@@ -247,7 +240,7 @@ impl<C: CalendarStore + ?Sized> ResourceService for CalendarResource<C> {
.get_calendar(&self.principal, &self.calendar_id) .get_calendar(&self.principal, &self.calendar_id)
.await .await
.map_err(|_e| Error::NotFound)?; .map_err(|_e| Error::NotFound)?;
Ok(CalendarFile { calendar }) Ok(calendar.into())
} }
async fn get_members( async fn get_members(
@@ -262,12 +255,7 @@ impl<C: CalendarStore + ?Sized> ResourceService for CalendarResource<C> {
.get_events(&self.principal, &self.calendar_id) .get_events(&self.principal, &self.calendar_id)
.await? .await?
.into_iter() .into_iter()
.map(|event| { .map(|event| (format!("{}/{}", self.path, &event.get_uid()), event.into()))
(
format!("{}/{}", self.path, &event.get_uid()),
EventFile { event },
)
})
.collect()) .collect())
} }
@@ -297,7 +285,7 @@ impl<C: CalendarStore + ?Sized> ResourceService for CalendarResource<C> {
.update_calendar( .update_calendar(
self.principal.to_owned(), self.principal.to_owned(),
self.calendar_id.to_owned(), self.calendar_id.to_owned(),
file.calendar, file.into(),
) )
.await?; .await?;
Ok(()) Ok(())

View File

@@ -1,6 +1,7 @@
use crate::Error; use crate::Error;
use actix_web::{web::Data, HttpRequest}; use actix_web::{web::Data, HttpRequest};
use async_trait::async_trait; use async_trait::async_trait;
use derive_more::derive::{From, Into};
use rustical_auth::AuthInfo; use rustical_auth::AuthInfo;
use rustical_dav::resource::{InvalidProperty, Resource, ResourceService}; use rustical_dav::resource::{InvalidProperty, Resource, ResourceService};
use rustical_store::event::Event; use rustical_store::event::Event;
@@ -43,10 +44,8 @@ impl InvalidProperty for EventProp {
} }
} }
#[derive(Clone)] #[derive(Clone, From, Into)]
pub struct EventFile { pub struct EventFile(Event);
pub event: Event,
}
impl Resource for EventFile { impl Resource for EventFile {
type PropName = EventPropName; type PropName = EventPropName;
@@ -55,8 +54,8 @@ impl Resource for EventFile {
fn get_prop(&self, _prefix: &str, prop: Self::PropName) -> Result<Self::Prop, Self::Error> { fn get_prop(&self, _prefix: &str, prop: Self::PropName) -> Result<Self::Prop, Self::Error> {
Ok(match prop { Ok(match prop {
EventPropName::Getetag => EventProp::Getetag(self.event.get_etag()), EventPropName::Getetag => EventProp::Getetag(self.0.get_etag()),
EventPropName::CalendarData => EventProp::CalendarData(self.event.get_ics().to_owned()), EventPropName::CalendarData => EventProp::CalendarData(self.0.get_ics().to_owned()),
EventPropName::Getcontenttype => { EventPropName::Getcontenttype => {
EventProp::Getcontenttype("text/calendar;charset=utf-8".to_owned()) EventProp::Getcontenttype("text/calendar;charset=utf-8".to_owned())
} }
@@ -104,7 +103,7 @@ impl<C: CalendarStore + ?Sized> ResourceService for EventResource<C> {
.await .await
.get_event(&self.principal, &self.cid, &self.uid) .get_event(&self.principal, &self.cid, &self.uid)
.await?; .await?;
Ok(EventFile { event }) Ok(event.into())
} }
async fn save_file(&self, _file: Self::File) -> Result<(), Self::Error> { async fn save_file(&self, _file: Self::File) -> Result<(), Self::Error> {

View File

@@ -130,12 +130,7 @@ impl<C: CalendarStore + ?Sized> ResourceService for PrincipalResource<C> {
.await?; .await?;
Ok(calendars Ok(calendars
.into_iter() .into_iter()
.map(|cal| { .map(|cal| (format!("{}/{}", &self.path, &cal.id), cal.into()))
(
format!("{}/{}", &self.path, &cal.id),
CalendarFile { calendar: cal },
)
})
.collect()) .collect())
} }