matrix_sdk_base/event_cache/store/
traits.rs1use std::{fmt, sync::Arc};
16
17use async_trait::async_trait;
18use matrix_sdk_common::{
19 linked_chunk::{ChunkIdentifier, ChunkIdentifierGenerator, RawChunk, Update},
20 AsyncTraitDeps,
21};
22use ruma::{MxcUri, OwnedEventId, RoomId};
23
24use super::{
25 media::{IgnoreMediaRetentionPolicy, MediaRetentionPolicy},
26 EventCacheStoreError,
27};
28use crate::{
29 event_cache::{Event, Gap},
30 media::MediaRequestParameters,
31};
32
33pub const DEFAULT_CHUNK_CAPACITY: usize = 128;
37
38#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
41#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
42pub trait EventCacheStore: AsyncTraitDeps {
43 type Error: fmt::Debug + Into<EventCacheStoreError>;
45
46 async fn try_take_leased_lock(
48 &self,
49 lease_duration_ms: u32,
50 key: &str,
51 holder: &str,
52 ) -> Result<bool, Self::Error>;
53
54 async fn handle_linked_chunk_updates(
58 &self,
59 room_id: &RoomId,
60 updates: Vec<Update<Event, Gap>>,
61 ) -> Result<(), Self::Error>;
62
63 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error> {
65 self.handle_linked_chunk_updates(room_id, vec![Update::Clear]).await
68 }
69
70 #[doc(hidden)]
73 async fn load_all_chunks(
74 &self,
75 room_id: &RoomId,
76 ) -> Result<Vec<RawChunk<Event, Gap>>, Self::Error>;
77
78 async fn load_last_chunk(
83 &self,
84 room_id: &RoomId,
85 ) -> Result<(Option<RawChunk<Event, Gap>>, ChunkIdentifierGenerator), Self::Error>;
86
87 async fn load_previous_chunk(
93 &self,
94 room_id: &RoomId,
95 before_chunk_identifier: ChunkIdentifier,
96 ) -> Result<Option<RawChunk<Event, Gap>>, Self::Error>;
97
98 async fn clear_all_rooms_chunks(&self) -> Result<(), Self::Error>;
103
104 async fn filter_duplicated_events(
107 &self,
108 room_id: &RoomId,
109 events: Vec<OwnedEventId>,
110 ) -> Result<Vec<OwnedEventId>, Self::Error>;
111
112 async fn add_media_content(
120 &self,
121 request: &MediaRequestParameters,
122 content: Vec<u8>,
123 ignore_policy: IgnoreMediaRetentionPolicy,
124 ) -> Result<(), Self::Error>;
125
126 async fn replace_media_key(
146 &self,
147 from: &MediaRequestParameters,
148 to: &MediaRequestParameters,
149 ) -> Result<(), Self::Error>;
150
151 async fn get_media_content(
157 &self,
158 request: &MediaRequestParameters,
159 ) -> Result<Option<Vec<u8>>, Self::Error>;
160
161 async fn remove_media_content(
167 &self,
168 request: &MediaRequestParameters,
169 ) -> Result<(), Self::Error>;
170
171 async fn get_media_content_for_uri(&self, uri: &MxcUri)
186 -> Result<Option<Vec<u8>>, Self::Error>;
187
188 async fn remove_media_content_for_uri(&self, uri: &MxcUri) -> Result<(), Self::Error>;
198
199 async fn set_media_retention_policy(
206 &self,
207 policy: MediaRetentionPolicy,
208 ) -> Result<(), Self::Error>;
209
210 fn media_retention_policy(&self) -> MediaRetentionPolicy;
212
213 async fn set_ignore_media_retention_policy(
225 &self,
226 request: &MediaRequestParameters,
227 ignore_policy: IgnoreMediaRetentionPolicy,
228 ) -> Result<(), Self::Error>;
229
230 async fn clean_up_media_cache(&self) -> Result<(), Self::Error>;
234}
235
236#[repr(transparent)]
237struct EraseEventCacheStoreError<T>(T);
238
239#[cfg(not(tarpaulin_include))]
240impl<T: fmt::Debug> fmt::Debug for EraseEventCacheStoreError<T> {
241 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
242 self.0.fmt(f)
243 }
244}
245
246#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
247#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
248impl<T: EventCacheStore> EventCacheStore for EraseEventCacheStoreError<T> {
249 type Error = EventCacheStoreError;
250
251 async fn try_take_leased_lock(
252 &self,
253 lease_duration_ms: u32,
254 key: &str,
255 holder: &str,
256 ) -> Result<bool, Self::Error> {
257 self.0.try_take_leased_lock(lease_duration_ms, key, holder).await.map_err(Into::into)
258 }
259
260 async fn handle_linked_chunk_updates(
261 &self,
262 room_id: &RoomId,
263 updates: Vec<Update<Event, Gap>>,
264 ) -> Result<(), Self::Error> {
265 self.0.handle_linked_chunk_updates(room_id, updates).await.map_err(Into::into)
266 }
267
268 async fn load_all_chunks(
269 &self,
270 room_id: &RoomId,
271 ) -> Result<Vec<RawChunk<Event, Gap>>, Self::Error> {
272 self.0.load_all_chunks(room_id).await.map_err(Into::into)
273 }
274
275 async fn load_last_chunk(
276 &self,
277 room_id: &RoomId,
278 ) -> Result<(Option<RawChunk<Event, Gap>>, ChunkIdentifierGenerator), Self::Error> {
279 self.0.load_last_chunk(room_id).await.map_err(Into::into)
280 }
281
282 async fn load_previous_chunk(
283 &self,
284 room_id: &RoomId,
285 before_chunk_identifier: ChunkIdentifier,
286 ) -> Result<Option<RawChunk<Event, Gap>>, Self::Error> {
287 self.0.load_previous_chunk(room_id, before_chunk_identifier).await.map_err(Into::into)
288 }
289
290 async fn clear_all_rooms_chunks(&self) -> Result<(), Self::Error> {
291 self.0.clear_all_rooms_chunks().await.map_err(Into::into)
292 }
293
294 async fn filter_duplicated_events(
295 &self,
296 room_id: &RoomId,
297 events: Vec<OwnedEventId>,
298 ) -> Result<Vec<OwnedEventId>, Self::Error> {
299 self.0.filter_duplicated_events(room_id, events).await.map_err(Into::into)
300 }
301
302 async fn add_media_content(
303 &self,
304 request: &MediaRequestParameters,
305 content: Vec<u8>,
306 ignore_policy: IgnoreMediaRetentionPolicy,
307 ) -> Result<(), Self::Error> {
308 self.0.add_media_content(request, content, ignore_policy).await.map_err(Into::into)
309 }
310
311 async fn replace_media_key(
312 &self,
313 from: &MediaRequestParameters,
314 to: &MediaRequestParameters,
315 ) -> Result<(), Self::Error> {
316 self.0.replace_media_key(from, to).await.map_err(Into::into)
317 }
318
319 async fn get_media_content(
320 &self,
321 request: &MediaRequestParameters,
322 ) -> Result<Option<Vec<u8>>, Self::Error> {
323 self.0.get_media_content(request).await.map_err(Into::into)
324 }
325
326 async fn remove_media_content(
327 &self,
328 request: &MediaRequestParameters,
329 ) -> Result<(), Self::Error> {
330 self.0.remove_media_content(request).await.map_err(Into::into)
331 }
332
333 async fn get_media_content_for_uri(
334 &self,
335 uri: &MxcUri,
336 ) -> Result<Option<Vec<u8>>, Self::Error> {
337 self.0.get_media_content_for_uri(uri).await.map_err(Into::into)
338 }
339
340 async fn remove_media_content_for_uri(&self, uri: &MxcUri) -> Result<(), Self::Error> {
341 self.0.remove_media_content_for_uri(uri).await.map_err(Into::into)
342 }
343
344 async fn set_media_retention_policy(
345 &self,
346 policy: MediaRetentionPolicy,
347 ) -> Result<(), Self::Error> {
348 self.0.set_media_retention_policy(policy).await.map_err(Into::into)
349 }
350
351 fn media_retention_policy(&self) -> MediaRetentionPolicy {
352 self.0.media_retention_policy()
353 }
354
355 async fn set_ignore_media_retention_policy(
356 &self,
357 request: &MediaRequestParameters,
358 ignore_policy: IgnoreMediaRetentionPolicy,
359 ) -> Result<(), Self::Error> {
360 self.0.set_ignore_media_retention_policy(request, ignore_policy).await.map_err(Into::into)
361 }
362
363 async fn clean_up_media_cache(&self) -> Result<(), Self::Error> {
364 self.0.clean_up_media_cache().await.map_err(Into::into)
365 }
366}
367
368pub type DynEventCacheStore = dyn EventCacheStore<Error = EventCacheStoreError>;
370
371pub trait IntoEventCacheStore {
377 #[doc(hidden)]
378 fn into_event_cache_store(self) -> Arc<DynEventCacheStore>;
379}
380
381impl<T> IntoEventCacheStore for T
382where
383 T: EventCacheStore + Sized + 'static,
384{
385 fn into_event_cache_store(self) -> Arc<DynEventCacheStore> {
386 Arc::new(EraseEventCacheStoreError(self))
387 }
388}
389
390impl<T> IntoEventCacheStore for Arc<T>
393where
394 T: EventCacheStore + 'static,
395{
396 fn into_event_cache_store(self) -> Arc<DynEventCacheStore> {
397 let ptr: *const T = Arc::into_raw(self);
398 let ptr_erased = ptr as *const EraseEventCacheStoreError<T>;
399 unsafe { Arc::from_raw(ptr_erased) }
402 }
403}