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(
168 &self,
169 room_id: &RoomId,
170 event_type: StateEventType,
171 state_keys: &[&str],
172 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error>;
173
174 async fn get_profile(
182 &self,
183 room_id: &RoomId,
184 user_id: &UserId,
185 ) -> Result<Option<MinimalRoomMemberEvent>, Self::Error>;
186
187 async fn get_profiles<'a>(
195 &self,
196 room_id: &RoomId,
197 user_ids: &'a [OwnedUserId],
198 ) -> Result<BTreeMap<&'a UserId, MinimalRoomMemberEvent>, Self::Error>;
199
200 async fn get_user_ids(
203 &self,
204 room_id: &RoomId,
205 memberships: RoomMemberships,
206 ) -> Result<Vec<OwnedUserId>, Self::Error>;
207
208 async fn get_room_infos(
210 &self,
211 room_load_settings: &RoomLoadSettings,
212 ) -> Result<Vec<RoomInfo>, Self::Error>;
213
214 async fn get_users_with_display_name(
222 &self,
223 room_id: &RoomId,
224 display_name: &DisplayName,
225 ) -> Result<BTreeSet<OwnedUserId>, Self::Error>;
226
227 async fn get_users_with_display_names<'a>(
235 &self,
236 room_id: &RoomId,
237 display_names: &'a [DisplayName],
238 ) -> Result<HashMap<&'a DisplayName, BTreeSet<OwnedUserId>>, Self::Error>;
239
240 async fn get_account_data_event(
246 &self,
247 event_type: GlobalAccountDataEventType,
248 ) -> Result<Option<Raw<AnyGlobalAccountDataEvent>>, Self::Error>;
249
250 async fn get_room_account_data_event(
259 &self,
260 room_id: &RoomId,
261 event_type: RoomAccountDataEventType,
262 ) -> Result<Option<Raw<AnyRoomAccountDataEvent>>, Self::Error>;
263
264 async fn get_user_room_receipt_event(
275 &self,
276 room_id: &RoomId,
277 receipt_type: ReceiptType,
278 receipt_thread: &ReceiptThread,
279 user_id: &UserId,
280 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error>;
281
282 async fn get_event_room_receipt_events(
294 &self,
295 room_id: &RoomId,
296 receipt_type: ReceiptType,
297 receipt_thread: &ReceiptThread,
298 event_id: &EventId,
299 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error>;
300
301 async fn get_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error>;
307
308 async fn set_custom_value(
316 &self,
317 key: &[u8],
318 value: Vec<u8>,
319 ) -> Result<Option<Vec<u8>>, Self::Error>;
320
321 async fn set_custom_value_no_read(
334 &self,
335 key: &[u8],
336 value: Vec<u8>,
337 ) -> Result<(), Self::Error> {
338 self.set_custom_value(key, value).await.map(|_| ())
339 }
340
341 async fn remove_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error>;
347
348 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error>;
354
355 async fn save_send_queue_request(
365 &self,
366 room_id: &RoomId,
367 transaction_id: OwnedTransactionId,
368 created_at: MilliSecondsSinceUnixEpoch,
369 request: QueuedRequestKind,
370 priority: usize,
371 ) -> Result<(), Self::Error>;
372
373 async fn update_send_queue_request(
385 &self,
386 room_id: &RoomId,
387 transaction_id: &TransactionId,
388 content: QueuedRequestKind,
389 ) -> Result<bool, Self::Error>;
390
391 async fn remove_send_queue_request(
397 &self,
398 room_id: &RoomId,
399 transaction_id: &TransactionId,
400 ) -> Result<bool, Self::Error>;
401
402 async fn load_send_queue_requests(
408 &self,
409 room_id: &RoomId,
410 ) -> Result<Vec<QueuedRequest>, Self::Error>;
411
412 async fn update_send_queue_request_status(
415 &self,
416 room_id: &RoomId,
417 transaction_id: &TransactionId,
418 error: Option<QueueWedgeError>,
419 ) -> Result<(), Self::Error>;
420
421 async fn load_rooms_with_unsent_requests(&self) -> Result<Vec<OwnedRoomId>, Self::Error>;
423
424 async fn save_dependent_queued_request(
427 &self,
428 room_id: &RoomId,
429 parent_txn_id: &TransactionId,
430 own_txn_id: ChildTransactionId,
431 created_at: MilliSecondsSinceUnixEpoch,
432 content: DependentQueuedRequestKind,
433 ) -> Result<(), Self::Error>;
434
435 async fn mark_dependent_queued_requests_as_ready(
444 &self,
445 room_id: &RoomId,
446 parent_txn_id: &TransactionId,
447 sent_parent_key: SentRequestKey,
448 ) -> Result<usize, Self::Error>;
449
450 async fn update_dependent_queued_request(
454 &self,
455 room_id: &RoomId,
456 own_transaction_id: &ChildTransactionId,
457 new_content: DependentQueuedRequestKind,
458 ) -> Result<bool, Self::Error>;
459
460 async fn remove_dependent_queued_request(
465 &self,
466 room: &RoomId,
467 own_txn_id: &ChildTransactionId,
468 ) -> Result<bool, Self::Error>;
469
470 async fn load_dependent_queued_requests(
476 &self,
477 room: &RoomId,
478 ) -> Result<Vec<DependentQueuedRequest>, Self::Error>;
479
480 async fn upsert_thread_subscriptions(
490 &self,
491 updates: Vec<(&RoomId, &EventId, StoredThreadSubscription)>,
492 ) -> Result<(), Self::Error>;
493
494 async fn remove_thread_subscription(
498 &self,
499 room: &RoomId,
500 thread_id: &EventId,
501 ) -> Result<(), Self::Error>;
502
503 async fn load_thread_subscription(
507 &self,
508 room: &RoomId,
509 thread_id: &EventId,
510 ) -> Result<Option<StoredThreadSubscription>, Self::Error>;
511
512 async fn get_global_profile(
521 &self,
522 user_id: &UserId,
523 ) -> Result<Option<UserProfile>, Self::Error>;
524
525 async fn get_global_profiles<'a>(
530 &self,
531 user_ids: &'a [OwnedUserId],
532 ) -> Result<BTreeMap<&'a UserId, UserProfile>, Self::Error>;
533
534 async fn get_missing_global_profiles<'a>(
541 &self,
542 user_ids: &'a [OwnedUserId],
543 ) -> Result<Vec<&'a UserId>, Self::Error>;
544
545 async fn close(&self) -> Result<(), Self::Error>;
551
552 async fn reopen(&self) -> Result<(), Self::Error>;
555
556 #[doc(hidden)]
562 async fn optimize(&self) -> Result<(), Self::Error>;
563
564 async fn get_size(&self) -> Result<Option<usize>, Self::Error>;
566}
567
568#[cfg_attr(target_family = "wasm", async_trait(?Send))]
569#[cfg_attr(not(target_family = "wasm"), async_trait)]
570impl<T: StateStore> StateStore for &T {
571 type Error = T::Error;
572
573 async fn get_kv_data(
574 &self,
575 key: StateStoreDataKey<'_>,
576 ) -> Result<Option<StateStoreDataValue>, Self::Error> {
577 (*self).get_kv_data(key).await
578 }
579
580 async fn set_kv_data(
581 &self,
582 key: StateStoreDataKey<'_>,
583 value: StateStoreDataValue,
584 ) -> Result<(), Self::Error> {
585 (*self).set_kv_data(key, value).await
586 }
587
588 async fn remove_kv_data(&self, key: StateStoreDataKey<'_>) -> Result<(), Self::Error> {
589 (*self).remove_kv_data(key).await
590 }
591
592 async fn save_changes(&self, changes: &StateChanges) -> Result<(), Self::Error> {
593 (*self).save_changes(changes).await
594 }
595
596 async fn get_presence_event(
597 &self,
598 user_id: &UserId,
599 ) -> Result<Option<Raw<PresenceEvent>>, Self::Error> {
600 (*self).get_presence_event(user_id).await
601 }
602
603 async fn get_presence_events(
604 &self,
605 user_ids: &[OwnedUserId],
606 ) -> Result<Vec<Raw<PresenceEvent>>, Self::Error> {
607 (*self).get_presence_events(user_ids).await
608 }
609
610 async fn get_state_event(
611 &self,
612 room_id: &RoomId,
613 event_type: StateEventType,
614 state_key: &str,
615 ) -> Result<Option<RawAnySyncOrStrippedState>, Self::Error> {
616 (*self).get_state_event(room_id, event_type, state_key).await
617 }
618
619 async fn get_state_events(
620 &self,
621 room_id: &RoomId,
622 event_type: StateEventType,
623 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
624 (*self).get_state_events(room_id, event_type).await
625 }
626
627 async fn get_state_events_for_keys(
628 &self,
629 room_id: &RoomId,
630 event_type: StateEventType,
631 state_keys: &[&str],
632 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
633 (*self).get_state_events_for_keys(room_id, event_type, state_keys).await
634 }
635
636 async fn get_profile(
637 &self,
638 room_id: &RoomId,
639 user_id: &UserId,
640 ) -> Result<Option<MinimalRoomMemberEvent>, Self::Error> {
641 (*self).get_profile(room_id, user_id).await
642 }
643
644 async fn get_profiles<'a>(
645 &self,
646 room_id: &RoomId,
647 user_ids: &'a [OwnedUserId],
648 ) -> Result<BTreeMap<&'a UserId, MinimalRoomMemberEvent>, Self::Error> {
649 (*self).get_profiles(room_id, user_ids).await
650 }
651
652 async fn get_user_ids(
653 &self,
654 room_id: &RoomId,
655 memberships: RoomMemberships,
656 ) -> Result<Vec<OwnedUserId>, Self::Error> {
657 (*self).get_user_ids(room_id, memberships).await
658 }
659
660 async fn get_room_infos(
661 &self,
662 room_load_settings: &RoomLoadSettings,
663 ) -> Result<Vec<RoomInfo>, Self::Error> {
664 (*self).get_room_infos(room_load_settings).await
665 }
666
667 async fn get_users_with_display_name(
668 &self,
669 room_id: &RoomId,
670 display_name: &DisplayName,
671 ) -> Result<BTreeSet<OwnedUserId>, Self::Error> {
672 (*self).get_users_with_display_name(room_id, display_name).await
673 }
674
675 async fn get_users_with_display_names<'a>(
676 &self,
677 room_id: &RoomId,
678 display_names: &'a [DisplayName],
679 ) -> Result<HashMap<&'a DisplayName, BTreeSet<OwnedUserId>>, Self::Error> {
680 (*self).get_users_with_display_names(room_id, display_names).await
681 }
682
683 async fn get_account_data_event(
684 &self,
685 event_type: GlobalAccountDataEventType,
686 ) -> Result<Option<Raw<AnyGlobalAccountDataEvent>>, Self::Error> {
687 (*self).get_account_data_event(event_type).await
688 }
689
690 async fn get_room_account_data_event(
691 &self,
692 room_id: &RoomId,
693 event_type: RoomAccountDataEventType,
694 ) -> Result<Option<Raw<AnyRoomAccountDataEvent>>, Self::Error> {
695 (*self).get_room_account_data_event(room_id, event_type).await
696 }
697
698 async fn get_user_room_receipt_event(
699 &self,
700 room_id: &RoomId,
701 receipt_type: ReceiptType,
702 receipt_thread: &ReceiptThread,
703 user_id: &UserId,
704 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error> {
705 (*self).get_user_room_receipt_event(room_id, receipt_type, receipt_thread, user_id).await
706 }
707
708 async fn get_event_room_receipt_events(
709 &self,
710 room_id: &RoomId,
711 receipt_type: ReceiptType,
712 receipt_thread: &ReceiptThread,
713 event_id: &EventId,
714 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error> {
715 (*self).get_event_room_receipt_events(room_id, receipt_type, receipt_thread, event_id).await
716 }
717
718 async fn get_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
719 (*self).get_custom_value(key).await
720 }
721
722 async fn set_custom_value(
723 &self,
724 key: &[u8],
725 value: Vec<u8>,
726 ) -> Result<Option<Vec<u8>>, Self::Error> {
727 (*self).set_custom_value(key, value).await
728 }
729
730 async fn remove_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
731 (*self).remove_custom_value(key).await
732 }
733
734 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error> {
735 (*self).remove_room(room_id).await
736 }
737
738 async fn save_send_queue_request(
739 &self,
740 room_id: &RoomId,
741 transaction_id: OwnedTransactionId,
742 created_at: MilliSecondsSinceUnixEpoch,
743 request: QueuedRequestKind,
744 priority: usize,
745 ) -> Result<(), Self::Error> {
746 (*self)
747 .save_send_queue_request(room_id, transaction_id, created_at, request, priority)
748 .await
749 }
750
751 async fn update_send_queue_request(
752 &self,
753 room_id: &RoomId,
754 transaction_id: &TransactionId,
755 content: QueuedRequestKind,
756 ) -> Result<bool, Self::Error> {
757 (*self).update_send_queue_request(room_id, transaction_id, content).await
758 }
759
760 async fn remove_send_queue_request(
761 &self,
762 room_id: &RoomId,
763 transaction_id: &TransactionId,
764 ) -> Result<bool, Self::Error> {
765 (*self).remove_send_queue_request(room_id, transaction_id).await
766 }
767
768 async fn load_send_queue_requests(
769 &self,
770 room_id: &RoomId,
771 ) -> Result<Vec<QueuedRequest>, Self::Error> {
772 (*self).load_send_queue_requests(room_id).await
773 }
774
775 async fn update_send_queue_request_status(
776 &self,
777 room_id: &RoomId,
778 transaction_id: &TransactionId,
779 error: Option<QueueWedgeError>,
780 ) -> Result<(), Self::Error> {
781 (*self).update_send_queue_request_status(room_id, transaction_id, error).await
782 }
783
784 async fn load_rooms_with_unsent_requests(&self) -> Result<Vec<OwnedRoomId>, Self::Error> {
785 (*self).load_rooms_with_unsent_requests().await
786 }
787
788 async fn save_dependent_queued_request(
789 &self,
790 room_id: &RoomId,
791 parent_txn_id: &TransactionId,
792 own_txn_id: ChildTransactionId,
793 created_at: MilliSecondsSinceUnixEpoch,
794 content: DependentQueuedRequestKind,
795 ) -> Result<(), Self::Error> {
796 (*self)
797 .save_dependent_queued_request(room_id, parent_txn_id, own_txn_id, created_at, content)
798 .await
799 }
800
801 async fn mark_dependent_queued_requests_as_ready(
802 &self,
803 room_id: &RoomId,
804 parent_txn_id: &TransactionId,
805 sent_parent_key: SentRequestKey,
806 ) -> Result<usize, Self::Error> {
807 (*self)
808 .mark_dependent_queued_requests_as_ready(room_id, parent_txn_id, sent_parent_key)
809 .await
810 }
811
812 async fn update_dependent_queued_request(
813 &self,
814 room_id: &RoomId,
815 own_transaction_id: &ChildTransactionId,
816 new_content: DependentQueuedRequestKind,
817 ) -> Result<bool, Self::Error> {
818 (*self).update_dependent_queued_request(room_id, own_transaction_id, new_content).await
819 }
820
821 async fn remove_dependent_queued_request(
822 &self,
823 room: &RoomId,
824 own_txn_id: &ChildTransactionId,
825 ) -> Result<bool, Self::Error> {
826 (*self).remove_dependent_queued_request(room, own_txn_id).await
827 }
828
829 async fn load_dependent_queued_requests(
830 &self,
831 room: &RoomId,
832 ) -> Result<Vec<DependentQueuedRequest>, Self::Error> {
833 (*self).load_dependent_queued_requests(room).await
834 }
835
836 async fn upsert_thread_subscriptions(
837 &self,
838 updates: Vec<(&RoomId, &EventId, StoredThreadSubscription)>,
839 ) -> Result<(), Self::Error> {
840 (*self).upsert_thread_subscriptions(updates).await
841 }
842
843 async fn remove_thread_subscription(
844 &self,
845 room: &RoomId,
846 thread_id: &EventId,
847 ) -> Result<(), Self::Error> {
848 (*self).remove_thread_subscription(room, thread_id).await
849 }
850
851 async fn load_thread_subscription(
852 &self,
853 room: &RoomId,
854 thread_id: &EventId,
855 ) -> Result<Option<StoredThreadSubscription>, Self::Error> {
856 (*self).load_thread_subscription(room, thread_id).await
857 }
858
859 async fn get_global_profile(
860 &self,
861 user_id: &UserId,
862 ) -> Result<Option<UserProfile>, Self::Error> {
863 (*self).get_global_profile(user_id).await
864 }
865
866 async fn get_global_profiles<'a>(
867 &self,
868 user_ids: &'a [OwnedUserId],
869 ) -> Result<BTreeMap<&'a UserId, UserProfile>, Self::Error> {
870 (*self).get_global_profiles(user_ids).await
871 }
872
873 async fn get_missing_global_profiles<'a>(
874 &self,
875 user_ids: &'a [OwnedUserId],
876 ) -> Result<Vec<&'a UserId>, Self::Error> {
877 (*self).get_missing_global_profiles(user_ids).await
878 }
879
880 async fn close(&self) -> Result<(), Self::Error> {
881 (*self).close().await
882 }
883
884 async fn reopen(&self) -> Result<(), Self::Error> {
885 (*self).reopen().await
886 }
887
888 async fn optimize(&self) -> Result<(), Self::Error> {
889 (*self).optimize().await
890 }
891
892 async fn get_size(&self) -> Result<Option<usize>, Self::Error> {
893 (*self).get_size().await
894 }
895}
896
897#[cfg_attr(target_family = "wasm", async_trait(?Send))]
898#[cfg_attr(not(target_family = "wasm"), async_trait)]
899impl<T: StateStore + ?Sized> StateStore for Arc<T> {
900 type Error = T::Error;
901
902 async fn get_kv_data(
903 &self,
904 key: StateStoreDataKey<'_>,
905 ) -> Result<Option<StateStoreDataValue>, Self::Error> {
906 self.deref().get_kv_data(key).await
907 }
908
909 async fn set_kv_data(
910 &self,
911 key: StateStoreDataKey<'_>,
912 value: StateStoreDataValue,
913 ) -> Result<(), Self::Error> {
914 self.deref().set_kv_data(key, value).await
915 }
916
917 async fn remove_kv_data(&self, key: StateStoreDataKey<'_>) -> Result<(), Self::Error> {
918 self.deref().remove_kv_data(key).await
919 }
920
921 async fn save_changes(&self, changes: &StateChanges) -> Result<(), Self::Error> {
922 self.deref().save_changes(changes).await
923 }
924
925 async fn get_presence_event(
926 &self,
927 user_id: &UserId,
928 ) -> Result<Option<Raw<PresenceEvent>>, Self::Error> {
929 self.deref().get_presence_event(user_id).await
930 }
931
932 async fn get_presence_events(
933 &self,
934 user_ids: &[OwnedUserId],
935 ) -> Result<Vec<Raw<PresenceEvent>>, Self::Error> {
936 self.deref().get_presence_events(user_ids).await
937 }
938
939 async fn get_state_event(
940 &self,
941 room_id: &RoomId,
942 event_type: StateEventType,
943 state_key: &str,
944 ) -> Result<Option<RawAnySyncOrStrippedState>, Self::Error> {
945 self.deref().get_state_event(room_id, event_type, state_key).await
946 }
947
948 async fn get_state_events(
949 &self,
950 room_id: &RoomId,
951 event_type: StateEventType,
952 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
953 self.deref().get_state_events(room_id, event_type).await
954 }
955
956 async fn get_state_events_for_keys(
957 &self,
958 room_id: &RoomId,
959 event_type: StateEventType,
960 state_keys: &[&str],
961 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
962 self.deref().get_state_events_for_keys(room_id, event_type, state_keys).await
963 }
964
965 async fn get_profile(
966 &self,
967 room_id: &RoomId,
968 user_id: &UserId,
969 ) -> Result<Option<MinimalRoomMemberEvent>, Self::Error> {
970 self.deref().get_profile(room_id, user_id).await
971 }
972
973 async fn get_profiles<'a>(
974 &self,
975 room_id: &RoomId,
976 user_ids: &'a [OwnedUserId],
977 ) -> Result<BTreeMap<&'a UserId, MinimalRoomMemberEvent>, Self::Error> {
978 self.deref().get_profiles(room_id, user_ids).await
979 }
980
981 async fn get_user_ids(
982 &self,
983 room_id: &RoomId,
984 memberships: RoomMemberships,
985 ) -> Result<Vec<OwnedUserId>, Self::Error> {
986 self.deref().get_user_ids(room_id, memberships).await
987 }
988
989 async fn get_room_infos(
990 &self,
991 room_load_settings: &RoomLoadSettings,
992 ) -> Result<Vec<RoomInfo>, Self::Error> {
993 self.deref().get_room_infos(room_load_settings).await
994 }
995
996 async fn get_users_with_display_name(
997 &self,
998 room_id: &RoomId,
999 display_name: &DisplayName,
1000 ) -> Result<BTreeSet<OwnedUserId>, Self::Error> {
1001 self.deref().get_users_with_display_name(room_id, display_name).await
1002 }
1003
1004 async fn get_users_with_display_names<'a>(
1005 &self,
1006 room_id: &RoomId,
1007 display_names: &'a [DisplayName],
1008 ) -> Result<HashMap<&'a DisplayName, BTreeSet<OwnedUserId>>, Self::Error> {
1009 self.deref().get_users_with_display_names(room_id, display_names).await
1010 }
1011
1012 async fn get_account_data_event(
1013 &self,
1014 event_type: GlobalAccountDataEventType,
1015 ) -> Result<Option<Raw<AnyGlobalAccountDataEvent>>, Self::Error> {
1016 self.deref().get_account_data_event(event_type).await
1017 }
1018
1019 async fn get_room_account_data_event(
1020 &self,
1021 room_id: &RoomId,
1022 event_type: RoomAccountDataEventType,
1023 ) -> Result<Option<Raw<AnyRoomAccountDataEvent>>, Self::Error> {
1024 self.deref().get_room_account_data_event(room_id, event_type).await
1025 }
1026
1027 async fn get_user_room_receipt_event(
1028 &self,
1029 room_id: &RoomId,
1030 receipt_type: ReceiptType,
1031 receipt_thread: &ReceiptThread,
1032 user_id: &UserId,
1033 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error> {
1034 self.deref()
1035 .get_user_room_receipt_event(room_id, receipt_type, receipt_thread, user_id)
1036 .await
1037 }
1038
1039 async fn get_event_room_receipt_events(
1040 &self,
1041 room_id: &RoomId,
1042 receipt_type: ReceiptType,
1043 receipt_thread: &ReceiptThread,
1044 event_id: &EventId,
1045 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error> {
1046 self.deref()
1047 .get_event_room_receipt_events(room_id, receipt_type, receipt_thread, event_id)
1048 .await
1049 }
1050
1051 async fn get_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1052 self.deref().get_custom_value(key).await
1053 }
1054
1055 async fn set_custom_value(
1056 &self,
1057 key: &[u8],
1058 value: Vec<u8>,
1059 ) -> Result<Option<Vec<u8>>, Self::Error> {
1060 self.deref().set_custom_value(key, value).await
1061 }
1062
1063 async fn remove_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1064 self.deref().remove_custom_value(key).await
1065 }
1066
1067 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error> {
1068 self.deref().remove_room(room_id).await
1069 }
1070
1071 async fn save_send_queue_request(
1072 &self,
1073 room_id: &RoomId,
1074 transaction_id: OwnedTransactionId,
1075 created_at: MilliSecondsSinceUnixEpoch,
1076 request: QueuedRequestKind,
1077 priority: usize,
1078 ) -> Result<(), Self::Error> {
1079 self.deref()
1080 .save_send_queue_request(room_id, transaction_id, created_at, request, priority)
1081 .await
1082 }
1083
1084 async fn update_send_queue_request(
1085 &self,
1086 room_id: &RoomId,
1087 transaction_id: &TransactionId,
1088 content: QueuedRequestKind,
1089 ) -> Result<bool, Self::Error> {
1090 self.deref().update_send_queue_request(room_id, transaction_id, content).await
1091 }
1092
1093 async fn remove_send_queue_request(
1094 &self,
1095 room_id: &RoomId,
1096 transaction_id: &TransactionId,
1097 ) -> Result<bool, Self::Error> {
1098 self.deref().remove_send_queue_request(room_id, transaction_id).await
1099 }
1100
1101 async fn load_send_queue_requests(
1102 &self,
1103 room_id: &RoomId,
1104 ) -> Result<Vec<QueuedRequest>, Self::Error> {
1105 self.deref().load_send_queue_requests(room_id).await
1106 }
1107
1108 async fn update_send_queue_request_status(
1109 &self,
1110 room_id: &RoomId,
1111 transaction_id: &TransactionId,
1112 error: Option<QueueWedgeError>,
1113 ) -> Result<(), Self::Error> {
1114 self.deref().update_send_queue_request_status(room_id, transaction_id, error).await
1115 }
1116
1117 async fn load_rooms_with_unsent_requests(&self) -> Result<Vec<OwnedRoomId>, Self::Error> {
1118 self.deref().load_rooms_with_unsent_requests().await
1119 }
1120
1121 async fn save_dependent_queued_request(
1122 &self,
1123 room_id: &RoomId,
1124 parent_txn_id: &TransactionId,
1125 own_txn_id: ChildTransactionId,
1126 created_at: MilliSecondsSinceUnixEpoch,
1127 content: DependentQueuedRequestKind,
1128 ) -> Result<(), Self::Error> {
1129 self.deref()
1130 .save_dependent_queued_request(room_id, parent_txn_id, own_txn_id, created_at, content)
1131 .await
1132 }
1133
1134 async fn mark_dependent_queued_requests_as_ready(
1135 &self,
1136 room_id: &RoomId,
1137 parent_txn_id: &TransactionId,
1138 sent_parent_key: SentRequestKey,
1139 ) -> Result<usize, Self::Error> {
1140 self.deref()
1141 .mark_dependent_queued_requests_as_ready(room_id, parent_txn_id, sent_parent_key)
1142 .await
1143 }
1144
1145 async fn update_dependent_queued_request(
1146 &self,
1147 room_id: &RoomId,
1148 own_transaction_id: &ChildTransactionId,
1149 new_content: DependentQueuedRequestKind,
1150 ) -> Result<bool, Self::Error> {
1151 self.deref().update_dependent_queued_request(room_id, own_transaction_id, new_content).await
1152 }
1153
1154 async fn remove_dependent_queued_request(
1155 &self,
1156 room: &RoomId,
1157 own_txn_id: &ChildTransactionId,
1158 ) -> Result<bool, Self::Error> {
1159 self.deref().remove_dependent_queued_request(room, own_txn_id).await
1160 }
1161
1162 async fn load_dependent_queued_requests(
1163 &self,
1164 room: &RoomId,
1165 ) -> Result<Vec<DependentQueuedRequest>, Self::Error> {
1166 self.deref().load_dependent_queued_requests(room).await
1167 }
1168
1169 async fn upsert_thread_subscriptions(
1170 &self,
1171 updates: Vec<(&RoomId, &EventId, StoredThreadSubscription)>,
1172 ) -> Result<(), Self::Error> {
1173 self.deref().upsert_thread_subscriptions(updates).await
1174 }
1175
1176 async fn remove_thread_subscription(
1177 &self,
1178 room: &RoomId,
1179 thread_id: &EventId,
1180 ) -> Result<(), Self::Error> {
1181 self.deref().remove_thread_subscription(room, thread_id).await
1182 }
1183
1184 async fn load_thread_subscription(
1185 &self,
1186 room: &RoomId,
1187 thread_id: &EventId,
1188 ) -> Result<Option<StoredThreadSubscription>, Self::Error> {
1189 self.deref().load_thread_subscription(room, thread_id).await
1190 }
1191
1192 async fn get_global_profile(
1193 &self,
1194 user_id: &UserId,
1195 ) -> Result<Option<UserProfile>, Self::Error> {
1196 self.deref().get_global_profile(user_id).await
1197 }
1198
1199 async fn get_global_profiles<'a>(
1200 &self,
1201 user_ids: &'a [OwnedUserId],
1202 ) -> Result<BTreeMap<&'a UserId, UserProfile>, Self::Error> {
1203 self.deref().get_global_profiles(user_ids).await
1204 }
1205
1206 async fn get_missing_global_profiles<'a>(
1207 &self,
1208 user_ids: &'a [OwnedUserId],
1209 ) -> Result<Vec<&'a UserId>, Self::Error> {
1210 self.deref().get_missing_global_profiles(user_ids).await
1211 }
1212
1213 async fn close(&self) -> Result<(), Self::Error> {
1214 self.deref().close().await
1215 }
1216
1217 async fn reopen(&self) -> Result<(), Self::Error> {
1218 self.deref().reopen().await
1219 }
1220
1221 async fn optimize(&self) -> Result<(), Self::Error> {
1222 self.deref().optimize().await
1223 }
1224
1225 async fn get_size(&self) -> Result<Option<usize>, Self::Error> {
1226 self.deref().get_size().await
1227 }
1228}
1229
1230#[repr(transparent)]
1231struct EraseStateStoreError<T>(T);
1232
1233#[cfg(not(tarpaulin_include))]
1234impl<T: fmt::Debug> fmt::Debug for EraseStateStoreError<T> {
1235 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1236 self.0.fmt(f)
1237 }
1238}
1239
1240#[cfg_attr(target_family = "wasm", async_trait(?Send))]
1241#[cfg_attr(not(target_family = "wasm"), async_trait)]
1242impl<T: StateStore> StateStore for EraseStateStoreError<T> {
1243 type Error = StoreError;
1244
1245 async fn get_kv_data(
1246 &self,
1247 key: StateStoreDataKey<'_>,
1248 ) -> Result<Option<StateStoreDataValue>, Self::Error> {
1249 self.0.get_kv_data(key).await.map_err(Into::into)
1250 }
1251
1252 async fn set_kv_data(
1253 &self,
1254 key: StateStoreDataKey<'_>,
1255 value: StateStoreDataValue,
1256 ) -> Result<(), Self::Error> {
1257 self.0.set_kv_data(key, value).await.map_err(Into::into)
1258 }
1259
1260 async fn remove_kv_data(&self, key: StateStoreDataKey<'_>) -> Result<(), Self::Error> {
1261 self.0.remove_kv_data(key).await.map_err(Into::into)
1262 }
1263
1264 async fn save_changes(&self, changes: &StateChanges) -> Result<(), Self::Error> {
1265 self.0.save_changes(changes).await.map_err(Into::into)
1266 }
1267
1268 async fn get_presence_event(
1269 &self,
1270 user_id: &UserId,
1271 ) -> Result<Option<Raw<PresenceEvent>>, Self::Error> {
1272 self.0.get_presence_event(user_id).await.map_err(Into::into)
1273 }
1274
1275 async fn get_presence_events(
1276 &self,
1277 user_ids: &[OwnedUserId],
1278 ) -> Result<Vec<Raw<PresenceEvent>>, Self::Error> {
1279 self.0.get_presence_events(user_ids).await.map_err(Into::into)
1280 }
1281
1282 async fn get_state_event(
1283 &self,
1284 room_id: &RoomId,
1285 event_type: StateEventType,
1286 state_key: &str,
1287 ) -> Result<Option<RawAnySyncOrStrippedState>, Self::Error> {
1288 self.0.get_state_event(room_id, event_type, state_key).await.map_err(Into::into)
1289 }
1290
1291 async fn get_state_events(
1292 &self,
1293 room_id: &RoomId,
1294 event_type: StateEventType,
1295 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
1296 self.0.get_state_events(room_id, event_type).await.map_err(Into::into)
1297 }
1298
1299 async fn get_state_events_for_keys(
1300 &self,
1301 room_id: &RoomId,
1302 event_type: StateEventType,
1303 state_keys: &[&str],
1304 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
1305 self.0.get_state_events_for_keys(room_id, event_type, state_keys).await.map_err(Into::into)
1306 }
1307
1308 async fn get_profile(
1309 &self,
1310 room_id: &RoomId,
1311 user_id: &UserId,
1312 ) -> Result<Option<MinimalRoomMemberEvent>, Self::Error> {
1313 self.0.get_profile(room_id, user_id).await.map_err(Into::into)
1314 }
1315
1316 async fn get_profiles<'a>(
1317 &self,
1318 room_id: &RoomId,
1319 user_ids: &'a [OwnedUserId],
1320 ) -> Result<BTreeMap<&'a UserId, MinimalRoomMemberEvent>, Self::Error> {
1321 self.0.get_profiles(room_id, user_ids).await.map_err(Into::into)
1322 }
1323
1324 async fn get_user_ids(
1325 &self,
1326 room_id: &RoomId,
1327 memberships: RoomMemberships,
1328 ) -> Result<Vec<OwnedUserId>, Self::Error> {
1329 self.0.get_user_ids(room_id, memberships).await.map_err(Into::into)
1330 }
1331
1332 async fn get_room_infos(
1333 &self,
1334 room_load_settings: &RoomLoadSettings,
1335 ) -> Result<Vec<RoomInfo>, Self::Error> {
1336 self.0.get_room_infos(room_load_settings).await.map_err(Into::into)
1337 }
1338
1339 async fn get_users_with_display_name(
1340 &self,
1341 room_id: &RoomId,
1342 display_name: &DisplayName,
1343 ) -> Result<BTreeSet<OwnedUserId>, Self::Error> {
1344 self.0.get_users_with_display_name(room_id, display_name).await.map_err(Into::into)
1345 }
1346
1347 async fn get_users_with_display_names<'a>(
1348 &self,
1349 room_id: &RoomId,
1350 display_names: &'a [DisplayName],
1351 ) -> Result<HashMap<&'a DisplayName, BTreeSet<OwnedUserId>>, Self::Error> {
1352 self.0.get_users_with_display_names(room_id, display_names).await.map_err(Into::into)
1353 }
1354
1355 async fn get_account_data_event(
1356 &self,
1357 event_type: GlobalAccountDataEventType,
1358 ) -> Result<Option<Raw<AnyGlobalAccountDataEvent>>, Self::Error> {
1359 self.0.get_account_data_event(event_type).await.map_err(Into::into)
1360 }
1361
1362 async fn get_room_account_data_event(
1363 &self,
1364 room_id: &RoomId,
1365 event_type: RoomAccountDataEventType,
1366 ) -> Result<Option<Raw<AnyRoomAccountDataEvent>>, Self::Error> {
1367 self.0.get_room_account_data_event(room_id, event_type).await.map_err(Into::into)
1368 }
1369
1370 async fn get_user_room_receipt_event(
1371 &self,
1372 room_id: &RoomId,
1373 receipt_type: ReceiptType,
1374 receipt_thread: &ReceiptThread,
1375 user_id: &UserId,
1376 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error> {
1377 self.0
1378 .get_user_room_receipt_event(room_id, receipt_type, receipt_thread, user_id)
1379 .await
1380 .map_err(Into::into)
1381 }
1382
1383 async fn get_event_room_receipt_events(
1384 &self,
1385 room_id: &RoomId,
1386 receipt_type: ReceiptType,
1387 receipt_thread: &ReceiptThread,
1388 event_id: &EventId,
1389 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error> {
1390 self.0
1391 .get_event_room_receipt_events(room_id, receipt_type, receipt_thread, event_id)
1392 .await
1393 .map_err(Into::into)
1394 }
1395
1396 async fn get_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1397 self.0.get_custom_value(key).await.map_err(Into::into)
1398 }
1399
1400 async fn set_custom_value(
1401 &self,
1402 key: &[u8],
1403 value: Vec<u8>,
1404 ) -> Result<Option<Vec<u8>>, Self::Error> {
1405 self.0.set_custom_value(key, value).await.map_err(Into::into)
1406 }
1407
1408 async fn remove_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1409 self.0.remove_custom_value(key).await.map_err(Into::into)
1410 }
1411
1412 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error> {
1413 self.0.remove_room(room_id).await.map_err(Into::into)
1414 }
1415
1416 async fn save_send_queue_request(
1417 &self,
1418 room_id: &RoomId,
1419 transaction_id: OwnedTransactionId,
1420 created_at: MilliSecondsSinceUnixEpoch,
1421 content: QueuedRequestKind,
1422 priority: usize,
1423 ) -> Result<(), Self::Error> {
1424 self.0
1425 .save_send_queue_request(room_id, transaction_id, created_at, content, priority)
1426 .await
1427 .map_err(Into::into)
1428 }
1429
1430 async fn update_send_queue_request(
1431 &self,
1432 room_id: &RoomId,
1433 transaction_id: &TransactionId,
1434 content: QueuedRequestKind,
1435 ) -> Result<bool, Self::Error> {
1436 self.0.update_send_queue_request(room_id, transaction_id, content).await.map_err(Into::into)
1437 }
1438
1439 async fn remove_send_queue_request(
1440 &self,
1441 room_id: &RoomId,
1442 transaction_id: &TransactionId,
1443 ) -> Result<bool, Self::Error> {
1444 self.0.remove_send_queue_request(room_id, transaction_id).await.map_err(Into::into)
1445 }
1446
1447 async fn load_send_queue_requests(
1448 &self,
1449 room_id: &RoomId,
1450 ) -> Result<Vec<QueuedRequest>, Self::Error> {
1451 self.0.load_send_queue_requests(room_id).await.map_err(Into::into)
1452 }
1453
1454 async fn update_send_queue_request_status(
1455 &self,
1456 room_id: &RoomId,
1457 transaction_id: &TransactionId,
1458 error: Option<QueueWedgeError>,
1459 ) -> Result<(), Self::Error> {
1460 self.0
1461 .update_send_queue_request_status(room_id, transaction_id, error)
1462 .await
1463 .map_err(Into::into)
1464 }
1465
1466 async fn load_rooms_with_unsent_requests(&self) -> Result<Vec<OwnedRoomId>, Self::Error> {
1467 self.0.load_rooms_with_unsent_requests().await.map_err(Into::into)
1468 }
1469
1470 async fn save_dependent_queued_request(
1471 &self,
1472 room_id: &RoomId,
1473 parent_txn_id: &TransactionId,
1474 own_txn_id: ChildTransactionId,
1475 created_at: MilliSecondsSinceUnixEpoch,
1476 content: DependentQueuedRequestKind,
1477 ) -> Result<(), Self::Error> {
1478 self.0
1479 .save_dependent_queued_request(room_id, parent_txn_id, own_txn_id, created_at, content)
1480 .await
1481 .map_err(Into::into)
1482 }
1483
1484 async fn mark_dependent_queued_requests_as_ready(
1485 &self,
1486 room_id: &RoomId,
1487 parent_txn_id: &TransactionId,
1488 sent_parent_key: SentRequestKey,
1489 ) -> Result<usize, Self::Error> {
1490 self.0
1491 .mark_dependent_queued_requests_as_ready(room_id, parent_txn_id, sent_parent_key)
1492 .await
1493 .map_err(Into::into)
1494 }
1495
1496 async fn remove_dependent_queued_request(
1497 &self,
1498 room_id: &RoomId,
1499 own_txn_id: &ChildTransactionId,
1500 ) -> Result<bool, Self::Error> {
1501 self.0.remove_dependent_queued_request(room_id, own_txn_id).await.map_err(Into::into)
1502 }
1503
1504 async fn load_dependent_queued_requests(
1505 &self,
1506 room_id: &RoomId,
1507 ) -> Result<Vec<DependentQueuedRequest>, Self::Error> {
1508 self.0.load_dependent_queued_requests(room_id).await.map_err(Into::into)
1509 }
1510
1511 async fn update_dependent_queued_request(
1512 &self,
1513 room_id: &RoomId,
1514 own_transaction_id: &ChildTransactionId,
1515 new_content: DependentQueuedRequestKind,
1516 ) -> Result<bool, Self::Error> {
1517 self.0
1518 .update_dependent_queued_request(room_id, own_transaction_id, new_content)
1519 .await
1520 .map_err(Into::into)
1521 }
1522
1523 async fn upsert_thread_subscriptions(
1524 &self,
1525 updates: Vec<(&RoomId, &EventId, StoredThreadSubscription)>,
1526 ) -> Result<(), Self::Error> {
1527 self.0.upsert_thread_subscriptions(updates).await.map_err(Into::into)
1528 }
1529
1530 async fn load_thread_subscription(
1531 &self,
1532 room: &RoomId,
1533 thread_id: &EventId,
1534 ) -> Result<Option<StoredThreadSubscription>, Self::Error> {
1535 self.0.load_thread_subscription(room, thread_id).await.map_err(Into::into)
1536 }
1537
1538 async fn remove_thread_subscription(
1539 &self,
1540 room: &RoomId,
1541 thread_id: &EventId,
1542 ) -> Result<(), Self::Error> {
1543 self.0.remove_thread_subscription(room, thread_id).await.map_err(Into::into)
1544 }
1545
1546 async fn get_global_profile(
1547 &self,
1548 user_id: &UserId,
1549 ) -> Result<Option<UserProfile>, Self::Error> {
1550 self.0.get_global_profile(user_id).await.map_err(Into::into)
1551 }
1552
1553 async fn get_global_profiles<'a>(
1554 &self,
1555 user_ids: &'a [OwnedUserId],
1556 ) -> Result<BTreeMap<&'a UserId, UserProfile>, Self::Error> {
1557 self.0.get_global_profiles(user_ids).await.map_err(Into::into)
1558 }
1559
1560 async fn get_missing_global_profiles<'a>(
1561 &self,
1562 user_ids: &'a [OwnedUserId],
1563 ) -> Result<Vec<&'a UserId>, Self::Error> {
1564 self.0.get_missing_global_profiles(user_ids).await.map_err(Into::into)
1565 }
1566
1567 async fn close(&self) -> Result<(), Self::Error> {
1568 self.0.close().await.map_err(Into::into)
1569 }
1570
1571 async fn reopen(&self) -> Result<(), Self::Error> {
1572 self.0.reopen().await.map_err(Into::into)
1573 }
1574
1575 async fn optimize(&self) -> Result<(), Self::Error> {
1576 self.0.optimize().await.map_err(Into::into)
1577 }
1578
1579 async fn get_size(&self) -> Result<Option<usize>, Self::Error> {
1580 self.0.get_size().await.map_err(Into::into)
1581 }
1582}
1583
1584#[derive(Debug, Clone)]
1587pub struct SaveLockedStateStore<T = Arc<DynStateStore>> {
1588 store: T,
1589 lock: Arc<Mutex<()>>,
1590}
1591
1592#[derive(Debug, Error)]
1596#[error("a mutex guard was provided, but it does not reference the correct mutex")]
1597pub struct IncorrectMutexGuardError;
1598
1599impl From<IncorrectMutexGuardError> for StoreError {
1600 fn from(value: IncorrectMutexGuardError) -> Self {
1601 Self::backend(value)
1602 }
1603}
1604
1605impl<T> SaveLockedStateStore<T> {
1606 pub fn new(store: T) -> Self {
1608 Self { store, lock: Arc::new(Mutex::new(())) }
1609 }
1610
1611 pub fn lock(&self) -> &Mutex<()> {
1614 self.lock.as_ref()
1615 }
1616}
1617
1618impl<T: StateStore> SaveLockedStateStore<T> {
1619 pub async fn save_changes_with_guard(
1623 &self,
1624 guard: &MutexGuard<'_, ()>,
1625 changes: &StateChanges,
1626 ) -> Result<(), StoreError> {
1627 if !std::ptr::eq(MutexGuard::mutex(guard), self.lock()) {
1628 Err(IncorrectMutexGuardError.into())
1629 } else {
1630 self.store.save_changes(changes).await.map_err(Into::into)
1631 }
1632 }
1633
1634 pub async fn remove_room_with_guard(
1638 &self,
1639 guard: &MutexGuard<'_, ()>,
1640 room_id: &RoomId,
1641 ) -> Result<(), StoreError> {
1642 if !std::ptr::eq(MutexGuard::mutex(guard), self.lock()) {
1643 Err(IncorrectMutexGuardError.into())
1644 } else {
1645 self.store.remove_room(room_id).await.map_err(Into::into)
1646 }
1647 }
1648}
1649
1650#[cfg_attr(target_family = "wasm", async_trait(?Send))]
1651#[cfg_attr(not(target_family = "wasm"), async_trait)]
1652impl<T: StateStore> StateStore for SaveLockedStateStore<T> {
1653 type Error = T::Error;
1654
1655 async fn get_kv_data(
1656 &self,
1657 key: StateStoreDataKey<'_>,
1658 ) -> Result<Option<StateStoreDataValue>, Self::Error> {
1659 self.store.get_kv_data(key).await
1660 }
1661
1662 async fn set_kv_data(
1663 &self,
1664 key: StateStoreDataKey<'_>,
1665 value: StateStoreDataValue,
1666 ) -> Result<(), Self::Error> {
1667 self.store.set_kv_data(key, value).await
1668 }
1669
1670 async fn remove_kv_data(&self, key: StateStoreDataKey<'_>) -> Result<(), Self::Error> {
1671 self.store.remove_kv_data(key).await
1672 }
1673
1674 async fn save_changes(&self, changes: &StateChanges) -> Result<(), Self::Error> {
1675 let _guard = self.lock.lock().await;
1676 self.store.save_changes(changes).await
1677 }
1678
1679 async fn get_presence_event(
1680 &self,
1681 user_id: &UserId,
1682 ) -> Result<Option<Raw<PresenceEvent>>, Self::Error> {
1683 self.store.get_presence_event(user_id).await
1684 }
1685
1686 async fn get_presence_events(
1687 &self,
1688 user_ids: &[OwnedUserId],
1689 ) -> Result<Vec<Raw<PresenceEvent>>, Self::Error> {
1690 self.store.get_presence_events(user_ids).await
1691 }
1692
1693 async fn get_state_event(
1694 &self,
1695 room_id: &RoomId,
1696 event_type: StateEventType,
1697 state_key: &str,
1698 ) -> Result<Option<RawAnySyncOrStrippedState>, Self::Error> {
1699 self.store.get_state_event(room_id, event_type, state_key).await
1700 }
1701
1702 async fn get_state_events(
1703 &self,
1704 room_id: &RoomId,
1705 event_type: StateEventType,
1706 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
1707 self.store.get_state_events(room_id, event_type).await
1708 }
1709
1710 async fn get_state_events_for_keys(
1711 &self,
1712 room_id: &RoomId,
1713 event_type: StateEventType,
1714 state_keys: &[&str],
1715 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
1716 self.store.get_state_events_for_keys(room_id, event_type, state_keys).await
1717 }
1718
1719 async fn get_profile(
1720 &self,
1721 room_id: &RoomId,
1722 user_id: &UserId,
1723 ) -> Result<Option<MinimalRoomMemberEvent>, Self::Error> {
1724 self.store.get_profile(room_id, user_id).await
1725 }
1726
1727 async fn get_profiles<'a>(
1728 &self,
1729 room_id: &RoomId,
1730 user_ids: &'a [OwnedUserId],
1731 ) -> Result<BTreeMap<&'a UserId, MinimalRoomMemberEvent>, Self::Error> {
1732 self.store.get_profiles(room_id, user_ids).await
1733 }
1734
1735 async fn get_user_ids(
1736 &self,
1737 room_id: &RoomId,
1738 memberships: RoomMemberships,
1739 ) -> Result<Vec<OwnedUserId>, Self::Error> {
1740 self.store.get_user_ids(room_id, memberships).await
1741 }
1742
1743 async fn get_room_infos(
1744 &self,
1745 room_load_settings: &RoomLoadSettings,
1746 ) -> Result<Vec<RoomInfo>, Self::Error> {
1747 self.store.get_room_infos(room_load_settings).await
1748 }
1749
1750 async fn get_users_with_display_name(
1751 &self,
1752 room_id: &RoomId,
1753 display_name: &DisplayName,
1754 ) -> Result<BTreeSet<OwnedUserId>, Self::Error> {
1755 self.store.get_users_with_display_name(room_id, display_name).await
1756 }
1757
1758 async fn get_users_with_display_names<'a>(
1759 &self,
1760 room_id: &RoomId,
1761 display_names: &'a [DisplayName],
1762 ) -> Result<HashMap<&'a DisplayName, BTreeSet<OwnedUserId>>, Self::Error> {
1763 self.store.get_users_with_display_names(room_id, display_names).await
1764 }
1765
1766 async fn get_account_data_event(
1767 &self,
1768 event_type: GlobalAccountDataEventType,
1769 ) -> Result<Option<Raw<AnyGlobalAccountDataEvent>>, Self::Error> {
1770 self.store.get_account_data_event(event_type).await
1771 }
1772
1773 async fn get_room_account_data_event(
1774 &self,
1775 room_id: &RoomId,
1776 event_type: RoomAccountDataEventType,
1777 ) -> Result<Option<Raw<AnyRoomAccountDataEvent>>, Self::Error> {
1778 self.store.get_room_account_data_event(room_id, event_type).await
1779 }
1780
1781 async fn get_user_room_receipt_event(
1782 &self,
1783 room_id: &RoomId,
1784 receipt_type: ReceiptType,
1785 receipt_thread: &ReceiptThread,
1786 user_id: &UserId,
1787 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error> {
1788 self.store.get_user_room_receipt_event(room_id, receipt_type, receipt_thread, user_id).await
1789 }
1790
1791 async fn get_event_room_receipt_events(
1792 &self,
1793 room_id: &RoomId,
1794 receipt_type: ReceiptType,
1795 receipt_thread: &ReceiptThread,
1796 event_id: &EventId,
1797 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error> {
1798 self.store
1799 .get_event_room_receipt_events(room_id, receipt_type, receipt_thread, event_id)
1800 .await
1801 }
1802
1803 async fn get_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1804 self.store.get_custom_value(key).await
1805 }
1806
1807 async fn set_custom_value(
1808 &self,
1809 key: &[u8],
1810 value: Vec<u8>,
1811 ) -> Result<Option<Vec<u8>>, Self::Error> {
1812 self.store.set_custom_value(key, value).await
1813 }
1814
1815 async fn remove_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1816 self.store.remove_custom_value(key).await
1817 }
1818
1819 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error> {
1820 let _guard = self.lock.lock().await;
1821 self.store.remove_room(room_id).await
1822 }
1823
1824 async fn save_send_queue_request(
1825 &self,
1826 room_id: &RoomId,
1827 transaction_id: OwnedTransactionId,
1828 created_at: MilliSecondsSinceUnixEpoch,
1829 request: QueuedRequestKind,
1830 priority: usize,
1831 ) -> Result<(), Self::Error> {
1832 self.store
1833 .save_send_queue_request(room_id, transaction_id, created_at, request, priority)
1834 .await
1835 }
1836
1837 async fn update_send_queue_request(
1838 &self,
1839 room_id: &RoomId,
1840 transaction_id: &TransactionId,
1841 content: QueuedRequestKind,
1842 ) -> Result<bool, Self::Error> {
1843 self.store.update_send_queue_request(room_id, transaction_id, content).await
1844 }
1845
1846 async fn remove_send_queue_request(
1847 &self,
1848 room_id: &RoomId,
1849 transaction_id: &TransactionId,
1850 ) -> Result<bool, Self::Error> {
1851 self.store.remove_send_queue_request(room_id, transaction_id).await
1852 }
1853
1854 async fn load_send_queue_requests(
1855 &self,
1856 room_id: &RoomId,
1857 ) -> Result<Vec<QueuedRequest>, Self::Error> {
1858 self.store.load_send_queue_requests(room_id).await
1859 }
1860
1861 async fn update_send_queue_request_status(
1862 &self,
1863 room_id: &RoomId,
1864 transaction_id: &TransactionId,
1865 error: Option<QueueWedgeError>,
1866 ) -> Result<(), Self::Error> {
1867 self.store.update_send_queue_request_status(room_id, transaction_id, error).await
1868 }
1869
1870 async fn load_rooms_with_unsent_requests(&self) -> Result<Vec<OwnedRoomId>, Self::Error> {
1871 self.store.load_rooms_with_unsent_requests().await
1872 }
1873
1874 async fn save_dependent_queued_request(
1875 &self,
1876 room_id: &RoomId,
1877 parent_txn_id: &TransactionId,
1878 own_txn_id: ChildTransactionId,
1879 created_at: MilliSecondsSinceUnixEpoch,
1880 content: DependentQueuedRequestKind,
1881 ) -> Result<(), Self::Error> {
1882 self.store
1883 .save_dependent_queued_request(room_id, parent_txn_id, own_txn_id, created_at, content)
1884 .await
1885 }
1886
1887 async fn mark_dependent_queued_requests_as_ready(
1888 &self,
1889 room_id: &RoomId,
1890 parent_txn_id: &TransactionId,
1891 sent_parent_key: SentRequestKey,
1892 ) -> Result<usize, Self::Error> {
1893 self.store
1894 .mark_dependent_queued_requests_as_ready(room_id, parent_txn_id, sent_parent_key)
1895 .await
1896 }
1897
1898 async fn update_dependent_queued_request(
1899 &self,
1900 room_id: &RoomId,
1901 own_transaction_id: &ChildTransactionId,
1902 new_content: DependentQueuedRequestKind,
1903 ) -> Result<bool, Self::Error> {
1904 self.store.update_dependent_queued_request(room_id, own_transaction_id, new_content).await
1905 }
1906
1907 async fn remove_dependent_queued_request(
1908 &self,
1909 room: &RoomId,
1910 own_txn_id: &ChildTransactionId,
1911 ) -> Result<bool, Self::Error> {
1912 self.store.remove_dependent_queued_request(room, own_txn_id).await
1913 }
1914
1915 async fn load_dependent_queued_requests(
1916 &self,
1917 room: &RoomId,
1918 ) -> Result<Vec<DependentQueuedRequest>, Self::Error> {
1919 self.store.load_dependent_queued_requests(room).await
1920 }
1921
1922 async fn upsert_thread_subscriptions(
1923 &self,
1924 updates: Vec<(&RoomId, &EventId, StoredThreadSubscription)>,
1925 ) -> Result<(), Self::Error> {
1926 self.store.upsert_thread_subscriptions(updates).await
1927 }
1928
1929 async fn load_thread_subscription(
1930 &self,
1931 room: &RoomId,
1932 thread_id: &EventId,
1933 ) -> Result<Option<StoredThreadSubscription>, Self::Error> {
1934 self.store.load_thread_subscription(room, thread_id).await
1935 }
1936
1937 async fn remove_thread_subscription(
1938 &self,
1939 room: &RoomId,
1940 thread_id: &EventId,
1941 ) -> Result<(), Self::Error> {
1942 self.store.remove_thread_subscription(room, thread_id).await
1943 }
1944
1945 async fn get_global_profile(
1946 &self,
1947 user_id: &UserId,
1948 ) -> Result<Option<UserProfile>, Self::Error> {
1949 self.store.get_global_profile(user_id).await
1950 }
1951
1952 async fn get_global_profiles<'a>(
1953 &self,
1954 user_ids: &'a [OwnedUserId],
1955 ) -> Result<BTreeMap<&'a UserId, UserProfile>, Self::Error> {
1956 self.store.get_global_profiles(user_ids).await
1957 }
1958
1959 async fn get_missing_global_profiles<'a>(
1960 &self,
1961 user_ids: &'a [OwnedUserId],
1962 ) -> Result<Vec<&'a UserId>, Self::Error> {
1963 self.store.get_missing_global_profiles(user_ids).await
1964 }
1965
1966 async fn close(&self) -> Result<(), Self::Error> {
1967 self.store.close().await
1968 }
1969
1970 async fn reopen(&self) -> Result<(), Self::Error> {
1971 self.store.reopen().await
1972 }
1973
1974 async fn optimize(&self) -> Result<(), Self::Error> {
1975 self.store.optimize().await
1976 }
1977
1978 async fn get_size(&self) -> Result<Option<usize>, Self::Error> {
1979 self.store.get_size().await
1980 }
1981}
1982
1983#[cfg_attr(target_family = "wasm", async_trait(?Send))]
1985#[cfg_attr(not(target_family = "wasm"), async_trait)]
1986pub trait StateStoreExt: StateStore {
1987 async fn get_state_event_static<C>(
1993 &self,
1994 room_id: &RoomId,
1995 ) -> Result<Option<RawSyncOrStrippedState<C>>, Self::Error>
1996 where
1997 C: StaticEventContent<IsPrefix = ruma::events::False>
1998 + StaticStateEventContent<StateKey = EmptyStateKey>
1999 + RedactContent,
2000 C::Redacted: RedactedStateEventContent,
2001 {
2002 Ok(self.get_state_event(room_id, C::TYPE.into(), "").await?.map(|raw| raw.cast()))
2003 }
2004
2005 async fn get_state_event_static_for_key<C, K>(
2011 &self,
2012 room_id: &RoomId,
2013 state_key: &K,
2014 ) -> Result<Option<RawSyncOrStrippedState<C>>, Self::Error>
2015 where
2016 C: StaticEventContent<IsPrefix = ruma::events::False>
2017 + StaticStateEventContent
2018 + RedactContent,
2019 C::StateKey: Borrow<K>,
2020 C::Redacted: RedactedStateEventContent,
2021 K: AsRef<str> + ?Sized + Sync,
2022 {
2023 Ok(self
2024 .get_state_event(room_id, C::TYPE.into(), state_key.as_ref())
2025 .await?
2026 .map(|raw| raw.cast()))
2027 }
2028
2029 async fn get_state_events_static<C>(
2035 &self,
2036 room_id: &RoomId,
2037 ) -> Result<Vec<RawSyncOrStrippedState<C>>, Self::Error>
2038 where
2039 C: StaticEventContent<IsPrefix = ruma::events::False>
2040 + StaticStateEventContent
2041 + RedactContent,
2042 C::Redacted: RedactedStateEventContent,
2043 {
2044 Ok(self
2047 .get_state_events(room_id, C::TYPE.into())
2048 .await?
2049 .into_iter()
2050 .map(|raw| raw.cast())
2051 .collect())
2052 }
2053
2054 async fn get_state_events_for_keys_static<'a, C, K, I>(
2062 &self,
2063 room_id: &RoomId,
2064 state_keys: I,
2065 ) -> Result<Vec<RawSyncOrStrippedState<C>>, Self::Error>
2066 where
2067 C: StaticEventContent<IsPrefix = ruma::events::False>
2068 + StaticStateEventContent
2069 + RedactContent,
2070 C::StateKey: Borrow<K>,
2071 C::Redacted: RedactedStateEventContent,
2072 K: AsRef<str> + Sized + Sync + 'a,
2073 I: IntoIterator<Item = &'a K> + Send,
2074 I::IntoIter: Send,
2075 {
2076 Ok(self
2077 .get_state_events_for_keys(
2078 room_id,
2079 C::TYPE.into(),
2080 &state_keys.into_iter().map(|k| k.as_ref()).collect::<Vec<_>>(),
2081 )
2082 .await?
2083 .into_iter()
2084 .map(|raw| raw.cast())
2085 .collect())
2086 }
2087
2088 async fn get_account_data_event_static<C>(
2090 &self,
2091 ) -> Result<Option<Raw<GlobalAccountDataEvent<C>>>, Self::Error>
2092 where
2093 C: StaticEventContent<IsPrefix = ruma::events::False> + GlobalAccountDataEventContent,
2094 {
2095 Ok(self.get_account_data_event(C::TYPE.into()).await?.map(Raw::cast_unchecked))
2096 }
2097
2098 async fn get_room_account_data_event_static<C>(
2106 &self,
2107 room_id: &RoomId,
2108 ) -> Result<Option<Raw<RoomAccountDataEvent<C>>>, Self::Error>
2109 where
2110 C: StaticEventContent<IsPrefix = ruma::events::False> + RoomAccountDataEventContent,
2111 {
2112 Ok(self
2113 .get_room_account_data_event(room_id, C::TYPE.into())
2114 .await?
2115 .map(Raw::cast_unchecked))
2116 }
2117
2118 async fn get_member_event(
2126 &self,
2127 room_id: &RoomId,
2128 state_key: &UserId,
2129 ) -> Result<Option<RawMemberEvent>, Self::Error> {
2130 self.get_state_event_static_for_key(room_id, state_key).await
2131 }
2132}
2133
2134#[cfg_attr(target_family = "wasm", async_trait(?Send))]
2135#[cfg_attr(not(target_family = "wasm"), async_trait)]
2136impl<T: StateStore + ?Sized> StateStoreExt for T {}
2137
2138pub type DynStateStore = dyn StateStore<Error = StoreError>;
2140
2141pub trait IntoStateStore {
2147 #[doc(hidden)]
2148 fn into_state_store(self) -> Arc<DynStateStore>;
2149}
2150
2151impl<T> IntoStateStore for T
2152where
2153 T: StateStore + Sized + 'static,
2154{
2155 fn into_state_store(self) -> Arc<DynStateStore> {
2156 Arc::new(EraseStateStoreError(self))
2157 }
2158}
2159
2160#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
2162pub struct SupportedVersionsResponse {
2163 pub versions: Vec<String>,
2165
2166 pub unstable_features: BTreeMap<String, bool>,
2168}
2169
2170impl SupportedVersionsResponse {
2171 pub fn supported_versions(&self) -> SupportedVersions {
2177 let mut supported_versions =
2178 SupportedVersions::from_parts(&self.versions, &self.unstable_features);
2179
2180 if supported_versions.versions.is_empty() {
2183 supported_versions.versions.insert(MatrixVersion::V1_0);
2184 }
2185
2186 supported_versions
2187 }
2188}
2189
2190#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
2191pub struct WellKnownResponse {
2193 pub homeserver: HomeserverInfo,
2195
2196 pub identity_server: Option<IdentityServerInfo>,
2198
2199 pub tile_server: Option<TileServerInfo>,
2201
2202 pub rtc_foci: Vec<RtcTransport>,
2204}
2205
2206impl From<discover_homeserver::Response> for WellKnownResponse {
2207 fn from(response: discover_homeserver::Response) -> Self {
2208 Self {
2209 homeserver: response.homeserver,
2210 identity_server: response.identity_server,
2211 tile_server: response.tile_server,
2212 rtc_foci: response.rtc_foci,
2213 }
2214 }
2215}
2216
2217#[derive(Debug, Clone)]
2219pub enum StateStoreDataValue {
2220 SyncToken(String),
2222
2223 SupportedVersions(TtlValue<SupportedVersionsResponse>),
2225
2226 WellKnown(TtlValue<Option<WellKnownResponse>>),
2228
2229 Filter(String),
2231
2232 UserAvatarUrl(OwnedMxcUri),
2234
2235 RecentlyVisitedRooms(Vec<OwnedRoomId>),
2237
2238 UtdHookManagerData(GrowableBloom),
2241
2242 OneTimeKeyAlreadyUploaded,
2245
2246 ComposerDraft(ComposerDraft),
2250
2251 SeenKnockRequests(BTreeMap<OwnedEventId, OwnedUserId>),
2253
2254 ThreadSubscriptionsCatchupTokens(Vec<ThreadSubscriptionCatchupToken>),
2259
2260 HomeserverCapabilities(TtlValue<Capabilities>),
2262}
2263
2264#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2274pub struct ThreadSubscriptionCatchupToken {
2275 pub from: String,
2281
2282 pub to: Option<String>,
2288}
2289
2290#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2292pub struct ComposerDraft {
2293 pub plain_text: String,
2295 pub html_text: Option<String>,
2298 pub draft_type: ComposerDraftType,
2300 #[serde(default)]
2302 pub attachments: Vec<DraftAttachment>,
2303}
2304
2305#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2307pub struct DraftAttachment {
2308 pub filename: String,
2310 pub content: DraftAttachmentContent,
2312}
2313
2314#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2316#[serde(tag = "type")]
2317pub enum DraftAttachmentContent {
2318 Image {
2320 #[serde(with = "serde_bytes")]
2322 data: Vec<u8>,
2323 mimetype: Option<String>,
2325 size: Option<u64>,
2327 width: Option<u64>,
2329 height: Option<u64>,
2331 blurhash: Option<String>,
2333 thumbnail: Option<DraftThumbnail>,
2335 },
2336 Video {
2338 #[serde(with = "serde_bytes")]
2340 data: Vec<u8>,
2341 mimetype: Option<String>,
2343 size: Option<u64>,
2345 width: Option<u64>,
2347 height: Option<u64>,
2349 duration: Option<std::time::Duration>,
2351 blurhash: Option<String>,
2353 thumbnail: Option<DraftThumbnail>,
2355 },
2356 Audio {
2358 #[serde(with = "serde_bytes")]
2360 data: Vec<u8>,
2361 mimetype: Option<String>,
2363 size: Option<u64>,
2365 duration: Option<std::time::Duration>,
2367 },
2368 File {
2370 #[serde(with = "serde_bytes")]
2372 data: Vec<u8>,
2373 mimetype: Option<String>,
2375 size: Option<u64>,
2377 },
2378}
2379
2380#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2382pub struct DraftThumbnail {
2383 pub filename: String,
2385 #[serde(with = "serde_bytes")]
2387 pub data: Vec<u8>,
2388 pub mimetype: Option<String>,
2390 pub width: Option<u64>,
2392 pub height: Option<u64>,
2394 pub size: Option<u64>,
2396}
2397
2398#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2400pub enum ComposerDraftType {
2401 NewMessage,
2403 Reply {
2405 event_id: OwnedEventId,
2407 },
2408 Edit {
2410 event_id: OwnedEventId,
2412 },
2413}
2414
2415impl StateStoreDataValue {
2416 pub fn into_sync_token(self) -> Option<String> {
2418 as_variant!(self, Self::SyncToken)
2419 }
2420
2421 pub fn into_filter(self) -> Option<String> {
2423 as_variant!(self, Self::Filter)
2424 }
2425
2426 pub fn into_user_avatar_url(self) -> Option<OwnedMxcUri> {
2428 as_variant!(self, Self::UserAvatarUrl)
2429 }
2430
2431 pub fn into_recently_visited_rooms(self) -> Option<Vec<OwnedRoomId>> {
2433 as_variant!(self, Self::RecentlyVisitedRooms)
2434 }
2435
2436 pub fn into_utd_hook_manager_data(self) -> Option<GrowableBloom> {
2438 as_variant!(self, Self::UtdHookManagerData)
2439 }
2440
2441 pub fn into_composer_draft(self) -> Option<ComposerDraft> {
2443 as_variant!(self, Self::ComposerDraft)
2444 }
2445
2446 pub fn into_supported_versions(self) -> Option<TtlValue<SupportedVersionsResponse>> {
2448 as_variant!(self, Self::SupportedVersions)
2449 }
2450
2451 pub fn into_well_known(self) -> Option<TtlValue<Option<WellKnownResponse>>> {
2453 as_variant!(self, Self::WellKnown)
2454 }
2455
2456 pub fn into_seen_knock_requests(self) -> Option<BTreeMap<OwnedEventId, OwnedUserId>> {
2458 as_variant!(self, Self::SeenKnockRequests)
2459 }
2460
2461 pub fn into_thread_subscriptions_catchup_tokens(
2464 self,
2465 ) -> Option<Vec<ThreadSubscriptionCatchupToken>> {
2466 as_variant!(self, Self::ThreadSubscriptionsCatchupTokens)
2467 }
2468
2469 pub fn into_homeserver_capabilities(self) -> Option<TtlValue<Capabilities>> {
2472 as_variant!(self, Self::HomeserverCapabilities)
2473 }
2474}
2475
2476#[derive(Debug, Clone, Copy)]
2478pub enum StateStoreDataKey<'a> {
2479 SyncToken,
2481
2482 SupportedVersions,
2484
2485 WellKnown,
2487
2488 Filter(&'a str),
2490
2491 UserAvatarUrl(&'a UserId),
2493
2494 RecentlyVisitedRooms(&'a UserId),
2496
2497 UtdHookManagerData,
2500
2501 OneTimeKeyAlreadyUploaded,
2504
2505 ComposerDraft(&'a RoomId, Option<&'a EventId>),
2509
2510 SeenKnockRequests(&'a RoomId),
2512
2513 ThreadSubscriptionsCatchupTokens,
2515
2516 HomeserverCapabilities,
2518}
2519
2520impl StateStoreDataKey<'_> {
2521 pub const SYNC_TOKEN: &'static str = "sync_token";
2523
2524 pub const SUPPORTED_VERSIONS: &'static str = "server_capabilities";
2528
2529 pub const WELL_KNOWN: &'static str = "well_known";
2531
2532 pub const FILTER: &'static str = "filter";
2534
2535 pub const USER_AVATAR_URL: &'static str = "user_avatar_url";
2538
2539 pub const RECENTLY_VISITED_ROOMS: &'static str = "recently_visited_rooms";
2542
2543 pub const UTD_HOOK_MANAGER_DATA: &'static str = "utd_hook_manager_data";
2546
2547 pub const ONE_TIME_KEY_ALREADY_UPLOADED: &'static str = "one_time_key_already_uploaded";
2550
2551 pub const COMPOSER_DRAFT: &'static str = "composer_draft";
2554
2555 pub const SEEN_KNOCK_REQUESTS: &'static str = "seen_knock_requests";
2558
2559 pub const THREAD_SUBSCRIPTIONS_CATCHUP_TOKENS: &'static str =
2563 "thread_subscriptions_catchup_tokens";
2564
2565 pub const HOMESERVER_CAPABILITIES: &'static str = "homeserver_capabilities";
2567}
2568
2569pub fn compare_thread_subscription_bump_stamps(
2578 previous: Option<u64>,
2579 new: &mut Option<u64>,
2580) -> bool {
2581 match (previous, &new) {
2582 (Some(prev_bump), None) => {
2586 *new = Some(prev_bump);
2587 }
2588
2589 (Some(prev_bump), Some(new_bump)) if *new_bump <= prev_bump => {
2591 return false;
2592 }
2593
2594 _ => {}
2596 }
2597
2598 true
2599}
2600
2601#[cfg(test)]
2602mod tests {
2603 mod save_locked_state_store {
2604 use std::time::Duration;
2605
2606 use assert_matches::assert_matches;
2607 use futures_util::future::{self, Either};
2608 #[cfg(all(target_family = "wasm", target_os = "unknown"))]
2609 use gloo_timers::future::sleep;
2610 use matrix_sdk_common::executor::spawn;
2611 use matrix_sdk_test::async_test;
2612 use ruma::room_id;
2613 use tokio::sync::Mutex;
2614 #[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
2615 use tokio::time::sleep;
2616
2617 use crate::{
2618 StateChanges, StateStore,
2619 store::{IntoStateStore, MemoryStore, Result, SaveLockedStateStore},
2620 };
2621
2622 async fn get_store() -> Result<impl StateStore> {
2623 Ok(SaveLockedStateStore::new(MemoryStore::new()))
2624 }
2625
2626 statestore_integration_tests!();
2627
2628 #[async_test]
2629 async fn test_save_changes_only_accepts_guard_for_underlying_mutex() {
2630 let state_store = SaveLockedStateStore::new(MemoryStore::new());
2631 let state_changes = StateChanges::default();
2632 state_store
2633 .save_changes_with_guard(&state_store.lock().lock().await, &state_changes)
2634 .await
2635 .expect("state store accepts guard for underlying mutex");
2636
2637 let mutex = Mutex::new(());
2638 state_store
2639 .save_changes_with_guard(&mutex.lock().await, &state_changes)
2640 .await
2641 .expect_err("state store does not accept guard for unknown mutex");
2642 }
2643
2644 #[async_test]
2645 async fn test_remove_room_only_accepts_guard_for_underlying_mutex() {
2646 let state_store = SaveLockedStateStore::new(MemoryStore::new());
2647 let room_id = room_id!("!room");
2648 state_store
2649 .remove_room_with_guard(&state_store.lock().lock().await, room_id)
2650 .await
2651 .expect("state store accepts guard for underlying mutex");
2652
2653 let mutex = Mutex::new(());
2654 state_store
2655 .remove_room_with_guard(&mutex.lock().await, room_id)
2656 .await
2657 .expect_err("state store does not accept guard for unknown mutex");
2658 }
2659
2660 #[derive(Debug)]
2661 struct Elapsed;
2662
2663 async fn timeout<F: Future + Unpin>(
2664 duration: Duration,
2665 f: F,
2666 ) -> Result<F::Output, Elapsed> {
2667 #[cfg(all(target_family = "wasm", target_os = "unknown"))]
2668 {
2669 match future::select(sleep(duration), f).await {
2670 Either::Left(_) => return Err(Elapsed),
2671 Either::Right((output, _)) => Ok(output),
2672 }
2673 }
2674 #[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
2675 {
2676 tokio::time::timeout(duration, f).await.map_err(|_| Elapsed)
2677 }
2678 }
2679
2680 #[async_test]
2681 async fn test_state_store_waits_to_acquire_lock_before_saving_changes() {
2682 let state_store = SaveLockedStateStore::new(MemoryStore::new().into_state_store());
2683
2684 let lock_task = spawn({
2686 let state_store = state_store.clone();
2687 async move {
2688 let lock = state_store.lock();
2689 let _guard = lock.lock().await;
2690 sleep(Duration::from_secs(5)).await;
2691 }
2692 });
2693
2694 let save_task =
2697 spawn(async move { state_store.save_changes(&StateChanges::default()).await });
2698
2699 assert_matches!(future::select(lock_task, save_task).await, Either::Left((_, save_task)) => {
2702 timeout(Duration::from_millis(100), save_task)
2703 .await
2704 .expect("task completes before timeout")
2705 .expect("task completes successfully")
2706 .expect("task saves changes");
2707 });
2708 }
2709
2710 #[async_test]
2711 async fn test_state_store_waits_to_acquire_lock_before_removing_room() {
2712 let state_store = SaveLockedStateStore::new(MemoryStore::new().into_state_store());
2713
2714 let lock_task = spawn({
2716 let state_store = state_store.clone();
2717 async move {
2718 let lock = state_store.lock();
2719 let _guard = lock.lock().await;
2720 sleep(Duration::from_secs(5)).await;
2721 }
2722 });
2723
2724 let remove_task =
2727 spawn(async move { state_store.remove_room(room_id!("!room")).await });
2728
2729 assert_matches!(future::select(lock_task, remove_task).await, Either::Left((_, remove_task)) => {
2732 timeout(Duration::from_millis(100), remove_task)
2733 .await
2734 .expect("task completes before timeout")
2735 .expect("task completes successfully")
2736 .expect("task saves changes");
2737 });
2738 }
2739 }
2740}