Skip to main content

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