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}