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::{
20 ChunkIdentifier, ChunkIdentifierGenerator, ChunkMetadata, LinkedChunkId, Position,
21 RawChunk, Update,
22 },
23 AsyncTraitDeps,
24};
25use ruma::{events::relation::RelationType, EventId, MxcUri, OwnedEventId, RoomId};
26
27use super::{
28 media::{IgnoreMediaRetentionPolicy, MediaRetentionPolicy},
29 EventCacheStoreError,
30};
31use crate::{
32 event_cache::{Event, Gap},
33 media::MediaRequestParameters,
34};
35
36pub const DEFAULT_CHUNK_CAPACITY: usize = 128;
40
41#[cfg_attr(target_family = "wasm", async_trait(?Send))]
44#[cfg_attr(not(target_family = "wasm"), async_trait)]
45pub trait EventCacheStore: AsyncTraitDeps {
46 type Error: fmt::Debug + Into<EventCacheStoreError>;
48
49 async fn try_take_leased_lock(
51 &self,
52 lease_duration_ms: u32,
53 key: &str,
54 holder: &str,
55 ) -> Result<bool, Self::Error>;
56
57 async fn handle_linked_chunk_updates(
61 &self,
62 linked_chunk_id: LinkedChunkId<'_>,
63 updates: Vec<Update<Event, Gap>>,
64 ) -> Result<(), Self::Error>;
65
66 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error> {
68 self.handle_linked_chunk_updates(LinkedChunkId::Room(room_id), vec![Update::Clear]).await
71 }
72
73 #[doc(hidden)]
76 async fn load_all_chunks(
77 &self,
78 linked_chunk_id: LinkedChunkId<'_>,
79 ) -> Result<Vec<RawChunk<Event, Gap>>, Self::Error>;
80
81 async fn load_all_chunks_metadata(
86 &self,
87 linked_chunk_id: LinkedChunkId<'_>,
88 ) -> Result<Vec<ChunkMetadata>, Self::Error>;
89
90 async fn load_last_chunk(
95 &self,
96 linked_chunk_id: LinkedChunkId<'_>,
97 ) -> Result<(Option<RawChunk<Event, Gap>>, ChunkIdentifierGenerator), Self::Error>;
98
99 async fn load_previous_chunk(
105 &self,
106 linked_chunk_id: LinkedChunkId<'_>,
107 before_chunk_identifier: ChunkIdentifier,
108 ) -> Result<Option<RawChunk<Event, Gap>>, Self::Error>;
109
110 async fn clear_all_linked_chunks(&self) -> Result<(), Self::Error>;
121
122 async fn filter_duplicated_events(
125 &self,
126 linked_chunk_id: LinkedChunkId<'_>,
127 events: Vec<OwnedEventId>,
128 ) -> Result<Vec<(OwnedEventId, Position)>, Self::Error>;
129
130 async fn find_event(
132 &self,
133 room_id: &RoomId,
134 event_id: &EventId,
135 ) -> Result<Option<Event>, Self::Error>;
136
137 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 save_event(&self, room_id: &RoomId, event: Event) -> Result<(), Self::Error>;
166
167 async fn add_media_content(
175 &self,
176 request: &MediaRequestParameters,
177 content: Vec<u8>,
178 ignore_policy: IgnoreMediaRetentionPolicy,
179 ) -> Result<(), Self::Error>;
180
181 async fn replace_media_key(
201 &self,
202 from: &MediaRequestParameters,
203 to: &MediaRequestParameters,
204 ) -> Result<(), Self::Error>;
205
206 async fn get_media_content(
212 &self,
213 request: &MediaRequestParameters,
214 ) -> Result<Option<Vec<u8>>, Self::Error>;
215
216 async fn remove_media_content(
222 &self,
223 request: &MediaRequestParameters,
224 ) -> Result<(), Self::Error>;
225
226 async fn get_media_content_for_uri(&self, uri: &MxcUri)
241 -> Result<Option<Vec<u8>>, Self::Error>;
242
243 async fn remove_media_content_for_uri(&self, uri: &MxcUri) -> Result<(), Self::Error>;
253
254 async fn set_media_retention_policy(
261 &self,
262 policy: MediaRetentionPolicy,
263 ) -> Result<(), Self::Error>;
264
265 fn media_retention_policy(&self) -> MediaRetentionPolicy;
267
268 async fn set_ignore_media_retention_policy(
280 &self,
281 request: &MediaRequestParameters,
282 ignore_policy: IgnoreMediaRetentionPolicy,
283 ) -> Result<(), Self::Error>;
284
285 async fn clean_up_media_cache(&self) -> Result<(), Self::Error>;
289}
290
291#[repr(transparent)]
292struct EraseEventCacheStoreError<T>(T);
293
294#[cfg(not(tarpaulin_include))]
295impl<T: fmt::Debug> fmt::Debug for EraseEventCacheStoreError<T> {
296 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
297 self.0.fmt(f)
298 }
299}
300
301#[cfg_attr(target_family = "wasm", async_trait(?Send))]
302#[cfg_attr(not(target_family = "wasm"), async_trait)]
303impl<T: EventCacheStore> EventCacheStore for EraseEventCacheStoreError<T> {
304 type Error = EventCacheStoreError;
305
306 async fn try_take_leased_lock(
307 &self,
308 lease_duration_ms: u32,
309 key: &str,
310 holder: &str,
311 ) -> Result<bool, Self::Error> {
312 self.0.try_take_leased_lock(lease_duration_ms, key, holder).await.map_err(Into::into)
313 }
314
315 async fn handle_linked_chunk_updates(
316 &self,
317 linked_chunk_id: LinkedChunkId<'_>,
318 updates: Vec<Update<Event, Gap>>,
319 ) -> Result<(), Self::Error> {
320 self.0.handle_linked_chunk_updates(linked_chunk_id, updates).await.map_err(Into::into)
321 }
322
323 async fn load_all_chunks(
324 &self,
325 linked_chunk_id: LinkedChunkId<'_>,
326 ) -> Result<Vec<RawChunk<Event, Gap>>, Self::Error> {
327 self.0.load_all_chunks(linked_chunk_id).await.map_err(Into::into)
328 }
329
330 async fn load_all_chunks_metadata(
331 &self,
332 linked_chunk_id: LinkedChunkId<'_>,
333 ) -> Result<Vec<ChunkMetadata>, Self::Error> {
334 self.0.load_all_chunks_metadata(linked_chunk_id).await.map_err(Into::into)
335 }
336
337 async fn load_last_chunk(
338 &self,
339 linked_chunk_id: LinkedChunkId<'_>,
340 ) -> Result<(Option<RawChunk<Event, Gap>>, ChunkIdentifierGenerator), Self::Error> {
341 self.0.load_last_chunk(linked_chunk_id).await.map_err(Into::into)
342 }
343
344 async fn load_previous_chunk(
345 &self,
346 linked_chunk_id: LinkedChunkId<'_>,
347 before_chunk_identifier: ChunkIdentifier,
348 ) -> Result<Option<RawChunk<Event, Gap>>, Self::Error> {
349 self.0
350 .load_previous_chunk(linked_chunk_id, before_chunk_identifier)
351 .await
352 .map_err(Into::into)
353 }
354
355 async fn clear_all_linked_chunks(&self) -> Result<(), Self::Error> {
356 self.0.clear_all_linked_chunks().await.map_err(Into::into)
357 }
358
359 async fn filter_duplicated_events(
360 &self,
361 linked_chunk_id: LinkedChunkId<'_>,
362 events: Vec<OwnedEventId>,
363 ) -> Result<Vec<(OwnedEventId, Position)>, Self::Error> {
364 self.0.filter_duplicated_events(linked_chunk_id, events).await.map_err(Into::into)
365 }
366
367 async fn find_event(
368 &self,
369 room_id: &RoomId,
370 event_id: &EventId,
371 ) -> Result<Option<Event>, Self::Error> {
372 self.0.find_event(room_id, event_id).await.map_err(Into::into)
373 }
374
375 async fn find_event_relations(
376 &self,
377 room_id: &RoomId,
378 event_id: &EventId,
379 filter: Option<&[RelationType]>,
380 ) -> Result<Vec<(Event, Option<Position>)>, Self::Error> {
381 self.0.find_event_relations(room_id, event_id, filter).await.map_err(Into::into)
382 }
383
384 async fn save_event(&self, room_id: &RoomId, event: Event) -> Result<(), Self::Error> {
385 self.0.save_event(room_id, event).await.map_err(Into::into)
386 }
387
388 async fn add_media_content(
389 &self,
390 request: &MediaRequestParameters,
391 content: Vec<u8>,
392 ignore_policy: IgnoreMediaRetentionPolicy,
393 ) -> Result<(), Self::Error> {
394 self.0.add_media_content(request, content, ignore_policy).await.map_err(Into::into)
395 }
396
397 async fn replace_media_key(
398 &self,
399 from: &MediaRequestParameters,
400 to: &MediaRequestParameters,
401 ) -> Result<(), Self::Error> {
402 self.0.replace_media_key(from, to).await.map_err(Into::into)
403 }
404
405 async fn get_media_content(
406 &self,
407 request: &MediaRequestParameters,
408 ) -> Result<Option<Vec<u8>>, Self::Error> {
409 self.0.get_media_content(request).await.map_err(Into::into)
410 }
411
412 async fn remove_media_content(
413 &self,
414 request: &MediaRequestParameters,
415 ) -> Result<(), Self::Error> {
416 self.0.remove_media_content(request).await.map_err(Into::into)
417 }
418
419 async fn get_media_content_for_uri(
420 &self,
421 uri: &MxcUri,
422 ) -> Result<Option<Vec<u8>>, Self::Error> {
423 self.0.get_media_content_for_uri(uri).await.map_err(Into::into)
424 }
425
426 async fn remove_media_content_for_uri(&self, uri: &MxcUri) -> Result<(), Self::Error> {
427 self.0.remove_media_content_for_uri(uri).await.map_err(Into::into)
428 }
429
430 async fn set_media_retention_policy(
431 &self,
432 policy: MediaRetentionPolicy,
433 ) -> Result<(), Self::Error> {
434 self.0.set_media_retention_policy(policy).await.map_err(Into::into)
435 }
436
437 fn media_retention_policy(&self) -> MediaRetentionPolicy {
438 self.0.media_retention_policy()
439 }
440
441 async fn set_ignore_media_retention_policy(
442 &self,
443 request: &MediaRequestParameters,
444 ignore_policy: IgnoreMediaRetentionPolicy,
445 ) -> Result<(), Self::Error> {
446 self.0.set_ignore_media_retention_policy(request, ignore_policy).await.map_err(Into::into)
447 }
448
449 async fn clean_up_media_cache(&self) -> Result<(), Self::Error> {
450 self.0.clean_up_media_cache().await.map_err(Into::into)
451 }
452}
453
454pub type DynEventCacheStore = dyn EventCacheStore<Error = EventCacheStoreError>;
456
457pub trait IntoEventCacheStore {
463 #[doc(hidden)]
464 fn into_event_cache_store(self) -> Arc<DynEventCacheStore>;
465}
466
467impl<T> IntoEventCacheStore for T
468where
469 T: EventCacheStore + Sized + 'static,
470{
471 fn into_event_cache_store(self) -> Arc<DynEventCacheStore> {
472 Arc::new(EraseEventCacheStoreError(self))
473 }
474}
475
476impl<T> IntoEventCacheStore for Arc<T>
479where
480 T: EventCacheStore + 'static,
481{
482 fn into_event_cache_store(self) -> Arc<DynEventCacheStore> {
483 let ptr: *const T = Arc::into_raw(self);
484 let ptr_erased = ptr as *const EraseEventCacheStoreError<T>;
485 unsafe { Arc::from_raw(ptr_erased) }
488 }
489}