rustical_store/
combined_calendar_store.rs

1use crate::{Calendar, CalendarStore, calendar_store::CalendarQuery};
2use async_trait::async_trait;
3use rustical_ical::CalendarObject;
4use std::{collections::HashMap, sync::Arc};
5
6pub trait PrefixedCalendarStore: CalendarStore {
7    const PREFIX: &'static str;
8}
9
10#[derive(Clone)]
11pub struct CombinedCalendarStore {
12    stores: HashMap<&'static str, Arc<dyn CalendarStore>>,
13    default: Arc<dyn CalendarStore>,
14}
15
16impl CombinedCalendarStore {
17    pub fn new(default: Arc<dyn CalendarStore>) -> Self {
18        Self {
19            stores: HashMap::new(),
20            default,
21        }
22    }
23
24    #[must_use]
25    pub fn with_store<CS: PrefixedCalendarStore>(mut self, store: Arc<CS>) -> Self {
26        let store: Arc<dyn CalendarStore> = store;
27        self.stores.insert(CS::PREFIX, store);
28        self
29    }
30
31    fn store_for_id(&self, id: &str) -> Arc<dyn CalendarStore> {
32        self.stores
33            .iter()
34            .find(|&(prefix, _store)| id.starts_with(prefix))
35            .map_or_else(|| self.default.clone(), |(_prefix, store)| store.clone())
36    }
37}
38
39#[async_trait]
40impl CalendarStore for CombinedCalendarStore {
41    #[inline]
42    async fn get_calendar(
43        &self,
44        principal: &str,
45        id: &str,
46        show_deleted: bool,
47    ) -> Result<crate::Calendar, crate::Error> {
48        self.store_for_id(id)
49            .get_calendar(principal, id, show_deleted)
50            .await
51    }
52
53    async fn update_calendar(
54        &self,
55        principal: &str,
56        id: &str,
57        calendar: Calendar,
58    ) -> Result<(), crate::Error> {
59        self.store_for_id(id)
60            .update_calendar(principal, id, calendar)
61            .await
62    }
63
64    async fn insert_calendar(&self, calendar: crate::Calendar) -> Result<(), crate::Error> {
65        self.store_for_id(&calendar.id)
66            .insert_calendar(calendar)
67            .await
68    }
69
70    async fn delete_calendar(
71        &self,
72        principal: &str,
73        name: &str,
74        use_trashbin: bool,
75    ) -> Result<(), crate::Error> {
76        self.store_for_id(name)
77            .delete_calendar(principal, name, use_trashbin)
78            .await
79    }
80
81    async fn restore_calendar(&self, principal: &str, name: &str) -> Result<(), crate::Error> {
82        self.store_for_id(name)
83            .restore_calendar(principal, name)
84            .await
85    }
86
87    async fn sync_changes(
88        &self,
89        principal: &str,
90        cal_id: &str,
91        synctoken: i64,
92    ) -> Result<(Vec<(String, CalendarObject)>, Vec<String>, i64), crate::Error> {
93        self.store_for_id(cal_id)
94            .sync_changes(principal, cal_id, synctoken)
95            .await
96    }
97
98    async fn import_calendar(
99        &self,
100        calendar: crate::Calendar,
101        objects: Vec<CalendarObject>,
102        merge_existing: bool,
103    ) -> Result<(), crate::Error> {
104        self.store_for_id(&calendar.id)
105            .import_calendar(calendar, objects, merge_existing)
106            .await
107    }
108
109    async fn calendar_query(
110        &self,
111        principal: &str,
112        cal_id: &str,
113        query: CalendarQuery,
114    ) -> Result<Vec<(String, CalendarObject)>, crate::Error> {
115        self.store_for_id(cal_id)
116            .calendar_query(principal, cal_id, query)
117            .await
118    }
119
120    async fn restore_object(
121        &self,
122        principal: &str,
123        cal_id: &str,
124        object_id: &str,
125    ) -> Result<(), crate::Error> {
126        self.store_for_id(cal_id)
127            .restore_object(principal, cal_id, object_id)
128            .await
129    }
130
131    async fn calendar_metadata(
132        &self,
133        principal: &str,
134        cal_id: &str,
135    ) -> Result<crate::CollectionMetadata, crate::Error> {
136        self.store_for_id(cal_id)
137            .calendar_metadata(principal, cal_id)
138            .await
139    }
140
141    async fn get_objects(
142        &self,
143        principal: &str,
144        cal_id: &str,
145    ) -> Result<Vec<(String, CalendarObject)>, crate::Error> {
146        self.store_for_id(cal_id)
147            .get_objects(principal, cal_id)
148            .await
149    }
150
151    async fn put_objects(
152        &self,
153        principal: &str,
154        cal_id: &str,
155        objects: Vec<(String, CalendarObject)>,
156        overwrite: bool,
157    ) -> Result<(), crate::Error> {
158        self.store_for_id(cal_id)
159            .put_objects(principal, cal_id, objects, overwrite)
160            .await
161    }
162
163    async fn delete_object(
164        &self,
165        principal: &str,
166        cal_id: &str,
167        object_id: &str,
168        use_trashbin: bool,
169    ) -> Result<(), crate::Error> {
170        self.store_for_id(cal_id)
171            .delete_object(principal, cal_id, object_id, use_trashbin)
172            .await
173    }
174
175    async fn get_object(
176        &self,
177        principal: &str,
178        cal_id: &str,
179        object_id: &str,
180        show_deleted: bool,
181    ) -> Result<rustical_ical::CalendarObject, crate::Error> {
182        self.store_for_id(cal_id)
183            .get_object(principal, cal_id, object_id, show_deleted)
184            .await
185    }
186
187    async fn get_calendars(&self, principal: &str) -> Result<Vec<crate::Calendar>, crate::Error> {
188        let mut calendars = self.default.get_calendars(principal).await?;
189        for store in self.stores.values() {
190            calendars.extend(store.get_calendars(principal).await?);
191        }
192        Ok(calendars)
193    }
194
195    async fn get_deleted_calendars(
196        &self,
197        principal: &str,
198    ) -> Result<Vec<crate::Calendar>, crate::Error> {
199        let mut calendars = self.default.get_deleted_calendars(principal).await?;
200        for store in self.stores.values() {
201            calendars.extend(store.get_deleted_calendars(principal).await?);
202        }
203        Ok(calendars)
204    }
205
206    fn is_read_only(&self, cal_id: &str) -> bool {
207        self.store_for_id(cal_id).is_read_only(cal_id)
208    }
209}