rustical_dav/resources/
root.rs1use crate::Principal;
2use crate::extensions::{
3 CommonPropertiesExtension, CommonPropertiesProp, CommonPropertiesPropName,
4};
5use crate::namespace::NS_DAV;
6use crate::privileges::UserPrivilegeSet;
7use crate::resource::{AxumMethods, PrincipalUri, Resource, ResourceName, ResourceService};
8use crate::xml::{Resourcetype, ResourcetypeInner};
9use async_trait::async_trait;
10use axum::Router;
11use axum::extract::FromRequestParts;
12use std::marker::PhantomData;
13
14#[derive(Clone)]
15pub struct RootResource<PR: Resource, P: Principal>(PhantomData<PR>, PhantomData<P>);
16
17impl<PR: Resource, P: Principal> Default for RootResource<PR, P> {
18 fn default() -> Self {
19 Self(PhantomData, PhantomData)
20 }
21}
22
23impl<PR: Resource, P: Principal> Resource for RootResource<PR, P> {
24 type Prop = CommonPropertiesProp;
25 type Error = PR::Error;
26 type Principal = P;
27
28 fn is_collection(&self) -> bool {
29 true
30 }
31
32 fn get_resourcetype(&self) -> Resourcetype {
33 Resourcetype(&[ResourcetypeInner(Some(NS_DAV), "collection")])
34 }
35
36 fn get_displayname(&self) -> Option<&str> {
37 Some("RustiCal DAV root")
38 }
39
40 fn get_prop(
41 &self,
42 principal_uri: &impl PrincipalUri,
43 user: &P,
44 prop: &CommonPropertiesPropName,
45 ) -> Result<Self::Prop, Self::Error> {
46 CommonPropertiesExtension::get_prop(self, principal_uri, user, prop)
47 }
48
49 fn get_user_privileges(&self, _user: &P) -> Result<UserPrivilegeSet, Self::Error> {
50 Ok(UserPrivilegeSet::all())
51 }
52}
53
54#[derive(Clone)]
55pub struct RootResourceService<PRS: ResourceService + Clone, P: Principal, PURI: PrincipalUri>(
56 PRS,
57 PhantomData<P>,
58 PhantomData<PURI>,
59);
60
61impl<PRS: ResourceService + Clone, P: Principal, PURI: PrincipalUri>
62 RootResourceService<PRS, P, PURI>
63{
64 pub const fn new(principal_resource_service: PRS) -> Self {
65 Self(principal_resource_service, PhantomData, PhantomData)
66 }
67}
68
69#[async_trait]
70impl<
71 PRS: ResourceService<Principal = P> + Clone,
72 P: Principal + FromRequestParts<Self>,
73 PURI: PrincipalUri,
74> ResourceService for RootResourceService<PRS, P, PURI>
75where
76 PRS::Resource: ResourceName,
77{
78 type PathComponents = ();
79 type MemberType = PRS::Resource;
80 type Resource = RootResource<PRS::Resource, P>;
81 type Error = PRS::Error;
82 type Principal = P;
83 type PrincipalUri = PURI;
84
85 const DAV_HEADER: &str = "1, 3, access-control";
86
87 async fn get_resource(
88 &self,
89 (): &(),
90 _show_deleted: bool,
91 ) -> Result<Self::Resource, Self::Error> {
92 Ok(RootResource::<PRS::Resource, P>::default())
93 }
94
95 fn axum_router<S: Send + Sync + Clone + 'static>(self) -> Router<S> {
96 Router::new()
97 .nest("/principal/{principal}", self.0.clone().axum_router())
98 .route_service("/", self.axum_service())
99 }
100}
101
102impl<PRS: ResourceService<Principal = P> + Clone, P: Principal, PURI: PrincipalUri> AxumMethods
103 for RootResourceService<PRS, P, PURI>
104{
105}