diff --git a/crates/caldav/src/calendar/resource.rs b/crates/caldav/src/calendar/resource.rs index 035b05a..e3af1c9 100644 --- a/crates/caldav/src/calendar/resource.rs +++ b/crates/caldav/src/calendar/resource.rs @@ -1,9 +1,10 @@ use super::prop::{SupportedCalendarComponentSet, SupportedCalendarData, SupportedReportSet}; use crate::calendar::methods::mkcalendar::route_mkcalendar; use crate::calendar::methods::report::route_report_calendar; -use crate::calendar_object::resource::CalendarObjectResource; +use crate::calendar_object::resource::{CalendarObjectResource, CalendarObjectResourceService}; use crate::{CalDavPrincipalUri, Error}; use async_trait::async_trait; +use axum::Router; use axum::extract::Request; use axum::handler::Handler; use axum::response::Response; @@ -398,6 +399,15 @@ impl ResourceService for CalendarResourc .await?; Ok(()) } + + fn axum_router(self) -> axum::Router { + Router::new() + .nest( + "/{object_id}", + CalendarObjectResourceService::new(self.cal_store.clone()).axum_router(), + ) + .route_service("/", self.axum_service()) + } } impl AxumMethods for CalendarResourceService { diff --git a/crates/caldav/src/calendar_set/mod.rs b/crates/caldav/src/calendar_set/mod.rs index 3461a82..2029cd1 100644 --- a/crates/caldav/src/calendar_set/mod.rs +++ b/crates/caldav/src/calendar_set/mod.rs @@ -1,6 +1,7 @@ -use crate::calendar::resource::CalendarResource; +use crate::calendar::resource::{CalendarResource, CalendarResourceService}; use crate::{CalDavPrincipalUri, Error}; use async_trait::async_trait; +use axum::Router; use rustical_dav::extensions::{CommonPropertiesExtension, CommonPropertiesProp}; use rustical_dav::privileges::UserPrivilegeSet; use rustical_dav::resource::{AxumMethods, PrincipalUri, Resource, ResourceService}; @@ -125,5 +126,15 @@ impl ResourceService for CalendarSetReso }) .collect()) } + + fn axum_router(self) -> axum::Router { + Router::new() + .nest( + "/{calendar_id}", + CalendarResourceService::new(self.cal_store.clone(), self.sub_store.clone()) + .axum_router(), + ) + .route_service("/", self.axum_service()) + } } impl AxumMethods for CalendarSetResourceService {} diff --git a/crates/caldav/src/lib.rs b/crates/caldav/src/lib.rs index 99e8e04..d4503f6 100644 --- a/crates/caldav/src/lib.rs +++ b/crates/caldav/src/lib.rs @@ -17,10 +17,6 @@ pub mod principal; pub use error::Error; -use crate::calendar::resource::CalendarResourceService; -use crate::calendar_object::resource::CalendarObjectResourceService; -use crate::calendar_set::CalendarSetResourceService; - #[derive(Debug, Clone, Constructor)] pub struct CalDavPrincipalUri(&'static str); @@ -50,44 +46,8 @@ pub fn caldav_router< cal_store: store.clone(), }; - Router::new() - .route_service( - "/", - RootResourceService::<_, User, CalDavPrincipalUri>::new(principal_service.clone()) - .axum_service(), - ) - .route_service("/principal/{principal}", principal_service.axum_service()) - .route_service( - "/principal/{principal}/calendar", - CalendarSetResourceService::new("calendar", store.clone(), subscription_store.clone()) - .axum_service(), - ) - .route_service( - "/principal/{principal}/calendar/{calendar_id}", - CalendarResourceService::new(store.clone(), subscription_store.clone()).axum_service(), - ) - .route_service( - "/principal/{principal}/calendar/{calendar_id}/{object_id}", - CalendarObjectResourceService::new(store.clone()).axum_service(), - ) - .route_service( - "/principal/{principal}/birthdays", - CalendarSetResourceService::new( - "birthdays", - birthday_store.clone(), - subscription_store.clone(), - ) - .axum_service(), - ) - .route_service( - "/principal/{principal}/birthdays/{calendar_id}", - CalendarResourceService::new(birthday_store.clone(), subscription_store.clone()) - .axum_service(), - ) - .route_service( - "/principal/{principal}/birthdays/{calendar_id}/{object_id}", - CalendarObjectResourceService::new(birthday_store.clone()).axum_service(), - ) + RootResourceService::<_, User, CalDavPrincipalUri>::new(principal_service.clone()) + .axum_router() .layer(AuthenticationLayer::new(auth_provider)) .layer(Extension(CalDavPrincipalUri(prefix))) } diff --git a/crates/caldav/src/principal/mod.rs b/crates/caldav/src/principal/mod.rs index 29aea83..6095391 100644 --- a/crates/caldav/src/principal/mod.rs +++ b/crates/caldav/src/principal/mod.rs @@ -1,6 +1,7 @@ -use crate::calendar_set::CalendarSetResource; +use crate::calendar_set::{CalendarSetResource, CalendarSetResourceService}; use crate::{CalDavPrincipalUri, Error}; use async_trait::async_trait; +use axum::Router; use rustical_dav::extensions::{CommonPropertiesExtension, CommonPropertiesProp}; use rustical_dav::privileges::UserPrivilegeSet; use rustical_dav::resource::{AxumMethods, PrincipalUri, Resource, ResourceService}; @@ -193,6 +194,29 @@ impl(self) -> axum::Router { + Router::new() + .nest( + "/calendar", + CalendarSetResourceService::new( + "calendar", + self.cal_store.clone(), + self.sub_store.clone(), + ) + .axum_router(), + ) + .nest( + "/birthdays", + CalendarSetResourceService::new( + "birthdays", + self.birthday_store.clone(), + self.sub_store.clone(), + ) + .axum_router(), + ) + .route_service("/", self.axum_service()) + } } impl diff --git a/crates/carddav/src/addressbook/resource.rs b/crates/carddav/src/addressbook/resource.rs index e247bc1..17eed53 100644 --- a/crates/carddav/src/addressbook/resource.rs +++ b/crates/carddav/src/addressbook/resource.rs @@ -1,9 +1,10 @@ use super::methods::mkcol::route_mkcol; use super::methods::report::route_report_addressbook; use super::prop::{SupportedAddressData, SupportedReportSet}; -use crate::address_object::resource::AddressObjectResource; +use crate::address_object::resource::{AddressObjectResource, AddressObjectResourceService}; use crate::{CardDavPrincipalUri, Error}; use async_trait::async_trait; +use axum::Router; use axum::extract::Request; use axum::handler::Handler; use axum::response::Response; @@ -266,6 +267,15 @@ impl ResourceService .await?; Ok(()) } + + fn axum_router(self) -> Router { + Router::new() + .nest( + "/{object_id}", + AddressObjectResourceService::new(self.addr_store.clone()).axum_router(), + ) + .route_service("/", self.axum_service()) + } } impl AxumMethods for AddressbookResourceService { diff --git a/crates/carddav/src/lib.rs b/crates/carddav/src/lib.rs index 9a08b8b..56b0b30 100644 --- a/crates/carddav/src/lib.rs +++ b/crates/carddav/src/lib.rs @@ -1,5 +1,3 @@ -use crate::address_object::resource::AddressObjectResourceService; -use crate::addressbook::resource::AddressbookResourceService; use axum::{Extension, Router}; use derive_more::Constructor; pub use error::Error; @@ -38,22 +36,8 @@ pub fn carddav_router::new(principal_service.clone()) - .axum_service(), - ) - .route_service("/principal/{principal}", principal_service.axum_service()) - .route_service( - "/principal/{principal}/{addressbook_id}", - AddressbookResourceService::new(store.clone(), subscription_store.clone()) - .axum_service(), - ) - .route_service( - "/principal/{principal}/{addressbook_id}/{object_id}", - AddressObjectResourceService::new(store.clone()).axum_service(), - ) + RootResourceService::<_, User, CardDavPrincipalUri>::new(principal_service.clone()) + .axum_router() .layer(AuthenticationLayer::new(auth_provider)) .layer(Extension(CardDavPrincipalUri(prefix))) } diff --git a/crates/carddav/src/principal/mod.rs b/crates/carddav/src/principal/mod.rs index 81284bd..baf3b5d 100644 --- a/crates/carddav/src/principal/mod.rs +++ b/crates/carddav/src/principal/mod.rs @@ -1,6 +1,7 @@ -use crate::addressbook::resource::AddressbookResource; +use crate::addressbook::resource::{AddressbookResource, AddressbookResourceService}; use crate::{CardDavPrincipalUri, Error}; use async_trait::async_trait; +use axum::Router; use rustical_dav::extensions::{CommonPropertiesExtension, CommonPropertiesProp}; use rustical_dav::privileges::UserPrivilegeSet; use rustical_dav::resource::{AxumMethods, PrincipalUri, Resource, ResourceService}; @@ -174,6 +175,16 @@ impl Reso .map(|addressbook| (addressbook.id.to_owned(), addressbook.into())) .collect()) } + + fn axum_router(self) -> Router { + Router::new() + .nest( + "/{addressbook_id}", + AddressbookResourceService::new(self.addr_store.clone(), self.sub_store.clone()) + .axum_router(), + ) + .route_service("/", self.axum_service()) + } } impl AxumMethods diff --git a/crates/dav/src/resource/resource_service.rs b/crates/dav/src/resource/resource_service.rs index 2766248..b1d9b46 100644 --- a/crates/dav/src/resource/resource_service.rs +++ b/crates/dav/src/resource/resource_service.rs @@ -2,15 +2,18 @@ use super::{PrincipalUri, Resource}; use crate::Principal; use crate::resource::{AxumMethods, AxumService}; use async_trait::async_trait; +use axum::Router; +use axum::extract::FromRequestParts; +use axum::response::IntoResponse; use serde::Deserialize; #[async_trait] -pub trait ResourceService: Sized + Send + Sync + 'static { +pub trait ResourceService: Clone + Sized + Send + Sync + AxumMethods + 'static { type PathComponents: for<'de> Deserialize<'de> + Sized + Send + Sync + Clone + 'static; // defines how the resource URI maps to parameters, i.e. /{principal}/{calendar} -> (String, String) type MemberType: Resource; type Resource: Resource; - type Error: From + Send; - type Principal: Principal; + type Error: From + Send + Sync + IntoResponse + 'static; + type Principal: Principal + FromRequestParts; type PrincipalUri: PrincipalUri; const DAV_HEADER: &'static str; @@ -45,8 +48,12 @@ pub trait ResourceService: Sized + Send + Sync + 'static { fn axum_service(self) -> AxumService where - Self: Clone + Send + Sync + AxumMethods, + Self: AxumMethods, { AxumService::new(self) } + + fn axum_router(self) -> Router { + Router::new().route_service("/", self.axum_service()) + } } diff --git a/crates/dav/src/resources/root.rs b/crates/dav/src/resources/root.rs index 7c13c5b..75ae02b 100644 --- a/crates/dav/src/resources/root.rs +++ b/crates/dav/src/resources/root.rs @@ -6,6 +6,8 @@ use crate::privileges::UserPrivilegeSet; use crate::resource::{AxumMethods, PrincipalUri, Resource, ResourceService}; use crate::xml::{Resourcetype, ResourcetypeInner}; use async_trait::async_trait; +use axum::Router; +use axum::extract::FromRequestParts; use std::marker::PhantomData; #[derive(Clone)] @@ -59,8 +61,11 @@ impl } #[async_trait] -impl + Clone, P: Principal, PURI: PrincipalUri> ResourceService - for RootResourceService +impl< + PRS: ResourceService + Clone, + P: Principal + FromRequestParts, + PURI: PrincipalUri, +> ResourceService for RootResourceService { type PathComponents = (); type MemberType = PRS::Resource; @@ -74,6 +79,12 @@ impl + Clone, P: Principal, PURI: PrincipalU async fn get_resource(&self, _: &()) -> Result { Ok(RootResource::::default()) } + + fn axum_router(self) -> Router { + Router::new() + .nest("/principal/{principal}", self.0.clone().axum_router()) + .route_service("/", self.axum_service()) + } } impl + Clone, P: Principal, PURI: PrincipalUri> AxumMethods