matrix_sdk_base/event_cache/store/
traits.rs1use std::{fmt, sync::Arc};
16
17use async_trait::async_trait;
18use matrix_sdk_common::{
19 AsyncTraitDeps,
20 linked_chunk::{
21 ChunkIdentifier, ChunkIdentifierGenerator, ChunkMetadata, LinkedChunkId, Position,
22 RawChunk, Update,
23 },
24};
25use ruma::{EventId, OwnedEventId, RoomId, events::relation::RelationType};
26
27use super::EventCacheStoreError;
28use crate::event_cache::{Event, Gap};
29
30pub const DEFAULT_CHUNK_CAPACITY: usize = 128;
34
35#[cfg_attr(target_family = "wasm", async_trait(?Send))]
38#[cfg_attr(not(target_family = "wasm"), async_trait)]
39pub trait EventCacheStore: AsyncTraitDeps {
40 type Error: fmt::Debug + Into<EventCacheStoreError>;
42
43 async fn try_take_leased_lock(
45 &self,
46 lease_duration_ms: u32,
47 key: &str,
48 holder: &str,
49 ) -> Result<bool, Self::Error>;
50
51 async fn handle_linked_chunk_updates(
55 &self,
56 linked_chunk_id: LinkedChunkId<'_>,
57 updates: Vec<Update<Event, Gap>>,
58 ) -> Result<(), Self::Error>;
59
60 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error> {
62 self.handle_linked_chunk_updates(LinkedChunkId::Room(room_id), vec![Update::Clear]).await
65 }
66
67 #[doc(hidden)]
70 async fn load_all_chunks(
71 &self,
72 linked_chunk_id: LinkedChunkId<'_>,
73 ) -> Result<Vec<RawChunk<Event, Gap>>, Self::Error>;
74
75 async fn load_all_chunks_metadata(
80 &self,
81 linked_chunk_id: LinkedChunkId<'_>,
82 ) -> Result<Vec<ChunkMetadata>, Self::Error>;
83
84 async fn load_last_chunk(
89 &self,
90 linked_chunk_id: LinkedChunkId<'_>,
91 ) -> Result<(Option<RawChunk<Event, Gap>>, ChunkIdentifierGenerator), Self::Error>;
92
93 async fn load_previous_chunk(
99 &self,
100 linked_chunk_id: LinkedChunkId<'_>,
101 before_chunk_identifier: ChunkIdentifier,
102 ) -> Result<Option<RawChunk<Event, Gap>>, Self::Error>;
103
104 async fn clear_all_linked_chunks(&self) -> Result<(), Self::Error>;
115
116 async fn filter_duplicated_events(
119 &self,
120 linked_chunk_id: LinkedChunkId<'_>,
121 events: Vec<OwnedEventId>,
122 ) -> Result<Vec<(OwnedEventId, Position)>, Self::Error>;
123
124 async fn find_event(
129 &self,
130 room_id: &RoomId,
131 event_id: &EventId,
132 ) -> Result<Option<Event>, Self::Error>;
133
134 async fn find_event_relations(
151 &self,
152 room_id: &RoomId,
153 event_id: &EventId,
154 filter: Option<&[RelationType]>,
155 ) -> Result<Vec<(Event, Option<Position>)>, Self::Error>;
156
157 async fn get_room_events(&self, room_id: &RoomId) -> Result<Vec<Event>, Self::Error>;
162
163 async fn save_event(&self, room_id: &RoomId, event: Event) -> Result<(), Self::Error>;
172}
173
174#[repr(transparent)]
175struct EraseEventCacheStoreError<T>(T);
176
177#[cfg(not(tarpaulin_include))]
178impl<T: fmt::Debug> fmt::Debug for EraseEventCacheStoreError<T> {
179 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
180 self.0.fmt(f)
181 }
182}
183
184#[cfg_attr(target_family = "wasm", async_trait(?Send))]
185#[cfg_attr(not(target_family = "wasm"), async_trait)]
186impl<T: EventCacheStore> EventCacheStore for EraseEventCacheStoreError<T> {
187 type Error = EventCacheStoreError;
188
189 async fn try_take_leased_lock(
190 &self,
191 lease_duration_ms: u32,
192 key: &str,
193 holder: &str,
194 ) -> Result<bool, Self::Error> {
195 self.0.try_take_leased_lock(lease_duration_ms, key, holder).await.map_err(Into::into)
196 }
197
198 async fn handle_linked_chunk_updates(
199 &self,
200 linked_chunk_id: LinkedChunkId<'_>,
201 updates: Vec<Update<Event, Gap>>,
202 ) -> Result<(), Self::Error> {
203 self.0.handle_linked_chunk_updates(linked_chunk_id, updates).await.map_err(Into::into)
204 }
205
206 async fn load_all_chunks(
207 &self,
208 linked_chunk_id: LinkedChunkId<'_>,
209 ) -> Result<Vec<RawChunk<Event, Gap>>, Self::Error> {
210 self.0.load_all_chunks(linked_chunk_id).await.map_err(Into::into)
211 }
212
213 async fn load_all_chunks_metadata(
214 &self,
215 linked_chunk_id: LinkedChunkId<'_>,
216 ) -> Result<Vec<ChunkMetadata>, Self::Error> {
217 self.0.load_all_chunks_metadata(linked_chunk_id).await.map_err(Into::into)
218 }
219
220 async fn load_last_chunk(
221 &self,
222 linked_chunk_id: LinkedChunkId<'_>,
223 ) -> Result<(Option<RawChunk<Event, Gap>>, ChunkIdentifierGenerator), Self::Error> {
224 self.0.load_last_chunk(linked_chunk_id).await.map_err(Into::into)
225 }
226
227 async fn load_previous_chunk(
228 &self,
229 linked_chunk_id: LinkedChunkId<'_>,
230 before_chunk_identifier: ChunkIdentifier,
231 ) -> Result<Option<RawChunk<Event, Gap>>, Self::Error> {
232 self.0
233 .load_previous_chunk(linked_chunk_id, before_chunk_identifier)
234 .await
235 .map_err(Into::into)
236 }
237
238 async fn clear_all_linked_chunks(&self) -> Result<(), Self::Error> {
239 self.0.clear_all_linked_chunks().await.map_err(Into::into)
240 }
241
242 async fn filter_duplicated_events(
243 &self,
244 linked_chunk_id: LinkedChunkId<'_>,
245 events: Vec<OwnedEventId>,
246 ) -> Result<Vec<(OwnedEventId, Position)>, Self::Error> {
247 self.0.filter_duplicated_events(linked_chunk_id, events).await.map_err(Into::into)
248 }
249
250 async fn find_event(
251 &self,
252 room_id: &RoomId,
253 event_id: &EventId,
254 ) -> Result<Option<Event>, Self::Error> {
255 self.0.find_event(room_id, event_id).await.map_err(Into::into)
256 }
257
258 async fn find_event_relations(
259 &self,
260 room_id: &RoomId,
261 event_id: &EventId,
262 filter: Option<&[RelationType]>,
263 ) -> Result<Vec<(Event, Option<Position>)>, Self::Error> {
264 self.0.find_event_relations(room_id, event_id, filter).await.map_err(Into::into)
265 }
266
267 async fn get_room_events(&self, room_id: &RoomId) -> Result<Vec<Event>, Self::Error> {
268 self.0.get_room_events(room_id).await.map_err(Into::into)
269 }
270
271 async fn save_event(&self, room_id: &RoomId, event: Event) -> Result<(), Self::Error> {
272 self.0.save_event(room_id, event).await.map_err(Into::into)
273 }
274}
275
276pub type DynEventCacheStore = dyn EventCacheStore<Error = EventCacheStoreError>;
278
279pub trait IntoEventCacheStore {
285 #[doc(hidden)]
286 fn into_event_cache_store(self) -> Arc<DynEventCacheStore>;
287}
288
289impl IntoEventCacheStore for Arc<DynEventCacheStore> {
290 fn into_event_cache_store(self) -> Arc<DynEventCacheStore> {
291 self
292 }
293}
294
295impl<T> IntoEventCacheStore for T
296where
297 T: EventCacheStore + Sized + 'static,
298{
299 fn into_event_cache_store(self) -> Arc<DynEventCacheStore> {
300 Arc::new(EraseEventCacheStoreError(self))
301 }
302}
303
304impl<T> IntoEventCacheStore for Arc<T>
307where
308 T: EventCacheStore + 'static,
309{
310 fn into_event_cache_store(self) -> Arc<DynEventCacheStore> {
311 let ptr: *const T = Arc::into_raw(self);
312 let ptr_erased = ptr as *const EraseEventCacheStoreError<T>;
313 unsafe { Arc::from_raw(ptr_erased) }
316 }
317}