1use std::{
16 borrow::Borrow,
17 collections::{BTreeMap, BTreeSet, HashMap},
18 fmt,
19 ops::Deref,
20 sync::Arc,
21};
22
23use as_variant::as_variant;
24use async_trait::async_trait;
25use growable_bloom_filter::GrowableBloom;
26use matrix_sdk_common::{AsyncTraitDeps, ttl::TtlValue};
27use ruma::{
28 EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedMxcUri, OwnedRoomId,
29 OwnedTransactionId, OwnedUserId, RoomId, TransactionId, UserId,
30 api::{
31 MatrixVersion, SupportedVersions,
32 client::{
33 discovery::{
34 discover_homeserver::{self, HomeserverInfo, IdentityServerInfo, TileServerInfo},
35 get_capabilities::v3::Capabilities,
36 },
37 rtc::RtcTransport,
38 },
39 },
40 events::{
41 AnyGlobalAccountDataEvent, AnyRoomAccountDataEvent, EmptyStateKey, GlobalAccountDataEvent,
42 GlobalAccountDataEventContent, GlobalAccountDataEventType, RedactContent,
43 RedactedStateEventContent, RoomAccountDataEvent, RoomAccountDataEventContent,
44 RoomAccountDataEventType, StateEventType, StaticEventContent, StaticStateEventContent,
45 presence::PresenceEvent,
46 receipt::{Receipt, ReceiptThread, ReceiptType},
47 },
48 profile::UserProfile,
49 serde::Raw,
50};
51use serde::{Deserialize, Serialize};
52use thiserror::Error;
53use tokio::sync::{Mutex, MutexGuard};
54
55use super::{
56 ChildTransactionId, DependentQueuedRequest, DependentQueuedRequestKind, QueueWedgeError,
57 QueuedRequest, QueuedRequestKind, RoomLoadSettings, StateChanges, StoreError,
58 send_queue::SentRequestKey,
59};
60use crate::{
61 MinimalRoomMemberEvent, RoomInfo, RoomMemberships,
62 deserialized_responses::{
63 DisplayName, RawAnySyncOrStrippedState, RawMemberEvent, RawSyncOrStrippedState,
64 },
65 store::StoredThreadSubscription,
66};
67
68#[cfg_attr(target_family = "wasm", async_trait(?Send))]
71#[cfg_attr(not(target_family = "wasm"), async_trait)]
72pub trait StateStore: AsyncTraitDeps {
73 type Error: fmt::Debug + Into<StoreError> + From<serde_json::Error>;
75
76 async fn get_kv_data(
82 &self,
83 key: StateStoreDataKey<'_>,
84 ) -> Result<Option<StateStoreDataValue>, Self::Error>;
85
86 async fn set_kv_data(
96 &self,
97 key: StateStoreDataKey<'_>,
98 value: StateStoreDataValue,
99 ) -> Result<(), Self::Error>;
100
101 async fn remove_kv_data(&self, key: StateStoreDataKey<'_>) -> Result<(), Self::Error>;
107
108 async fn save_changes(&self, changes: &StateChanges) -> Result<(), Self::Error>;
110
111 async fn get_presence_event(
118 &self,
119 user_id: &UserId,
120 ) -> Result<Option<Raw<PresenceEvent>>, Self::Error>;
121
122 async fn get_presence_events(
128 &self,
129 user_ids: &[OwnedUserId],
130 ) -> Result<Vec<Raw<PresenceEvent>>, Self::Error>;
131
132 async fn get_state_event(
140 &self,
141 room_id: &RoomId,
142 event_type: StateEventType,
143 state_key: &str,
144 ) -> Result<Option<RawAnySyncOrStrippedState>, Self::Error>;
145
146 async fn get_state_events(
154 &self,
155 room_id: &RoomId,
156 event_type: StateEventType,
157 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error>;
158
159 async fn get_state_events_for_keys(
170 &self,
171 room_id: &RoomId,
172 event_type: StateEventType,
173 state_keys: &[&str],
174 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error>;
175
176 async fn get_profile(
184 &self,
185 room_id: &RoomId,
186 user_id: &UserId,
187 ) -> Result<Option<MinimalRoomMemberEvent>, Self::Error>;
188
189 async fn get_profiles<'a>(
197 &self,
198 room_id: &RoomId,
199 user_ids: &'a [OwnedUserId],
200 ) -> Result<BTreeMap<&'a UserId, MinimalRoomMemberEvent>, Self::Error>;
201
202 async fn get_user_ids(
205 &self,
206 room_id: &RoomId,
207 memberships: RoomMemberships,
208 ) -> Result<Vec<OwnedUserId>, Self::Error>;
209
210 async fn get_room_infos(
212 &self,
213 room_load_settings: &RoomLoadSettings,
214 ) -> Result<Vec<RoomInfo>, Self::Error>;
215
216 async fn get_users_with_display_name(
225 &self,
226 room_id: &RoomId,
227 display_name: &DisplayName,
228 ) -> Result<BTreeSet<OwnedUserId>, Self::Error>;
229
230 async fn get_users_with_display_names<'a>(
238 &self,
239 room_id: &RoomId,
240 display_names: &'a [DisplayName],
241 ) -> Result<HashMap<&'a DisplayName, BTreeSet<OwnedUserId>>, Self::Error>;
242
243 async fn get_account_data_event(
249 &self,
250 event_type: GlobalAccountDataEventType,
251 ) -> Result<Option<Raw<AnyGlobalAccountDataEvent>>, Self::Error>;
252
253 async fn get_room_account_data_event(
263 &self,
264 room_id: &RoomId,
265 event_type: RoomAccountDataEventType,
266 ) -> Result<Option<Raw<AnyRoomAccountDataEvent>>, Self::Error>;
267
268 async fn get_user_room_receipt_event(
281 &self,
282 room_id: &RoomId,
283 receipt_type: ReceiptType,
284 receipt_thread: &ReceiptThread,
285 user_id: &UserId,
286 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error>;
287
288 async fn get_event_room_receipt_events(
302 &self,
303 room_id: &RoomId,
304 receipt_type: ReceiptType,
305 receipt_thread: &ReceiptThread,
306 event_id: &EventId,
307 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error>;
308
309 async fn get_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error>;
315
316 async fn set_custom_value(
325 &self,
326 key: &[u8],
327 value: Vec<u8>,
328 ) -> Result<Option<Vec<u8>>, Self::Error>;
329
330 async fn set_custom_value_no_read(
344 &self,
345 key: &[u8],
346 value: Vec<u8>,
347 ) -> Result<(), Self::Error> {
348 self.set_custom_value(key, value).await.map(|_| ())
349 }
350
351 async fn remove_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error>;
357
358 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error>;
364
365 async fn save_send_queue_request(
375 &self,
376 room_id: &RoomId,
377 transaction_id: OwnedTransactionId,
378 created_at: MilliSecondsSinceUnixEpoch,
379 request: QueuedRequestKind,
380 priority: usize,
381 ) -> Result<(), Self::Error>;
382
383 async fn update_send_queue_request(
395 &self,
396 room_id: &RoomId,
397 transaction_id: &TransactionId,
398 content: QueuedRequestKind,
399 ) -> Result<bool, Self::Error>;
400
401 async fn remove_send_queue_request(
407 &self,
408 room_id: &RoomId,
409 transaction_id: &TransactionId,
410 ) -> Result<bool, Self::Error>;
411
412 async fn load_send_queue_requests(
418 &self,
419 room_id: &RoomId,
420 ) -> Result<Vec<QueuedRequest>, Self::Error>;
421
422 async fn update_send_queue_request_status(
425 &self,
426 room_id: &RoomId,
427 transaction_id: &TransactionId,
428 error: Option<QueueWedgeError>,
429 ) -> Result<(), Self::Error>;
430
431 async fn load_rooms_with_unsent_requests(&self) -> Result<Vec<OwnedRoomId>, Self::Error>;
433
434 async fn save_dependent_queued_request(
437 &self,
438 room_id: &RoomId,
439 parent_txn_id: &TransactionId,
440 own_txn_id: ChildTransactionId,
441 created_at: MilliSecondsSinceUnixEpoch,
442 content: DependentQueuedRequestKind,
443 ) -> Result<(), Self::Error>;
444
445 async fn mark_dependent_queued_requests_as_ready(
454 &self,
455 room_id: &RoomId,
456 parent_txn_id: &TransactionId,
457 sent_parent_key: SentRequestKey,
458 ) -> Result<usize, Self::Error>;
459
460 async fn update_dependent_queued_request(
464 &self,
465 room_id: &RoomId,
466 own_transaction_id: &ChildTransactionId,
467 new_content: DependentQueuedRequestKind,
468 ) -> Result<bool, Self::Error>;
469
470 async fn remove_dependent_queued_request(
475 &self,
476 room: &RoomId,
477 own_txn_id: &ChildTransactionId,
478 ) -> Result<bool, Self::Error>;
479
480 async fn load_dependent_queued_requests(
486 &self,
487 room: &RoomId,
488 ) -> Result<Vec<DependentQueuedRequest>, Self::Error>;
489
490 async fn upsert_thread_subscriptions(
500 &self,
501 updates: Vec<(&RoomId, &EventId, StoredThreadSubscription)>,
502 ) -> Result<(), Self::Error>;
503
504 async fn remove_thread_subscription(
508 &self,
509 room: &RoomId,
510 thread_id: &EventId,
511 ) -> Result<(), Self::Error>;
512
513 async fn load_thread_subscription(
517 &self,
518 room: &RoomId,
519 thread_id: &EventId,
520 ) -> Result<Option<StoredThreadSubscription>, Self::Error>;
521
522 async fn get_global_profile(
531 &self,
532 user_id: &UserId,
533 ) -> Result<Option<UserProfile>, Self::Error>;
534
535 async fn get_global_profiles<'a>(
540 &self,
541 user_ids: &'a [OwnedUserId],
542 ) -> Result<BTreeMap<&'a UserId, UserProfile>, Self::Error>;
543
544 async fn close(&self) -> Result<(), Self::Error>;
550
551 async fn reopen(&self) -> Result<(), Self::Error>;
554
555 #[doc(hidden)]
561 async fn optimize(&self) -> Result<(), Self::Error>;
562
563 async fn get_size(&self) -> Result<Option<usize>, Self::Error>;
565}
566
567#[cfg_attr(target_family = "wasm", async_trait(?Send))]
568#[cfg_attr(not(target_family = "wasm"), async_trait)]
569impl<T: StateStore> StateStore for &T {
570 type Error = T::Error;
571
572 async fn get_kv_data(
573 &self,
574 key: StateStoreDataKey<'_>,
575 ) -> Result<Option<StateStoreDataValue>, Self::Error> {
576 (*self).get_kv_data(key).await
577 }
578
579 async fn set_kv_data(
580 &self,
581 key: StateStoreDataKey<'_>,
582 value: StateStoreDataValue,
583 ) -> Result<(), Self::Error> {
584 (*self).set_kv_data(key, value).await
585 }
586
587 async fn remove_kv_data(&self, key: StateStoreDataKey<'_>) -> Result<(), Self::Error> {
588 (*self).remove_kv_data(key).await
589 }
590
591 async fn save_changes(&self, changes: &StateChanges) -> Result<(), Self::Error> {
592 (*self).save_changes(changes).await
593 }
594
595 async fn get_presence_event(
596 &self,
597 user_id: &UserId,
598 ) -> Result<Option<Raw<PresenceEvent>>, Self::Error> {
599 (*self).get_presence_event(user_id).await
600 }
601
602 async fn get_presence_events(
603 &self,
604 user_ids: &[OwnedUserId],
605 ) -> Result<Vec<Raw<PresenceEvent>>, Self::Error> {
606 (*self).get_presence_events(user_ids).await
607 }
608
609 async fn get_state_event(
610 &self,
611 room_id: &RoomId,
612 event_type: StateEventType,
613 state_key: &str,
614 ) -> Result<Option<RawAnySyncOrStrippedState>, Self::Error> {
615 (*self).get_state_event(room_id, event_type, state_key).await
616 }
617
618 async fn get_state_events(
619 &self,
620 room_id: &RoomId,
621 event_type: StateEventType,
622 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
623 (*self).get_state_events(room_id, event_type).await
624 }
625
626 async fn get_state_events_for_keys(
627 &self,
628 room_id: &RoomId,
629 event_type: StateEventType,
630 state_keys: &[&str],
631 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
632 (*self).get_state_events_for_keys(room_id, event_type, state_keys).await
633 }
634
635 async fn get_profile(
636 &self,
637 room_id: &RoomId,
638 user_id: &UserId,
639 ) -> Result<Option<MinimalRoomMemberEvent>, Self::Error> {
640 (*self).get_profile(room_id, user_id).await
641 }
642
643 async fn get_profiles<'a>(
644 &self,
645 room_id: &RoomId,
646 user_ids: &'a [OwnedUserId],
647 ) -> Result<BTreeMap<&'a UserId, MinimalRoomMemberEvent>, Self::Error> {
648 (*self).get_profiles(room_id, user_ids).await
649 }
650
651 async fn get_user_ids(
652 &self,
653 room_id: &RoomId,
654 memberships: RoomMemberships,
655 ) -> Result<Vec<OwnedUserId>, Self::Error> {
656 (*self).get_user_ids(room_id, memberships).await
657 }
658
659 async fn get_room_infos(
660 &self,
661 room_load_settings: &RoomLoadSettings,
662 ) -> Result<Vec<RoomInfo>, Self::Error> {
663 (*self).get_room_infos(room_load_settings).await
664 }
665
666 async fn get_users_with_display_name(
667 &self,
668 room_id: &RoomId,
669 display_name: &DisplayName,
670 ) -> Result<BTreeSet<OwnedUserId>, Self::Error> {
671 (*self).get_users_with_display_name(room_id, display_name).await
672 }
673
674 async fn get_users_with_display_names<'a>(
675 &self,
676 room_id: &RoomId,
677 display_names: &'a [DisplayName],
678 ) -> Result<HashMap<&'a DisplayName, BTreeSet<OwnedUserId>>, Self::Error> {
679 (*self).get_users_with_display_names(room_id, display_names).await
680 }
681
682 async fn get_account_data_event(
683 &self,
684 event_type: GlobalAccountDataEventType,
685 ) -> Result<Option<Raw<AnyGlobalAccountDataEvent>>, Self::Error> {
686 (*self).get_account_data_event(event_type).await
687 }
688
689 async fn get_room_account_data_event(
690 &self,
691 room_id: &RoomId,
692 event_type: RoomAccountDataEventType,
693 ) -> Result<Option<Raw<AnyRoomAccountDataEvent>>, Self::Error> {
694 (*self).get_room_account_data_event(room_id, event_type).await
695 }
696
697 async fn get_user_room_receipt_event(
698 &self,
699 room_id: &RoomId,
700 receipt_type: ReceiptType,
701 receipt_thread: &ReceiptThread,
702 user_id: &UserId,
703 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error> {
704 (*self).get_user_room_receipt_event(room_id, receipt_type, receipt_thread, user_id).await
705 }
706
707 async fn get_event_room_receipt_events(
708 &self,
709 room_id: &RoomId,
710 receipt_type: ReceiptType,
711 receipt_thread: &ReceiptThread,
712 event_id: &EventId,
713 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error> {
714 (*self).get_event_room_receipt_events(room_id, receipt_type, receipt_thread, event_id).await
715 }
716
717 async fn get_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
718 (*self).get_custom_value(key).await
719 }
720
721 async fn set_custom_value(
722 &self,
723 key: &[u8],
724 value: Vec<u8>,
725 ) -> Result<Option<Vec<u8>>, Self::Error> {
726 (*self).set_custom_value(key, value).await
727 }
728
729 async fn remove_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
730 (*self).remove_custom_value(key).await
731 }
732
733 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error> {
734 (*self).remove_room(room_id).await
735 }
736
737 async fn save_send_queue_request(
738 &self,
739 room_id: &RoomId,
740 transaction_id: OwnedTransactionId,
741 created_at: MilliSecondsSinceUnixEpoch,
742 request: QueuedRequestKind,
743 priority: usize,
744 ) -> Result<(), Self::Error> {
745 (*self)
746 .save_send_queue_request(room_id, transaction_id, created_at, request, priority)
747 .await
748 }
749
750 async fn update_send_queue_request(
751 &self,
752 room_id: &RoomId,
753 transaction_id: &TransactionId,
754 content: QueuedRequestKind,
755 ) -> Result<bool, Self::Error> {
756 (*self).update_send_queue_request(room_id, transaction_id, content).await
757 }
758
759 async fn remove_send_queue_request(
760 &self,
761 room_id: &RoomId,
762 transaction_id: &TransactionId,
763 ) -> Result<bool, Self::Error> {
764 (*self).remove_send_queue_request(room_id, transaction_id).await
765 }
766
767 async fn load_send_queue_requests(
768 &self,
769 room_id: &RoomId,
770 ) -> Result<Vec<QueuedRequest>, Self::Error> {
771 (*self).load_send_queue_requests(room_id).await
772 }
773
774 async fn update_send_queue_request_status(
775 &self,
776 room_id: &RoomId,
777 transaction_id: &TransactionId,
778 error: Option<QueueWedgeError>,
779 ) -> Result<(), Self::Error> {
780 (*self).update_send_queue_request_status(room_id, transaction_id, error).await
781 }
782
783 async fn load_rooms_with_unsent_requests(&self) -> Result<Vec<OwnedRoomId>, Self::Error> {
784 (*self).load_rooms_with_unsent_requests().await
785 }
786
787 async fn save_dependent_queued_request(
788 &self,
789 room_id: &RoomId,
790 parent_txn_id: &TransactionId,
791 own_txn_id: ChildTransactionId,
792 created_at: MilliSecondsSinceUnixEpoch,
793 content: DependentQueuedRequestKind,
794 ) -> Result<(), Self::Error> {
795 (*self)
796 .save_dependent_queued_request(room_id, parent_txn_id, own_txn_id, created_at, content)
797 .await
798 }
799
800 async fn mark_dependent_queued_requests_as_ready(
801 &self,
802 room_id: &RoomId,
803 parent_txn_id: &TransactionId,
804 sent_parent_key: SentRequestKey,
805 ) -> Result<usize, Self::Error> {
806 (*self)
807 .mark_dependent_queued_requests_as_ready(room_id, parent_txn_id, sent_parent_key)
808 .await
809 }
810
811 async fn update_dependent_queued_request(
812 &self,
813 room_id: &RoomId,
814 own_transaction_id: &ChildTransactionId,
815 new_content: DependentQueuedRequestKind,
816 ) -> Result<bool, Self::Error> {
817 (*self).update_dependent_queued_request(room_id, own_transaction_id, new_content).await
818 }
819
820 async fn remove_dependent_queued_request(
821 &self,
822 room: &RoomId,
823 own_txn_id: &ChildTransactionId,
824 ) -> Result<bool, Self::Error> {
825 (*self).remove_dependent_queued_request(room, own_txn_id).await
826 }
827
828 async fn load_dependent_queued_requests(
829 &self,
830 room: &RoomId,
831 ) -> Result<Vec<DependentQueuedRequest>, Self::Error> {
832 (*self).load_dependent_queued_requests(room).await
833 }
834
835 async fn upsert_thread_subscriptions(
836 &self,
837 updates: Vec<(&RoomId, &EventId, StoredThreadSubscription)>,
838 ) -> Result<(), Self::Error> {
839 (*self).upsert_thread_subscriptions(updates).await
840 }
841
842 async fn remove_thread_subscription(
843 &self,
844 room: &RoomId,
845 thread_id: &EventId,
846 ) -> Result<(), Self::Error> {
847 (*self).remove_thread_subscription(room, thread_id).await
848 }
849
850 async fn load_thread_subscription(
851 &self,
852 room: &RoomId,
853 thread_id: &EventId,
854 ) -> Result<Option<StoredThreadSubscription>, Self::Error> {
855 (*self).load_thread_subscription(room, thread_id).await
856 }
857
858 async fn get_global_profile(
859 &self,
860 user_id: &UserId,
861 ) -> Result<Option<UserProfile>, Self::Error> {
862 (*self).get_global_profile(user_id).await
863 }
864
865 async fn get_global_profiles<'a>(
866 &self,
867 user_ids: &'a [OwnedUserId],
868 ) -> Result<BTreeMap<&'a UserId, UserProfile>, Self::Error> {
869 (*self).get_global_profiles(user_ids).await
870 }
871
872 async fn close(&self) -> Result<(), Self::Error> {
873 (*self).close().await
874 }
875
876 async fn reopen(&self) -> Result<(), Self::Error> {
877 (*self).reopen().await
878 }
879
880 async fn optimize(&self) -> Result<(), Self::Error> {
881 (*self).optimize().await
882 }
883
884 async fn get_size(&self) -> Result<Option<usize>, Self::Error> {
885 (*self).get_size().await
886 }
887}
888
889#[cfg_attr(target_family = "wasm", async_trait(?Send))]
890#[cfg_attr(not(target_family = "wasm"), async_trait)]
891impl<T: StateStore + ?Sized> StateStore for Arc<T> {
892 type Error = T::Error;
893
894 async fn get_kv_data(
895 &self,
896 key: StateStoreDataKey<'_>,
897 ) -> Result<Option<StateStoreDataValue>, Self::Error> {
898 self.deref().get_kv_data(key).await
899 }
900
901 async fn set_kv_data(
902 &self,
903 key: StateStoreDataKey<'_>,
904 value: StateStoreDataValue,
905 ) -> Result<(), Self::Error> {
906 self.deref().set_kv_data(key, value).await
907 }
908
909 async fn remove_kv_data(&self, key: StateStoreDataKey<'_>) -> Result<(), Self::Error> {
910 self.deref().remove_kv_data(key).await
911 }
912
913 async fn save_changes(&self, changes: &StateChanges) -> Result<(), Self::Error> {
914 self.deref().save_changes(changes).await
915 }
916
917 async fn get_presence_event(
918 &self,
919 user_id: &UserId,
920 ) -> Result<Option<Raw<PresenceEvent>>, Self::Error> {
921 self.deref().get_presence_event(user_id).await
922 }
923
924 async fn get_presence_events(
925 &self,
926 user_ids: &[OwnedUserId],
927 ) -> Result<Vec<Raw<PresenceEvent>>, Self::Error> {
928 self.deref().get_presence_events(user_ids).await
929 }
930
931 async fn get_state_event(
932 &self,
933 room_id: &RoomId,
934 event_type: StateEventType,
935 state_key: &str,
936 ) -> Result<Option<RawAnySyncOrStrippedState>, Self::Error> {
937 self.deref().get_state_event(room_id, event_type, state_key).await
938 }
939
940 async fn get_state_events(
941 &self,
942 room_id: &RoomId,
943 event_type: StateEventType,
944 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
945 self.deref().get_state_events(room_id, event_type).await
946 }
947
948 async fn get_state_events_for_keys(
949 &self,
950 room_id: &RoomId,
951 event_type: StateEventType,
952 state_keys: &[&str],
953 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
954 self.deref().get_state_events_for_keys(room_id, event_type, state_keys).await
955 }
956
957 async fn get_profile(
958 &self,
959 room_id: &RoomId,
960 user_id: &UserId,
961 ) -> Result<Option<MinimalRoomMemberEvent>, Self::Error> {
962 self.deref().get_profile(room_id, user_id).await
963 }
964
965 async fn get_profiles<'a>(
966 &self,
967 room_id: &RoomId,
968 user_ids: &'a [OwnedUserId],
969 ) -> Result<BTreeMap<&'a UserId, MinimalRoomMemberEvent>, Self::Error> {
970 self.deref().get_profiles(room_id, user_ids).await
971 }
972
973 async fn get_user_ids(
974 &self,
975 room_id: &RoomId,
976 memberships: RoomMemberships,
977 ) -> Result<Vec<OwnedUserId>, Self::Error> {
978 self.deref().get_user_ids(room_id, memberships).await
979 }
980
981 async fn get_room_infos(
982 &self,
983 room_load_settings: &RoomLoadSettings,
984 ) -> Result<Vec<RoomInfo>, Self::Error> {
985 self.deref().get_room_infos(room_load_settings).await
986 }
987
988 async fn get_users_with_display_name(
989 &self,
990 room_id: &RoomId,
991 display_name: &DisplayName,
992 ) -> Result<BTreeSet<OwnedUserId>, Self::Error> {
993 self.deref().get_users_with_display_name(room_id, display_name).await
994 }
995
996 async fn get_users_with_display_names<'a>(
997 &self,
998 room_id: &RoomId,
999 display_names: &'a [DisplayName],
1000 ) -> Result<HashMap<&'a DisplayName, BTreeSet<OwnedUserId>>, Self::Error> {
1001 self.deref().get_users_with_display_names(room_id, display_names).await
1002 }
1003
1004 async fn get_account_data_event(
1005 &self,
1006 event_type: GlobalAccountDataEventType,
1007 ) -> Result<Option<Raw<AnyGlobalAccountDataEvent>>, Self::Error> {
1008 self.deref().get_account_data_event(event_type).await
1009 }
1010
1011 async fn get_room_account_data_event(
1012 &self,
1013 room_id: &RoomId,
1014 event_type: RoomAccountDataEventType,
1015 ) -> Result<Option<Raw<AnyRoomAccountDataEvent>>, Self::Error> {
1016 self.deref().get_room_account_data_event(room_id, event_type).await
1017 }
1018
1019 async fn get_user_room_receipt_event(
1020 &self,
1021 room_id: &RoomId,
1022 receipt_type: ReceiptType,
1023 receipt_thread: &ReceiptThread,
1024 user_id: &UserId,
1025 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error> {
1026 self.deref()
1027 .get_user_room_receipt_event(room_id, receipt_type, receipt_thread, user_id)
1028 .await
1029 }
1030
1031 async fn get_event_room_receipt_events(
1032 &self,
1033 room_id: &RoomId,
1034 receipt_type: ReceiptType,
1035 receipt_thread: &ReceiptThread,
1036 event_id: &EventId,
1037 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error> {
1038 self.deref()
1039 .get_event_room_receipt_events(room_id, receipt_type, receipt_thread, event_id)
1040 .await
1041 }
1042
1043 async fn get_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1044 self.deref().get_custom_value(key).await
1045 }
1046
1047 async fn set_custom_value(
1048 &self,
1049 key: &[u8],
1050 value: Vec<u8>,
1051 ) -> Result<Option<Vec<u8>>, Self::Error> {
1052 self.deref().set_custom_value(key, value).await
1053 }
1054
1055 async fn remove_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1056 self.deref().remove_custom_value(key).await
1057 }
1058
1059 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error> {
1060 self.deref().remove_room(room_id).await
1061 }
1062
1063 async fn save_send_queue_request(
1064 &self,
1065 room_id: &RoomId,
1066 transaction_id: OwnedTransactionId,
1067 created_at: MilliSecondsSinceUnixEpoch,
1068 request: QueuedRequestKind,
1069 priority: usize,
1070 ) -> Result<(), Self::Error> {
1071 self.deref()
1072 .save_send_queue_request(room_id, transaction_id, created_at, request, priority)
1073 .await
1074 }
1075
1076 async fn update_send_queue_request(
1077 &self,
1078 room_id: &RoomId,
1079 transaction_id: &TransactionId,
1080 content: QueuedRequestKind,
1081 ) -> Result<bool, Self::Error> {
1082 self.deref().update_send_queue_request(room_id, transaction_id, content).await
1083 }
1084
1085 async fn remove_send_queue_request(
1086 &self,
1087 room_id: &RoomId,
1088 transaction_id: &TransactionId,
1089 ) -> Result<bool, Self::Error> {
1090 self.deref().remove_send_queue_request(room_id, transaction_id).await
1091 }
1092
1093 async fn load_send_queue_requests(
1094 &self,
1095 room_id: &RoomId,
1096 ) -> Result<Vec<QueuedRequest>, Self::Error> {
1097 self.deref().load_send_queue_requests(room_id).await
1098 }
1099
1100 async fn update_send_queue_request_status(
1101 &self,
1102 room_id: &RoomId,
1103 transaction_id: &TransactionId,
1104 error: Option<QueueWedgeError>,
1105 ) -> Result<(), Self::Error> {
1106 self.deref().update_send_queue_request_status(room_id, transaction_id, error).await
1107 }
1108
1109 async fn load_rooms_with_unsent_requests(&self) -> Result<Vec<OwnedRoomId>, Self::Error> {
1110 self.deref().load_rooms_with_unsent_requests().await
1111 }
1112
1113 async fn save_dependent_queued_request(
1114 &self,
1115 room_id: &RoomId,
1116 parent_txn_id: &TransactionId,
1117 own_txn_id: ChildTransactionId,
1118 created_at: MilliSecondsSinceUnixEpoch,
1119 content: DependentQueuedRequestKind,
1120 ) -> Result<(), Self::Error> {
1121 self.deref()
1122 .save_dependent_queued_request(room_id, parent_txn_id, own_txn_id, created_at, content)
1123 .await
1124 }
1125
1126 async fn mark_dependent_queued_requests_as_ready(
1127 &self,
1128 room_id: &RoomId,
1129 parent_txn_id: &TransactionId,
1130 sent_parent_key: SentRequestKey,
1131 ) -> Result<usize, Self::Error> {
1132 self.deref()
1133 .mark_dependent_queued_requests_as_ready(room_id, parent_txn_id, sent_parent_key)
1134 .await
1135 }
1136
1137 async fn update_dependent_queued_request(
1138 &self,
1139 room_id: &RoomId,
1140 own_transaction_id: &ChildTransactionId,
1141 new_content: DependentQueuedRequestKind,
1142 ) -> Result<bool, Self::Error> {
1143 self.deref().update_dependent_queued_request(room_id, own_transaction_id, new_content).await
1144 }
1145
1146 async fn remove_dependent_queued_request(
1147 &self,
1148 room: &RoomId,
1149 own_txn_id: &ChildTransactionId,
1150 ) -> Result<bool, Self::Error> {
1151 self.deref().remove_dependent_queued_request(room, own_txn_id).await
1152 }
1153
1154 async fn load_dependent_queued_requests(
1155 &self,
1156 room: &RoomId,
1157 ) -> Result<Vec<DependentQueuedRequest>, Self::Error> {
1158 self.deref().load_dependent_queued_requests(room).await
1159 }
1160
1161 async fn upsert_thread_subscriptions(
1162 &self,
1163 updates: Vec<(&RoomId, &EventId, StoredThreadSubscription)>,
1164 ) -> Result<(), Self::Error> {
1165 self.deref().upsert_thread_subscriptions(updates).await
1166 }
1167
1168 async fn remove_thread_subscription(
1169 &self,
1170 room: &RoomId,
1171 thread_id: &EventId,
1172 ) -> Result<(), Self::Error> {
1173 self.deref().remove_thread_subscription(room, thread_id).await
1174 }
1175
1176 async fn load_thread_subscription(
1177 &self,
1178 room: &RoomId,
1179 thread_id: &EventId,
1180 ) -> Result<Option<StoredThreadSubscription>, Self::Error> {
1181 self.deref().load_thread_subscription(room, thread_id).await
1182 }
1183
1184 async fn get_global_profile(
1185 &self,
1186 user_id: &UserId,
1187 ) -> Result<Option<UserProfile>, Self::Error> {
1188 self.deref().get_global_profile(user_id).await
1189 }
1190
1191 async fn get_global_profiles<'a>(
1192 &self,
1193 user_ids: &'a [OwnedUserId],
1194 ) -> Result<BTreeMap<&'a UserId, UserProfile>, Self::Error> {
1195 self.deref().get_global_profiles(user_ids).await
1196 }
1197
1198 async fn close(&self) -> Result<(), Self::Error> {
1199 self.deref().close().await
1200 }
1201
1202 async fn reopen(&self) -> Result<(), Self::Error> {
1203 self.deref().reopen().await
1204 }
1205
1206 async fn optimize(&self) -> Result<(), Self::Error> {
1207 self.deref().optimize().await
1208 }
1209
1210 async fn get_size(&self) -> Result<Option<usize>, Self::Error> {
1211 self.deref().get_size().await
1212 }
1213}
1214
1215#[repr(transparent)]
1216struct EraseStateStoreError<T>(T);
1217
1218#[cfg(not(tarpaulin_include))]
1219impl<T: fmt::Debug> fmt::Debug for EraseStateStoreError<T> {
1220 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1221 self.0.fmt(f)
1222 }
1223}
1224
1225#[cfg_attr(target_family = "wasm", async_trait(?Send))]
1226#[cfg_attr(not(target_family = "wasm"), async_trait)]
1227impl<T: StateStore> StateStore for EraseStateStoreError<T> {
1228 type Error = StoreError;
1229
1230 async fn get_kv_data(
1231 &self,
1232 key: StateStoreDataKey<'_>,
1233 ) -> Result<Option<StateStoreDataValue>, Self::Error> {
1234 self.0.get_kv_data(key).await.map_err(Into::into)
1235 }
1236
1237 async fn set_kv_data(
1238 &self,
1239 key: StateStoreDataKey<'_>,
1240 value: StateStoreDataValue,
1241 ) -> Result<(), Self::Error> {
1242 self.0.set_kv_data(key, value).await.map_err(Into::into)
1243 }
1244
1245 async fn remove_kv_data(&self, key: StateStoreDataKey<'_>) -> Result<(), Self::Error> {
1246 self.0.remove_kv_data(key).await.map_err(Into::into)
1247 }
1248
1249 async fn save_changes(&self, changes: &StateChanges) -> Result<(), Self::Error> {
1250 self.0.save_changes(changes).await.map_err(Into::into)
1251 }
1252
1253 async fn get_presence_event(
1254 &self,
1255 user_id: &UserId,
1256 ) -> Result<Option<Raw<PresenceEvent>>, Self::Error> {
1257 self.0.get_presence_event(user_id).await.map_err(Into::into)
1258 }
1259
1260 async fn get_presence_events(
1261 &self,
1262 user_ids: &[OwnedUserId],
1263 ) -> Result<Vec<Raw<PresenceEvent>>, Self::Error> {
1264 self.0.get_presence_events(user_ids).await.map_err(Into::into)
1265 }
1266
1267 async fn get_state_event(
1268 &self,
1269 room_id: &RoomId,
1270 event_type: StateEventType,
1271 state_key: &str,
1272 ) -> Result<Option<RawAnySyncOrStrippedState>, Self::Error> {
1273 self.0.get_state_event(room_id, event_type, state_key).await.map_err(Into::into)
1274 }
1275
1276 async fn get_state_events(
1277 &self,
1278 room_id: &RoomId,
1279 event_type: StateEventType,
1280 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
1281 self.0.get_state_events(room_id, event_type).await.map_err(Into::into)
1282 }
1283
1284 async fn get_state_events_for_keys(
1285 &self,
1286 room_id: &RoomId,
1287 event_type: StateEventType,
1288 state_keys: &[&str],
1289 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
1290 self.0.get_state_events_for_keys(room_id, event_type, state_keys).await.map_err(Into::into)
1291 }
1292
1293 async fn get_profile(
1294 &self,
1295 room_id: &RoomId,
1296 user_id: &UserId,
1297 ) -> Result<Option<MinimalRoomMemberEvent>, Self::Error> {
1298 self.0.get_profile(room_id, user_id).await.map_err(Into::into)
1299 }
1300
1301 async fn get_profiles<'a>(
1302 &self,
1303 room_id: &RoomId,
1304 user_ids: &'a [OwnedUserId],
1305 ) -> Result<BTreeMap<&'a UserId, MinimalRoomMemberEvent>, Self::Error> {
1306 self.0.get_profiles(room_id, user_ids).await.map_err(Into::into)
1307 }
1308
1309 async fn get_user_ids(
1310 &self,
1311 room_id: &RoomId,
1312 memberships: RoomMemberships,
1313 ) -> Result<Vec<OwnedUserId>, Self::Error> {
1314 self.0.get_user_ids(room_id, memberships).await.map_err(Into::into)
1315 }
1316
1317 async fn get_room_infos(
1318 &self,
1319 room_load_settings: &RoomLoadSettings,
1320 ) -> Result<Vec<RoomInfo>, Self::Error> {
1321 self.0.get_room_infos(room_load_settings).await.map_err(Into::into)
1322 }
1323
1324 async fn get_users_with_display_name(
1325 &self,
1326 room_id: &RoomId,
1327 display_name: &DisplayName,
1328 ) -> Result<BTreeSet<OwnedUserId>, Self::Error> {
1329 self.0.get_users_with_display_name(room_id, display_name).await.map_err(Into::into)
1330 }
1331
1332 async fn get_users_with_display_names<'a>(
1333 &self,
1334 room_id: &RoomId,
1335 display_names: &'a [DisplayName],
1336 ) -> Result<HashMap<&'a DisplayName, BTreeSet<OwnedUserId>>, Self::Error> {
1337 self.0.get_users_with_display_names(room_id, display_names).await.map_err(Into::into)
1338 }
1339
1340 async fn get_account_data_event(
1341 &self,
1342 event_type: GlobalAccountDataEventType,
1343 ) -> Result<Option<Raw<AnyGlobalAccountDataEvent>>, Self::Error> {
1344 self.0.get_account_data_event(event_type).await.map_err(Into::into)
1345 }
1346
1347 async fn get_room_account_data_event(
1348 &self,
1349 room_id: &RoomId,
1350 event_type: RoomAccountDataEventType,
1351 ) -> Result<Option<Raw<AnyRoomAccountDataEvent>>, Self::Error> {
1352 self.0.get_room_account_data_event(room_id, event_type).await.map_err(Into::into)
1353 }
1354
1355 async fn get_user_room_receipt_event(
1356 &self,
1357 room_id: &RoomId,
1358 receipt_type: ReceiptType,
1359 receipt_thread: &ReceiptThread,
1360 user_id: &UserId,
1361 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error> {
1362 self.0
1363 .get_user_room_receipt_event(room_id, receipt_type, receipt_thread, user_id)
1364 .await
1365 .map_err(Into::into)
1366 }
1367
1368 async fn get_event_room_receipt_events(
1369 &self,
1370 room_id: &RoomId,
1371 receipt_type: ReceiptType,
1372 receipt_thread: &ReceiptThread,
1373 event_id: &EventId,
1374 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error> {
1375 self.0
1376 .get_event_room_receipt_events(room_id, receipt_type, receipt_thread, event_id)
1377 .await
1378 .map_err(Into::into)
1379 }
1380
1381 async fn get_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1382 self.0.get_custom_value(key).await.map_err(Into::into)
1383 }
1384
1385 async fn set_custom_value(
1386 &self,
1387 key: &[u8],
1388 value: Vec<u8>,
1389 ) -> Result<Option<Vec<u8>>, Self::Error> {
1390 self.0.set_custom_value(key, value).await.map_err(Into::into)
1391 }
1392
1393 async fn remove_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1394 self.0.remove_custom_value(key).await.map_err(Into::into)
1395 }
1396
1397 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error> {
1398 self.0.remove_room(room_id).await.map_err(Into::into)
1399 }
1400
1401 async fn save_send_queue_request(
1402 &self,
1403 room_id: &RoomId,
1404 transaction_id: OwnedTransactionId,
1405 created_at: MilliSecondsSinceUnixEpoch,
1406 content: QueuedRequestKind,
1407 priority: usize,
1408 ) -> Result<(), Self::Error> {
1409 self.0
1410 .save_send_queue_request(room_id, transaction_id, created_at, content, priority)
1411 .await
1412 .map_err(Into::into)
1413 }
1414
1415 async fn update_send_queue_request(
1416 &self,
1417 room_id: &RoomId,
1418 transaction_id: &TransactionId,
1419 content: QueuedRequestKind,
1420 ) -> Result<bool, Self::Error> {
1421 self.0.update_send_queue_request(room_id, transaction_id, content).await.map_err(Into::into)
1422 }
1423
1424 async fn remove_send_queue_request(
1425 &self,
1426 room_id: &RoomId,
1427 transaction_id: &TransactionId,
1428 ) -> Result<bool, Self::Error> {
1429 self.0.remove_send_queue_request(room_id, transaction_id).await.map_err(Into::into)
1430 }
1431
1432 async fn load_send_queue_requests(
1433 &self,
1434 room_id: &RoomId,
1435 ) -> Result<Vec<QueuedRequest>, Self::Error> {
1436 self.0.load_send_queue_requests(room_id).await.map_err(Into::into)
1437 }
1438
1439 async fn update_send_queue_request_status(
1440 &self,
1441 room_id: &RoomId,
1442 transaction_id: &TransactionId,
1443 error: Option<QueueWedgeError>,
1444 ) -> Result<(), Self::Error> {
1445 self.0
1446 .update_send_queue_request_status(room_id, transaction_id, error)
1447 .await
1448 .map_err(Into::into)
1449 }
1450
1451 async fn load_rooms_with_unsent_requests(&self) -> Result<Vec<OwnedRoomId>, Self::Error> {
1452 self.0.load_rooms_with_unsent_requests().await.map_err(Into::into)
1453 }
1454
1455 async fn save_dependent_queued_request(
1456 &self,
1457 room_id: &RoomId,
1458 parent_txn_id: &TransactionId,
1459 own_txn_id: ChildTransactionId,
1460 created_at: MilliSecondsSinceUnixEpoch,
1461 content: DependentQueuedRequestKind,
1462 ) -> Result<(), Self::Error> {
1463 self.0
1464 .save_dependent_queued_request(room_id, parent_txn_id, own_txn_id, created_at, content)
1465 .await
1466 .map_err(Into::into)
1467 }
1468
1469 async fn mark_dependent_queued_requests_as_ready(
1470 &self,
1471 room_id: &RoomId,
1472 parent_txn_id: &TransactionId,
1473 sent_parent_key: SentRequestKey,
1474 ) -> Result<usize, Self::Error> {
1475 self.0
1476 .mark_dependent_queued_requests_as_ready(room_id, parent_txn_id, sent_parent_key)
1477 .await
1478 .map_err(Into::into)
1479 }
1480
1481 async fn remove_dependent_queued_request(
1482 &self,
1483 room_id: &RoomId,
1484 own_txn_id: &ChildTransactionId,
1485 ) -> Result<bool, Self::Error> {
1486 self.0.remove_dependent_queued_request(room_id, own_txn_id).await.map_err(Into::into)
1487 }
1488
1489 async fn load_dependent_queued_requests(
1490 &self,
1491 room_id: &RoomId,
1492 ) -> Result<Vec<DependentQueuedRequest>, Self::Error> {
1493 self.0.load_dependent_queued_requests(room_id).await.map_err(Into::into)
1494 }
1495
1496 async fn update_dependent_queued_request(
1497 &self,
1498 room_id: &RoomId,
1499 own_transaction_id: &ChildTransactionId,
1500 new_content: DependentQueuedRequestKind,
1501 ) -> Result<bool, Self::Error> {
1502 self.0
1503 .update_dependent_queued_request(room_id, own_transaction_id, new_content)
1504 .await
1505 .map_err(Into::into)
1506 }
1507
1508 async fn upsert_thread_subscriptions(
1509 &self,
1510 updates: Vec<(&RoomId, &EventId, StoredThreadSubscription)>,
1511 ) -> Result<(), Self::Error> {
1512 self.0.upsert_thread_subscriptions(updates).await.map_err(Into::into)
1513 }
1514
1515 async fn load_thread_subscription(
1516 &self,
1517 room: &RoomId,
1518 thread_id: &EventId,
1519 ) -> Result<Option<StoredThreadSubscription>, Self::Error> {
1520 self.0.load_thread_subscription(room, thread_id).await.map_err(Into::into)
1521 }
1522
1523 async fn remove_thread_subscription(
1524 &self,
1525 room: &RoomId,
1526 thread_id: &EventId,
1527 ) -> Result<(), Self::Error> {
1528 self.0.remove_thread_subscription(room, thread_id).await.map_err(Into::into)
1529 }
1530
1531 async fn get_global_profile(
1532 &self,
1533 user_id: &UserId,
1534 ) -> Result<Option<UserProfile>, Self::Error> {
1535 self.0.get_global_profile(user_id).await.map_err(Into::into)
1536 }
1537
1538 async fn get_global_profiles<'a>(
1539 &self,
1540 user_ids: &'a [OwnedUserId],
1541 ) -> Result<BTreeMap<&'a UserId, UserProfile>, Self::Error> {
1542 self.0.get_global_profiles(user_ids).await.map_err(Into::into)
1543 }
1544
1545 async fn close(&self) -> Result<(), Self::Error> {
1546 self.0.close().await.map_err(Into::into)
1547 }
1548
1549 async fn reopen(&self) -> Result<(), Self::Error> {
1550 self.0.reopen().await.map_err(Into::into)
1551 }
1552
1553 async fn optimize(&self) -> Result<(), Self::Error> {
1554 self.0.optimize().await.map_err(Into::into)
1555 }
1556
1557 async fn get_size(&self) -> Result<Option<usize>, Self::Error> {
1558 self.0.get_size().await.map_err(Into::into)
1559 }
1560}
1561
1562#[derive(Debug, Clone)]
1565pub struct SaveLockedStateStore<T = Arc<DynStateStore>> {
1566 store: T,
1567 lock: Arc<Mutex<()>>,
1568}
1569
1570#[derive(Debug, Error)]
1574#[error("a mutex guard was provided, but it does not reference the correct mutex")]
1575pub struct IncorrectMutexGuardError;
1576
1577impl From<IncorrectMutexGuardError> for StoreError {
1578 fn from(value: IncorrectMutexGuardError) -> Self {
1579 Self::backend(value)
1580 }
1581}
1582
1583impl<T> SaveLockedStateStore<T> {
1584 pub fn new(store: T) -> Self {
1586 Self { store, lock: Arc::new(Mutex::new(())) }
1587 }
1588
1589 pub fn lock(&self) -> &Mutex<()> {
1592 self.lock.as_ref()
1593 }
1594}
1595
1596impl<T: StateStore> SaveLockedStateStore<T> {
1597 pub async fn save_changes_with_guard(
1602 &self,
1603 guard: &MutexGuard<'_, ()>,
1604 changes: &StateChanges,
1605 ) -> Result<(), StoreError> {
1606 if !std::ptr::eq(MutexGuard::mutex(guard), self.lock()) {
1607 Err(IncorrectMutexGuardError.into())
1608 } else {
1609 self.store.save_changes(changes).await.map_err(Into::into)
1610 }
1611 }
1612
1613 pub async fn remove_room_with_guard(
1618 &self,
1619 guard: &MutexGuard<'_, ()>,
1620 room_id: &RoomId,
1621 ) -> Result<(), StoreError> {
1622 if !std::ptr::eq(MutexGuard::mutex(guard), self.lock()) {
1623 Err(IncorrectMutexGuardError.into())
1624 } else {
1625 self.store.remove_room(room_id).await.map_err(Into::into)
1626 }
1627 }
1628}
1629
1630#[cfg_attr(target_family = "wasm", async_trait(?Send))]
1631#[cfg_attr(not(target_family = "wasm"), async_trait)]
1632impl<T: StateStore> StateStore for SaveLockedStateStore<T> {
1633 type Error = T::Error;
1634
1635 async fn get_kv_data(
1636 &self,
1637 key: StateStoreDataKey<'_>,
1638 ) -> Result<Option<StateStoreDataValue>, Self::Error> {
1639 self.store.get_kv_data(key).await
1640 }
1641
1642 async fn set_kv_data(
1643 &self,
1644 key: StateStoreDataKey<'_>,
1645 value: StateStoreDataValue,
1646 ) -> Result<(), Self::Error> {
1647 self.store.set_kv_data(key, value).await
1648 }
1649
1650 async fn remove_kv_data(&self, key: StateStoreDataKey<'_>) -> Result<(), Self::Error> {
1651 self.store.remove_kv_data(key).await
1652 }
1653
1654 async fn save_changes(&self, changes: &StateChanges) -> Result<(), Self::Error> {
1655 let _guard = self.lock.lock().await;
1656 self.store.save_changes(changes).await
1657 }
1658
1659 async fn get_presence_event(
1660 &self,
1661 user_id: &UserId,
1662 ) -> Result<Option<Raw<PresenceEvent>>, Self::Error> {
1663 self.store.get_presence_event(user_id).await
1664 }
1665
1666 async fn get_presence_events(
1667 &self,
1668 user_ids: &[OwnedUserId],
1669 ) -> Result<Vec<Raw<PresenceEvent>>, Self::Error> {
1670 self.store.get_presence_events(user_ids).await
1671 }
1672
1673 async fn get_state_event(
1674 &self,
1675 room_id: &RoomId,
1676 event_type: StateEventType,
1677 state_key: &str,
1678 ) -> Result<Option<RawAnySyncOrStrippedState>, Self::Error> {
1679 self.store.get_state_event(room_id, event_type, state_key).await
1680 }
1681
1682 async fn get_state_events(
1683 &self,
1684 room_id: &RoomId,
1685 event_type: StateEventType,
1686 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
1687 self.store.get_state_events(room_id, event_type).await
1688 }
1689
1690 async fn get_state_events_for_keys(
1691 &self,
1692 room_id: &RoomId,
1693 event_type: StateEventType,
1694 state_keys: &[&str],
1695 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
1696 self.store.get_state_events_for_keys(room_id, event_type, state_keys).await
1697 }
1698
1699 async fn get_profile(
1700 &self,
1701 room_id: &RoomId,
1702 user_id: &UserId,
1703 ) -> Result<Option<MinimalRoomMemberEvent>, Self::Error> {
1704 self.store.get_profile(room_id, user_id).await
1705 }
1706
1707 async fn get_profiles<'a>(
1708 &self,
1709 room_id: &RoomId,
1710 user_ids: &'a [OwnedUserId],
1711 ) -> Result<BTreeMap<&'a UserId, MinimalRoomMemberEvent>, Self::Error> {
1712 self.store.get_profiles(room_id, user_ids).await
1713 }
1714
1715 async fn get_user_ids(
1716 &self,
1717 room_id: &RoomId,
1718 memberships: RoomMemberships,
1719 ) -> Result<Vec<OwnedUserId>, Self::Error> {
1720 self.store.get_user_ids(room_id, memberships).await
1721 }
1722
1723 async fn get_room_infos(
1724 &self,
1725 room_load_settings: &RoomLoadSettings,
1726 ) -> Result<Vec<RoomInfo>, Self::Error> {
1727 self.store.get_room_infos(room_load_settings).await
1728 }
1729
1730 async fn get_users_with_display_name(
1731 &self,
1732 room_id: &RoomId,
1733 display_name: &DisplayName,
1734 ) -> Result<BTreeSet<OwnedUserId>, Self::Error> {
1735 self.store.get_users_with_display_name(room_id, display_name).await
1736 }
1737
1738 async fn get_users_with_display_names<'a>(
1739 &self,
1740 room_id: &RoomId,
1741 display_names: &'a [DisplayName],
1742 ) -> Result<HashMap<&'a DisplayName, BTreeSet<OwnedUserId>>, Self::Error> {
1743 self.store.get_users_with_display_names(room_id, display_names).await
1744 }
1745
1746 async fn get_account_data_event(
1747 &self,
1748 event_type: GlobalAccountDataEventType,
1749 ) -> Result<Option<Raw<AnyGlobalAccountDataEvent>>, Self::Error> {
1750 self.store.get_account_data_event(event_type).await
1751 }
1752
1753 async fn get_room_account_data_event(
1754 &self,
1755 room_id: &RoomId,
1756 event_type: RoomAccountDataEventType,
1757 ) -> Result<Option<Raw<AnyRoomAccountDataEvent>>, Self::Error> {
1758 self.store.get_room_account_data_event(room_id, event_type).await
1759 }
1760
1761 async fn get_user_room_receipt_event(
1762 &self,
1763 room_id: &RoomId,
1764 receipt_type: ReceiptType,
1765 receipt_thread: &ReceiptThread,
1766 user_id: &UserId,
1767 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error> {
1768 self.store.get_user_room_receipt_event(room_id, receipt_type, receipt_thread, user_id).await
1769 }
1770
1771 async fn get_event_room_receipt_events(
1772 &self,
1773 room_id: &RoomId,
1774 receipt_type: ReceiptType,
1775 receipt_thread: &ReceiptThread,
1776 event_id: &EventId,
1777 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error> {
1778 self.store
1779 .get_event_room_receipt_events(room_id, receipt_type, receipt_thread, event_id)
1780 .await
1781 }
1782
1783 async fn get_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1784 self.store.get_custom_value(key).await
1785 }
1786
1787 async fn set_custom_value(
1788 &self,
1789 key: &[u8],
1790 value: Vec<u8>,
1791 ) -> Result<Option<Vec<u8>>, Self::Error> {
1792 self.store.set_custom_value(key, value).await
1793 }
1794
1795 async fn remove_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1796 self.store.remove_custom_value(key).await
1797 }
1798
1799 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error> {
1800 let _guard = self.lock.lock().await;
1801 self.store.remove_room(room_id).await
1802 }
1803
1804 async fn save_send_queue_request(
1805 &self,
1806 room_id: &RoomId,
1807 transaction_id: OwnedTransactionId,
1808 created_at: MilliSecondsSinceUnixEpoch,
1809 request: QueuedRequestKind,
1810 priority: usize,
1811 ) -> Result<(), Self::Error> {
1812 self.store
1813 .save_send_queue_request(room_id, transaction_id, created_at, request, priority)
1814 .await
1815 }
1816
1817 async fn update_send_queue_request(
1818 &self,
1819 room_id: &RoomId,
1820 transaction_id: &TransactionId,
1821 content: QueuedRequestKind,
1822 ) -> Result<bool, Self::Error> {
1823 self.store.update_send_queue_request(room_id, transaction_id, content).await
1824 }
1825
1826 async fn remove_send_queue_request(
1827 &self,
1828 room_id: &RoomId,
1829 transaction_id: &TransactionId,
1830 ) -> Result<bool, Self::Error> {
1831 self.store.remove_send_queue_request(room_id, transaction_id).await
1832 }
1833
1834 async fn load_send_queue_requests(
1835 &self,
1836 room_id: &RoomId,
1837 ) -> Result<Vec<QueuedRequest>, Self::Error> {
1838 self.store.load_send_queue_requests(room_id).await
1839 }
1840
1841 async fn update_send_queue_request_status(
1842 &self,
1843 room_id: &RoomId,
1844 transaction_id: &TransactionId,
1845 error: Option<QueueWedgeError>,
1846 ) -> Result<(), Self::Error> {
1847 self.store.update_send_queue_request_status(room_id, transaction_id, error).await
1848 }
1849
1850 async fn load_rooms_with_unsent_requests(&self) -> Result<Vec<OwnedRoomId>, Self::Error> {
1851 self.store.load_rooms_with_unsent_requests().await
1852 }
1853
1854 async fn save_dependent_queued_request(
1855 &self,
1856 room_id: &RoomId,
1857 parent_txn_id: &TransactionId,
1858 own_txn_id: ChildTransactionId,
1859 created_at: MilliSecondsSinceUnixEpoch,
1860 content: DependentQueuedRequestKind,
1861 ) -> Result<(), Self::Error> {
1862 self.store
1863 .save_dependent_queued_request(room_id, parent_txn_id, own_txn_id, created_at, content)
1864 .await
1865 }
1866
1867 async fn mark_dependent_queued_requests_as_ready(
1868 &self,
1869 room_id: &RoomId,
1870 parent_txn_id: &TransactionId,
1871 sent_parent_key: SentRequestKey,
1872 ) -> Result<usize, Self::Error> {
1873 self.store
1874 .mark_dependent_queued_requests_as_ready(room_id, parent_txn_id, sent_parent_key)
1875 .await
1876 }
1877
1878 async fn update_dependent_queued_request(
1879 &self,
1880 room_id: &RoomId,
1881 own_transaction_id: &ChildTransactionId,
1882 new_content: DependentQueuedRequestKind,
1883 ) -> Result<bool, Self::Error> {
1884 self.store.update_dependent_queued_request(room_id, own_transaction_id, new_content).await
1885 }
1886
1887 async fn remove_dependent_queued_request(
1888 &self,
1889 room: &RoomId,
1890 own_txn_id: &ChildTransactionId,
1891 ) -> Result<bool, Self::Error> {
1892 self.store.remove_dependent_queued_request(room, own_txn_id).await
1893 }
1894
1895 async fn load_dependent_queued_requests(
1896 &self,
1897 room: &RoomId,
1898 ) -> Result<Vec<DependentQueuedRequest>, Self::Error> {
1899 self.store.load_dependent_queued_requests(room).await
1900 }
1901
1902 async fn upsert_thread_subscriptions(
1903 &self,
1904 updates: Vec<(&RoomId, &EventId, StoredThreadSubscription)>,
1905 ) -> Result<(), Self::Error> {
1906 self.store.upsert_thread_subscriptions(updates).await
1907 }
1908
1909 async fn load_thread_subscription(
1910 &self,
1911 room: &RoomId,
1912 thread_id: &EventId,
1913 ) -> Result<Option<StoredThreadSubscription>, Self::Error> {
1914 self.store.load_thread_subscription(room, thread_id).await
1915 }
1916
1917 async fn remove_thread_subscription(
1918 &self,
1919 room: &RoomId,
1920 thread_id: &EventId,
1921 ) -> Result<(), Self::Error> {
1922 self.store.remove_thread_subscription(room, thread_id).await
1923 }
1924
1925 async fn get_global_profile(
1926 &self,
1927 user_id: &UserId,
1928 ) -> Result<Option<UserProfile>, Self::Error> {
1929 self.store.get_global_profile(user_id).await
1930 }
1931
1932 async fn get_global_profiles<'a>(
1933 &self,
1934 user_ids: &'a [OwnedUserId],
1935 ) -> Result<BTreeMap<&'a UserId, UserProfile>, Self::Error> {
1936 self.store.get_global_profiles(user_ids).await
1937 }
1938
1939 async fn close(&self) -> Result<(), Self::Error> {
1940 self.store.close().await
1941 }
1942
1943 async fn reopen(&self) -> Result<(), Self::Error> {
1944 self.store.reopen().await
1945 }
1946
1947 async fn optimize(&self) -> Result<(), Self::Error> {
1948 self.store.optimize().await
1949 }
1950
1951 async fn get_size(&self) -> Result<Option<usize>, Self::Error> {
1952 self.store.get_size().await
1953 }
1954}
1955
1956#[cfg_attr(target_family = "wasm", async_trait(?Send))]
1958#[cfg_attr(not(target_family = "wasm"), async_trait)]
1959pub trait StateStoreExt: StateStore {
1960 async fn get_state_event_static<C>(
1966 &self,
1967 room_id: &RoomId,
1968 ) -> Result<Option<RawSyncOrStrippedState<C>>, Self::Error>
1969 where
1970 C: StaticEventContent<IsPrefix = ruma::events::False>
1971 + StaticStateEventContent<StateKey = EmptyStateKey>
1972 + RedactContent,
1973 C::Redacted: RedactedStateEventContent,
1974 {
1975 Ok(self.get_state_event(room_id, C::TYPE.into(), "").await?.map(|raw| raw.cast()))
1976 }
1977
1978 async fn get_state_event_static_for_key<C, K>(
1984 &self,
1985 room_id: &RoomId,
1986 state_key: &K,
1987 ) -> Result<Option<RawSyncOrStrippedState<C>>, Self::Error>
1988 where
1989 C: StaticEventContent<IsPrefix = ruma::events::False>
1990 + StaticStateEventContent
1991 + RedactContent,
1992 C::StateKey: Borrow<K>,
1993 C::Redacted: RedactedStateEventContent,
1994 K: AsRef<str> + ?Sized + Sync,
1995 {
1996 Ok(self
1997 .get_state_event(room_id, C::TYPE.into(), state_key.as_ref())
1998 .await?
1999 .map(|raw| raw.cast()))
2000 }
2001
2002 async fn get_state_events_static<C>(
2008 &self,
2009 room_id: &RoomId,
2010 ) -> Result<Vec<RawSyncOrStrippedState<C>>, Self::Error>
2011 where
2012 C: StaticEventContent<IsPrefix = ruma::events::False>
2013 + StaticStateEventContent
2014 + RedactContent,
2015 C::Redacted: RedactedStateEventContent,
2016 {
2017 Ok(self
2019 .get_state_events(room_id, C::TYPE.into())
2020 .await?
2021 .into_iter()
2022 .map(|raw| raw.cast())
2023 .collect())
2024 }
2025
2026 async fn get_state_events_for_keys_static<'a, C, K, I>(
2035 &self,
2036 room_id: &RoomId,
2037 state_keys: I,
2038 ) -> Result<Vec<RawSyncOrStrippedState<C>>, Self::Error>
2039 where
2040 C: StaticEventContent<IsPrefix = ruma::events::False>
2041 + StaticStateEventContent
2042 + RedactContent,
2043 C::StateKey: Borrow<K>,
2044 C::Redacted: RedactedStateEventContent,
2045 K: AsRef<str> + Sized + Sync + 'a,
2046 I: IntoIterator<Item = &'a K> + Send,
2047 I::IntoIter: Send,
2048 {
2049 Ok(self
2050 .get_state_events_for_keys(
2051 room_id,
2052 C::TYPE.into(),
2053 &state_keys.into_iter().map(|k| k.as_ref()).collect::<Vec<_>>(),
2054 )
2055 .await?
2056 .into_iter()
2057 .map(|raw| raw.cast())
2058 .collect())
2059 }
2060
2061 async fn get_account_data_event_static<C>(
2063 &self,
2064 ) -> Result<Option<Raw<GlobalAccountDataEvent<C>>>, Self::Error>
2065 where
2066 C: StaticEventContent<IsPrefix = ruma::events::False> + GlobalAccountDataEventContent,
2067 {
2068 Ok(self.get_account_data_event(C::TYPE.into()).await?.map(Raw::cast_unchecked))
2069 }
2070
2071 async fn get_room_account_data_event_static<C>(
2079 &self,
2080 room_id: &RoomId,
2081 ) -> Result<Option<Raw<RoomAccountDataEvent<C>>>, Self::Error>
2082 where
2083 C: StaticEventContent<IsPrefix = ruma::events::False> + RoomAccountDataEventContent,
2084 {
2085 Ok(self
2086 .get_room_account_data_event(room_id, C::TYPE.into())
2087 .await?
2088 .map(Raw::cast_unchecked))
2089 }
2090
2091 async fn get_member_event(
2099 &self,
2100 room_id: &RoomId,
2101 state_key: &UserId,
2102 ) -> Result<Option<RawMemberEvent>, Self::Error> {
2103 self.get_state_event_static_for_key(room_id, state_key).await
2104 }
2105}
2106
2107#[cfg_attr(target_family = "wasm", async_trait(?Send))]
2108#[cfg_attr(not(target_family = "wasm"), async_trait)]
2109impl<T: StateStore + ?Sized> StateStoreExt for T {}
2110
2111pub type DynStateStore = dyn StateStore<Error = StoreError>;
2113
2114pub trait IntoStateStore {
2120 #[doc(hidden)]
2121 fn into_state_store(self) -> Arc<DynStateStore>;
2122}
2123
2124impl<T> IntoStateStore for T
2125where
2126 T: StateStore + Sized + 'static,
2127{
2128 fn into_state_store(self) -> Arc<DynStateStore> {
2129 Arc::new(EraseStateStoreError(self))
2130 }
2131}
2132
2133#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
2135pub struct SupportedVersionsResponse {
2136 pub versions: Vec<String>,
2138
2139 pub unstable_features: BTreeMap<String, bool>,
2141}
2142
2143impl SupportedVersionsResponse {
2144 pub fn supported_versions(&self) -> SupportedVersions {
2150 let mut supported_versions =
2151 SupportedVersions::from_parts(&self.versions, &self.unstable_features);
2152
2153 if supported_versions.versions.is_empty() {
2156 supported_versions.versions.insert(MatrixVersion::V1_0);
2157 }
2158
2159 supported_versions
2160 }
2161}
2162
2163#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
2164pub struct WellKnownResponse {
2166 pub homeserver: HomeserverInfo,
2168
2169 pub identity_server: Option<IdentityServerInfo>,
2171
2172 pub tile_server: Option<TileServerInfo>,
2174
2175 pub rtc_foci: Vec<RtcTransport>,
2177}
2178
2179impl From<discover_homeserver::Response> for WellKnownResponse {
2180 fn from(response: discover_homeserver::Response) -> Self {
2181 Self {
2182 homeserver: response.homeserver,
2183 identity_server: response.identity_server,
2184 tile_server: response.tile_server,
2185 rtc_foci: response.rtc_foci,
2186 }
2187 }
2188}
2189
2190#[derive(Debug, Clone)]
2192pub enum StateStoreDataValue {
2193 SyncToken(String),
2195
2196 SupportedVersions(TtlValue<SupportedVersionsResponse>),
2198
2199 WellKnown(TtlValue<Option<WellKnownResponse>>),
2201
2202 Filter(String),
2204
2205 UserAvatarUrl(OwnedMxcUri),
2207
2208 RecentlyVisitedRooms(Vec<OwnedRoomId>),
2210
2211 UtdHookManagerData(GrowableBloom),
2214
2215 OneTimeKeyAlreadyUploaded,
2218
2219 ComposerDraft(ComposerDraft),
2224
2225 SeenKnockRequests(BTreeMap<OwnedEventId, OwnedUserId>),
2227
2228 ThreadSubscriptionsCatchupTokens(Vec<ThreadSubscriptionCatchupToken>),
2233
2234 HomeserverCapabilities(TtlValue<Capabilities>),
2236}
2237
2238#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2248pub struct ThreadSubscriptionCatchupToken {
2249 pub from: String,
2255
2256 pub to: Option<String>,
2262}
2263
2264#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2266pub struct ComposerDraft {
2267 pub plain_text: String,
2269 pub html_text: Option<String>,
2272 pub draft_type: ComposerDraftType,
2274 #[serde(default)]
2276 pub attachments: Vec<DraftAttachment>,
2277}
2278
2279#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2281pub struct DraftAttachment {
2282 pub filename: String,
2284 pub content: DraftAttachmentContent,
2286}
2287
2288#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2290#[serde(tag = "type")]
2291pub enum DraftAttachmentContent {
2292 Image {
2294 data: Vec<u8>,
2296 mimetype: Option<String>,
2298 size: Option<u64>,
2300 width: Option<u64>,
2302 height: Option<u64>,
2304 blurhash: Option<String>,
2306 thumbnail: Option<DraftThumbnail>,
2308 },
2309 Video {
2311 data: Vec<u8>,
2313 mimetype: Option<String>,
2315 size: Option<u64>,
2317 width: Option<u64>,
2319 height: Option<u64>,
2321 duration: Option<std::time::Duration>,
2323 blurhash: Option<String>,
2325 thumbnail: Option<DraftThumbnail>,
2327 },
2328 Audio {
2330 data: Vec<u8>,
2332 mimetype: Option<String>,
2334 size: Option<u64>,
2336 duration: Option<std::time::Duration>,
2338 },
2339 File {
2341 data: Vec<u8>,
2343 mimetype: Option<String>,
2345 size: Option<u64>,
2347 },
2348}
2349
2350#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2352pub struct DraftThumbnail {
2353 pub filename: String,
2355 pub data: Vec<u8>,
2357 pub mimetype: Option<String>,
2359 pub width: Option<u64>,
2361 pub height: Option<u64>,
2363 pub size: Option<u64>,
2365}
2366
2367#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2369pub enum ComposerDraftType {
2370 NewMessage,
2372 Reply {
2374 event_id: OwnedEventId,
2376 },
2377 Edit {
2379 event_id: OwnedEventId,
2381 },
2382}
2383
2384impl StateStoreDataValue {
2385 pub fn into_sync_token(self) -> Option<String> {
2387 as_variant!(self, Self::SyncToken)
2388 }
2389
2390 pub fn into_filter(self) -> Option<String> {
2392 as_variant!(self, Self::Filter)
2393 }
2394
2395 pub fn into_user_avatar_url(self) -> Option<OwnedMxcUri> {
2397 as_variant!(self, Self::UserAvatarUrl)
2398 }
2399
2400 pub fn into_recently_visited_rooms(self) -> Option<Vec<OwnedRoomId>> {
2402 as_variant!(self, Self::RecentlyVisitedRooms)
2403 }
2404
2405 pub fn into_utd_hook_manager_data(self) -> Option<GrowableBloom> {
2407 as_variant!(self, Self::UtdHookManagerData)
2408 }
2409
2410 pub fn into_composer_draft(self) -> Option<ComposerDraft> {
2412 as_variant!(self, Self::ComposerDraft)
2413 }
2414
2415 pub fn into_supported_versions(self) -> Option<TtlValue<SupportedVersionsResponse>> {
2417 as_variant!(self, Self::SupportedVersions)
2418 }
2419
2420 pub fn into_well_known(self) -> Option<TtlValue<Option<WellKnownResponse>>> {
2422 as_variant!(self, Self::WellKnown)
2423 }
2424
2425 pub fn into_seen_knock_requests(self) -> Option<BTreeMap<OwnedEventId, OwnedUserId>> {
2427 as_variant!(self, Self::SeenKnockRequests)
2428 }
2429
2430 pub fn into_thread_subscriptions_catchup_tokens(
2433 self,
2434 ) -> Option<Vec<ThreadSubscriptionCatchupToken>> {
2435 as_variant!(self, Self::ThreadSubscriptionsCatchupTokens)
2436 }
2437
2438 pub fn into_homeserver_capabilities(self) -> Option<TtlValue<Capabilities>> {
2441 as_variant!(self, Self::HomeserverCapabilities)
2442 }
2443}
2444
2445#[derive(Debug, Clone, Copy)]
2447pub enum StateStoreDataKey<'a> {
2448 SyncToken,
2450
2451 SupportedVersions,
2453
2454 WellKnown,
2456
2457 Filter(&'a str),
2459
2460 UserAvatarUrl(&'a UserId),
2462
2463 RecentlyVisitedRooms(&'a UserId),
2465
2466 UtdHookManagerData,
2469
2470 OneTimeKeyAlreadyUploaded,
2473
2474 ComposerDraft(&'a RoomId, Option<&'a EventId>),
2479
2480 SeenKnockRequests(&'a RoomId),
2482
2483 ThreadSubscriptionsCatchupTokens,
2485
2486 HomeserverCapabilities,
2488}
2489
2490impl StateStoreDataKey<'_> {
2491 pub const SYNC_TOKEN: &'static str = "sync_token";
2493
2494 pub const SUPPORTED_VERSIONS: &'static str = "server_capabilities"; pub const WELL_KNOWN: &'static str = "well_known";
2501
2502 pub const FILTER: &'static str = "filter";
2504
2505 pub const USER_AVATAR_URL: &'static str = "user_avatar_url";
2508
2509 pub const RECENTLY_VISITED_ROOMS: &'static str = "recently_visited_rooms";
2512
2513 pub const UTD_HOOK_MANAGER_DATA: &'static str = "utd_hook_manager_data";
2516
2517 pub const ONE_TIME_KEY_ALREADY_UPLOADED: &'static str = "one_time_key_already_uploaded";
2520
2521 pub const COMPOSER_DRAFT: &'static str = "composer_draft";
2524
2525 pub const SEEN_KNOCK_REQUESTS: &'static str = "seen_knock_requests";
2528
2529 pub const THREAD_SUBSCRIPTIONS_CATCHUP_TOKENS: &'static str =
2532 "thread_subscriptions_catchup_tokens";
2533
2534 pub const HOMESERVER_CAPABILITIES: &'static str = "homeserver_capabilities";
2536}
2537
2538pub fn compare_thread_subscription_bump_stamps(
2547 previous: Option<u64>,
2548 new: &mut Option<u64>,
2549) -> bool {
2550 match (previous, &new) {
2551 (Some(prev_bump), None) => {
2554 *new = Some(prev_bump);
2555 }
2556
2557 (Some(prev_bump), Some(new_bump)) if *new_bump <= prev_bump => {
2559 return false;
2560 }
2561
2562 _ => {}
2564 }
2565
2566 true
2567}
2568
2569#[cfg(test)]
2570mod tests {
2571 mod save_locked_state_store {
2572 use std::time::Duration;
2573
2574 use assert_matches::assert_matches;
2575 use futures_util::future::{self, Either};
2576 #[cfg(all(target_family = "wasm", target_os = "unknown"))]
2577 use gloo_timers::future::sleep;
2578 use matrix_sdk_common::executor::spawn;
2579 use matrix_sdk_test::async_test;
2580 use ruma::room_id;
2581 use tokio::sync::Mutex;
2582 #[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
2583 use tokio::time::sleep;
2584
2585 use crate::{
2586 StateChanges, StateStore,
2587 store::{IntoStateStore, MemoryStore, Result, SaveLockedStateStore},
2588 };
2589
2590 async fn get_store() -> Result<impl StateStore> {
2591 Ok(SaveLockedStateStore::new(MemoryStore::new()))
2592 }
2593
2594 statestore_integration_tests!();
2595
2596 #[async_test]
2597 async fn test_save_changes_only_accepts_guard_for_underlying_mutex() {
2598 let state_store = SaveLockedStateStore::new(MemoryStore::new());
2599 let state_changes = StateChanges::default();
2600 state_store
2601 .save_changes_with_guard(&state_store.lock().lock().await, &state_changes)
2602 .await
2603 .expect("state store accepts guard for underlying mutex");
2604
2605 let mutex = Mutex::new(());
2606 state_store
2607 .save_changes_with_guard(&mutex.lock().await, &state_changes)
2608 .await
2609 .expect_err("state store does not accept guard for unknown mutex");
2610 }
2611
2612 #[async_test]
2613 async fn test_remove_room_only_accepts_guard_for_underlying_mutex() {
2614 let state_store = SaveLockedStateStore::new(MemoryStore::new());
2615 let room_id = room_id!("!room");
2616 state_store
2617 .remove_room_with_guard(&state_store.lock().lock().await, room_id)
2618 .await
2619 .expect("state store accepts guard for underlying mutex");
2620
2621 let mutex = Mutex::new(());
2622 state_store
2623 .remove_room_with_guard(&mutex.lock().await, room_id)
2624 .await
2625 .expect_err("state store does not accept guard for unknown mutex");
2626 }
2627
2628 #[derive(Debug)]
2629 struct Elapsed;
2630
2631 async fn timeout<F: Future + Unpin>(
2632 duration: Duration,
2633 f: F,
2634 ) -> Result<F::Output, Elapsed> {
2635 #[cfg(all(target_family = "wasm", target_os = "unknown"))]
2636 {
2637 match future::select(sleep(duration), f).await {
2638 Either::Left(_) => return Err(Elapsed),
2639 Either::Right((output, _)) => Ok(output),
2640 }
2641 }
2642 #[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
2643 {
2644 tokio::time::timeout(duration, f).await.map_err(|_| Elapsed)
2645 }
2646 }
2647
2648 #[async_test]
2649 async fn test_state_store_waits_to_acquire_lock_before_saving_changes() {
2650 let state_store = SaveLockedStateStore::new(MemoryStore::new().into_state_store());
2651
2652 let lock_task = spawn({
2654 let state_store = state_store.clone();
2655 async move {
2656 let lock = state_store.lock();
2657 let _guard = lock.lock().await;
2658 sleep(Duration::from_secs(5)).await;
2659 }
2660 });
2661
2662 let save_task =
2664 spawn(async move { state_store.save_changes(&StateChanges::default()).await });
2665
2666 assert_matches!(future::select(lock_task, save_task).await, Either::Left((_, save_task)) => {
2669 timeout(Duration::from_millis(100), save_task)
2670 .await
2671 .expect("task completes before timeout")
2672 .expect("task completes successfully")
2673 .expect("task saves changes");
2674 });
2675 }
2676
2677 #[async_test]
2678 async fn test_state_store_waits_to_acquire_lock_before_removing_room() {
2679 let state_store = SaveLockedStateStore::new(MemoryStore::new().into_state_store());
2680
2681 let lock_task = spawn({
2683 let state_store = state_store.clone();
2684 async move {
2685 let lock = state_store.lock();
2686 let _guard = lock.lock().await;
2687 sleep(Duration::from_secs(5)).await;
2688 }
2689 });
2690
2691 let remove_task =
2694 spawn(async move { state_store.remove_room(room_id!("!room")).await });
2695
2696 assert_matches!(future::select(lock_task, remove_task).await, Either::Left((_, remove_task)) => {
2699 timeout(Duration::from_millis(100), remove_task)
2700 .await
2701 .expect("task completes before timeout")
2702 .expect("task completes successfully")
2703 .expect("task saves changes");
2704 });
2705 }
2706 }
2707}