rustical_caldav/calendar_object/
resource.rs

1use super::prop::{
2    CalendarData, CalendarObjectProp, CalendarObjectPropName, CalendarObjectPropWrapper,
3    CalendarObjectPropWrapperName,
4};
5use crate::Error;
6use caldata::generator::Emitter;
7use derive_more::derive::{From, Into};
8use rustical_dav::{
9    extensions::CommonPropertiesExtension,
10    privileges::UserPrivilegeSet,
11    resource::{PrincipalUri, Resource, ResourceName},
12    xml::Resourcetype,
13};
14use rustical_ical::CalendarObject;
15use rustical_store::auth::Principal;
16use std::borrow::Cow;
17
18#[derive(Clone, From, Into)]
19pub struct CalendarObjectResource {
20    pub object: CalendarObject,
21    pub object_id: String,
22    pub principal: String,
23}
24
25impl ResourceName for CalendarObjectResource {
26    fn get_name(&self) -> Cow<'_, str> {
27        Cow::from(format!("{}.ics", self.object_id))
28    }
29}
30
31impl Resource for CalendarObjectResource {
32    type Prop = CalendarObjectPropWrapper;
33    type Error = Error;
34    type Principal = Principal;
35
36    fn is_collection(&self) -> bool {
37        false
38    }
39
40    fn get_resourcetype(&self) -> Resourcetype {
41        Resourcetype(&[])
42    }
43
44    fn get_prop(
45        &self,
46        puri: &impl PrincipalUri,
47        user: &Principal,
48        prop: &CalendarObjectPropWrapperName,
49    ) -> Result<Self::Prop, Self::Error> {
50        Ok(match prop {
51            CalendarObjectPropWrapperName::CalendarObject(prop) => {
52                CalendarObjectPropWrapper::CalendarObject(match prop {
53                    CalendarObjectPropName::Getetag => {
54                        CalendarObjectProp::Getetag(self.object.get_etag())
55                    }
56                    CalendarObjectPropName::CalendarData(CalendarData { expand, .. }) => {
57                        CalendarObjectProp::CalendarData(expand.as_ref().map_or_else(
58                            || self.object.get_ics().to_owned(),
59                            |expand| {
60                                self.object
61                                    .get_inner()
62                                    .expand_recurrence(
63                                        Some(expand.start.to_utc()),
64                                        Some(expand.end.to_utc()),
65                                    )
66                                    .generate()
67                            },
68                        ))
69                    }
70                    CalendarObjectPropName::Getcontenttype => {
71                        CalendarObjectProp::Getcontenttype("text/calendar;charset=utf-8")
72                    }
73                })
74            }
75            CalendarObjectPropWrapperName::Common(prop) => CalendarObjectPropWrapper::Common(
76                CommonPropertiesExtension::get_prop(self, puri, user, prop)?,
77            ),
78        })
79    }
80
81    fn get_displayname(&self) -> Option<&str> {
82        None
83    }
84
85    fn get_owner(&self) -> Option<&str> {
86        Some(&self.principal)
87    }
88
89    fn get_etag(&self) -> Option<String> {
90        Some(self.object.get_etag())
91    }
92
93    fn get_user_privileges(&self, user: &Principal) -> Result<UserPrivilegeSet, Self::Error> {
94        Ok(UserPrivilegeSet::owner_only(
95            user.is_principal(&self.principal),
96        ))
97    }
98}