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 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 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 thread: ReceiptThread,
702 user_id: &UserId,
703 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error> {
704 (*self).get_user_room_receipt_event(room_id, receipt_type, 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 thread: ReceiptThread,
712 event_id: &EventId,
713 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error> {
714 (*self).get_event_room_receipt_events(room_id, receipt_type, 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 thread: ReceiptThread,
1024 user_id: &UserId,
1025 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error> {
1026 self.deref().get_user_room_receipt_event(room_id, receipt_type, thread, user_id).await
1027 }
1028
1029 async fn get_event_room_receipt_events(
1030 &self,
1031 room_id: &RoomId,
1032 receipt_type: ReceiptType,
1033 thread: ReceiptThread,
1034 event_id: &EventId,
1035 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error> {
1036 self.deref().get_event_room_receipt_events(room_id, receipt_type, thread, event_id).await
1037 }
1038
1039 async fn get_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1040 self.deref().get_custom_value(key).await
1041 }
1042
1043 async fn set_custom_value(
1044 &self,
1045 key: &[u8],
1046 value: Vec<u8>,
1047 ) -> Result<Option<Vec<u8>>, Self::Error> {
1048 self.deref().set_custom_value(key, value).await
1049 }
1050
1051 async fn remove_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1052 self.deref().remove_custom_value(key).await
1053 }
1054
1055 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error> {
1056 self.deref().remove_room(room_id).await
1057 }
1058
1059 async fn save_send_queue_request(
1060 &self,
1061 room_id: &RoomId,
1062 transaction_id: OwnedTransactionId,
1063 created_at: MilliSecondsSinceUnixEpoch,
1064 request: QueuedRequestKind,
1065 priority: usize,
1066 ) -> Result<(), Self::Error> {
1067 self.deref()
1068 .save_send_queue_request(room_id, transaction_id, created_at, request, priority)
1069 .await
1070 }
1071
1072 async fn update_send_queue_request(
1073 &self,
1074 room_id: &RoomId,
1075 transaction_id: &TransactionId,
1076 content: QueuedRequestKind,
1077 ) -> Result<bool, Self::Error> {
1078 self.deref().update_send_queue_request(room_id, transaction_id, content).await
1079 }
1080
1081 async fn remove_send_queue_request(
1082 &self,
1083 room_id: &RoomId,
1084 transaction_id: &TransactionId,
1085 ) -> Result<bool, Self::Error> {
1086 self.deref().remove_send_queue_request(room_id, transaction_id).await
1087 }
1088
1089 async fn load_send_queue_requests(
1090 &self,
1091 room_id: &RoomId,
1092 ) -> Result<Vec<QueuedRequest>, Self::Error> {
1093 self.deref().load_send_queue_requests(room_id).await
1094 }
1095
1096 async fn update_send_queue_request_status(
1097 &self,
1098 room_id: &RoomId,
1099 transaction_id: &TransactionId,
1100 error: Option<QueueWedgeError>,
1101 ) -> Result<(), Self::Error> {
1102 self.deref().update_send_queue_request_status(room_id, transaction_id, error).await
1103 }
1104
1105 async fn load_rooms_with_unsent_requests(&self) -> Result<Vec<OwnedRoomId>, Self::Error> {
1106 self.deref().load_rooms_with_unsent_requests().await
1107 }
1108
1109 async fn save_dependent_queued_request(
1110 &self,
1111 room_id: &RoomId,
1112 parent_txn_id: &TransactionId,
1113 own_txn_id: ChildTransactionId,
1114 created_at: MilliSecondsSinceUnixEpoch,
1115 content: DependentQueuedRequestKind,
1116 ) -> Result<(), Self::Error> {
1117 self.deref()
1118 .save_dependent_queued_request(room_id, parent_txn_id, own_txn_id, created_at, content)
1119 .await
1120 }
1121
1122 async fn mark_dependent_queued_requests_as_ready(
1123 &self,
1124 room_id: &RoomId,
1125 parent_txn_id: &TransactionId,
1126 sent_parent_key: SentRequestKey,
1127 ) -> Result<usize, Self::Error> {
1128 self.deref()
1129 .mark_dependent_queued_requests_as_ready(room_id, parent_txn_id, sent_parent_key)
1130 .await
1131 }
1132
1133 async fn update_dependent_queued_request(
1134 &self,
1135 room_id: &RoomId,
1136 own_transaction_id: &ChildTransactionId,
1137 new_content: DependentQueuedRequestKind,
1138 ) -> Result<bool, Self::Error> {
1139 self.deref().update_dependent_queued_request(room_id, own_transaction_id, new_content).await
1140 }
1141
1142 async fn remove_dependent_queued_request(
1143 &self,
1144 room: &RoomId,
1145 own_txn_id: &ChildTransactionId,
1146 ) -> Result<bool, Self::Error> {
1147 self.deref().remove_dependent_queued_request(room, own_txn_id).await
1148 }
1149
1150 async fn load_dependent_queued_requests(
1151 &self,
1152 room: &RoomId,
1153 ) -> Result<Vec<DependentQueuedRequest>, Self::Error> {
1154 self.deref().load_dependent_queued_requests(room).await
1155 }
1156
1157 async fn upsert_thread_subscriptions(
1158 &self,
1159 updates: Vec<(&RoomId, &EventId, StoredThreadSubscription)>,
1160 ) -> Result<(), Self::Error> {
1161 self.deref().upsert_thread_subscriptions(updates).await
1162 }
1163
1164 async fn remove_thread_subscription(
1165 &self,
1166 room: &RoomId,
1167 thread_id: &EventId,
1168 ) -> Result<(), Self::Error> {
1169 self.deref().remove_thread_subscription(room, thread_id).await
1170 }
1171
1172 async fn load_thread_subscription(
1173 &self,
1174 room: &RoomId,
1175 thread_id: &EventId,
1176 ) -> Result<Option<StoredThreadSubscription>, Self::Error> {
1177 self.deref().load_thread_subscription(room, thread_id).await
1178 }
1179
1180 async fn get_global_profile(
1181 &self,
1182 user_id: &UserId,
1183 ) -> Result<Option<UserProfile>, Self::Error> {
1184 self.deref().get_global_profile(user_id).await
1185 }
1186
1187 async fn get_global_profiles<'a>(
1188 &self,
1189 user_ids: &'a [OwnedUserId],
1190 ) -> Result<BTreeMap<&'a UserId, UserProfile>, Self::Error> {
1191 self.deref().get_global_profiles(user_ids).await
1192 }
1193
1194 async fn close(&self) -> Result<(), Self::Error> {
1195 self.deref().close().await
1196 }
1197
1198 async fn reopen(&self) -> Result<(), Self::Error> {
1199 self.deref().reopen().await
1200 }
1201
1202 async fn optimize(&self) -> Result<(), Self::Error> {
1203 self.deref().optimize().await
1204 }
1205
1206 async fn get_size(&self) -> Result<Option<usize>, Self::Error> {
1207 self.deref().get_size().await
1208 }
1209}
1210
1211#[repr(transparent)]
1212struct EraseStateStoreError<T>(T);
1213
1214#[cfg(not(tarpaulin_include))]
1215impl<T: fmt::Debug> fmt::Debug for EraseStateStoreError<T> {
1216 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1217 self.0.fmt(f)
1218 }
1219}
1220
1221#[cfg_attr(target_family = "wasm", async_trait(?Send))]
1222#[cfg_attr(not(target_family = "wasm"), async_trait)]
1223impl<T: StateStore> StateStore for EraseStateStoreError<T> {
1224 type Error = StoreError;
1225
1226 async fn get_kv_data(
1227 &self,
1228 key: StateStoreDataKey<'_>,
1229 ) -> Result<Option<StateStoreDataValue>, Self::Error> {
1230 self.0.get_kv_data(key).await.map_err(Into::into)
1231 }
1232
1233 async fn set_kv_data(
1234 &self,
1235 key: StateStoreDataKey<'_>,
1236 value: StateStoreDataValue,
1237 ) -> Result<(), Self::Error> {
1238 self.0.set_kv_data(key, value).await.map_err(Into::into)
1239 }
1240
1241 async fn remove_kv_data(&self, key: StateStoreDataKey<'_>) -> Result<(), Self::Error> {
1242 self.0.remove_kv_data(key).await.map_err(Into::into)
1243 }
1244
1245 async fn save_changes(&self, changes: &StateChanges) -> Result<(), Self::Error> {
1246 self.0.save_changes(changes).await.map_err(Into::into)
1247 }
1248
1249 async fn get_presence_event(
1250 &self,
1251 user_id: &UserId,
1252 ) -> Result<Option<Raw<PresenceEvent>>, Self::Error> {
1253 self.0.get_presence_event(user_id).await.map_err(Into::into)
1254 }
1255
1256 async fn get_presence_events(
1257 &self,
1258 user_ids: &[OwnedUserId],
1259 ) -> Result<Vec<Raw<PresenceEvent>>, Self::Error> {
1260 self.0.get_presence_events(user_ids).await.map_err(Into::into)
1261 }
1262
1263 async fn get_state_event(
1264 &self,
1265 room_id: &RoomId,
1266 event_type: StateEventType,
1267 state_key: &str,
1268 ) -> Result<Option<RawAnySyncOrStrippedState>, Self::Error> {
1269 self.0.get_state_event(room_id, event_type, state_key).await.map_err(Into::into)
1270 }
1271
1272 async fn get_state_events(
1273 &self,
1274 room_id: &RoomId,
1275 event_type: StateEventType,
1276 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
1277 self.0.get_state_events(room_id, event_type).await.map_err(Into::into)
1278 }
1279
1280 async fn get_state_events_for_keys(
1281 &self,
1282 room_id: &RoomId,
1283 event_type: StateEventType,
1284 state_keys: &[&str],
1285 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
1286 self.0.get_state_events_for_keys(room_id, event_type, state_keys).await.map_err(Into::into)
1287 }
1288
1289 async fn get_profile(
1290 &self,
1291 room_id: &RoomId,
1292 user_id: &UserId,
1293 ) -> Result<Option<MinimalRoomMemberEvent>, Self::Error> {
1294 self.0.get_profile(room_id, user_id).await.map_err(Into::into)
1295 }
1296
1297 async fn get_profiles<'a>(
1298 &self,
1299 room_id: &RoomId,
1300 user_ids: &'a [OwnedUserId],
1301 ) -> Result<BTreeMap<&'a UserId, MinimalRoomMemberEvent>, Self::Error> {
1302 self.0.get_profiles(room_id, user_ids).await.map_err(Into::into)
1303 }
1304
1305 async fn get_user_ids(
1306 &self,
1307 room_id: &RoomId,
1308 memberships: RoomMemberships,
1309 ) -> Result<Vec<OwnedUserId>, Self::Error> {
1310 self.0.get_user_ids(room_id, memberships).await.map_err(Into::into)
1311 }
1312
1313 async fn get_room_infos(
1314 &self,
1315 room_load_settings: &RoomLoadSettings,
1316 ) -> Result<Vec<RoomInfo>, Self::Error> {
1317 self.0.get_room_infos(room_load_settings).await.map_err(Into::into)
1318 }
1319
1320 async fn get_users_with_display_name(
1321 &self,
1322 room_id: &RoomId,
1323 display_name: &DisplayName,
1324 ) -> Result<BTreeSet<OwnedUserId>, Self::Error> {
1325 self.0.get_users_with_display_name(room_id, display_name).await.map_err(Into::into)
1326 }
1327
1328 async fn get_users_with_display_names<'a>(
1329 &self,
1330 room_id: &RoomId,
1331 display_names: &'a [DisplayName],
1332 ) -> Result<HashMap<&'a DisplayName, BTreeSet<OwnedUserId>>, Self::Error> {
1333 self.0.get_users_with_display_names(room_id, display_names).await.map_err(Into::into)
1334 }
1335
1336 async fn get_account_data_event(
1337 &self,
1338 event_type: GlobalAccountDataEventType,
1339 ) -> Result<Option<Raw<AnyGlobalAccountDataEvent>>, Self::Error> {
1340 self.0.get_account_data_event(event_type).await.map_err(Into::into)
1341 }
1342
1343 async fn get_room_account_data_event(
1344 &self,
1345 room_id: &RoomId,
1346 event_type: RoomAccountDataEventType,
1347 ) -> Result<Option<Raw<AnyRoomAccountDataEvent>>, Self::Error> {
1348 self.0.get_room_account_data_event(room_id, event_type).await.map_err(Into::into)
1349 }
1350
1351 async fn get_user_room_receipt_event(
1352 &self,
1353 room_id: &RoomId,
1354 receipt_type: ReceiptType,
1355 thread: ReceiptThread,
1356 user_id: &UserId,
1357 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error> {
1358 self.0
1359 .get_user_room_receipt_event(room_id, receipt_type, thread, user_id)
1360 .await
1361 .map_err(Into::into)
1362 }
1363
1364 async fn get_event_room_receipt_events(
1365 &self,
1366 room_id: &RoomId,
1367 receipt_type: ReceiptType,
1368 thread: ReceiptThread,
1369 event_id: &EventId,
1370 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error> {
1371 self.0
1372 .get_event_room_receipt_events(room_id, receipt_type, thread, event_id)
1373 .await
1374 .map_err(Into::into)
1375 }
1376
1377 async fn get_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1378 self.0.get_custom_value(key).await.map_err(Into::into)
1379 }
1380
1381 async fn set_custom_value(
1382 &self,
1383 key: &[u8],
1384 value: Vec<u8>,
1385 ) -> Result<Option<Vec<u8>>, Self::Error> {
1386 self.0.set_custom_value(key, value).await.map_err(Into::into)
1387 }
1388
1389 async fn remove_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1390 self.0.remove_custom_value(key).await.map_err(Into::into)
1391 }
1392
1393 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error> {
1394 self.0.remove_room(room_id).await.map_err(Into::into)
1395 }
1396
1397 async fn save_send_queue_request(
1398 &self,
1399 room_id: &RoomId,
1400 transaction_id: OwnedTransactionId,
1401 created_at: MilliSecondsSinceUnixEpoch,
1402 content: QueuedRequestKind,
1403 priority: usize,
1404 ) -> Result<(), Self::Error> {
1405 self.0
1406 .save_send_queue_request(room_id, transaction_id, created_at, content, priority)
1407 .await
1408 .map_err(Into::into)
1409 }
1410
1411 async fn update_send_queue_request(
1412 &self,
1413 room_id: &RoomId,
1414 transaction_id: &TransactionId,
1415 content: QueuedRequestKind,
1416 ) -> Result<bool, Self::Error> {
1417 self.0.update_send_queue_request(room_id, transaction_id, content).await.map_err(Into::into)
1418 }
1419
1420 async fn remove_send_queue_request(
1421 &self,
1422 room_id: &RoomId,
1423 transaction_id: &TransactionId,
1424 ) -> Result<bool, Self::Error> {
1425 self.0.remove_send_queue_request(room_id, transaction_id).await.map_err(Into::into)
1426 }
1427
1428 async fn load_send_queue_requests(
1429 &self,
1430 room_id: &RoomId,
1431 ) -> Result<Vec<QueuedRequest>, Self::Error> {
1432 self.0.load_send_queue_requests(room_id).await.map_err(Into::into)
1433 }
1434
1435 async fn update_send_queue_request_status(
1436 &self,
1437 room_id: &RoomId,
1438 transaction_id: &TransactionId,
1439 error: Option<QueueWedgeError>,
1440 ) -> Result<(), Self::Error> {
1441 self.0
1442 .update_send_queue_request_status(room_id, transaction_id, error)
1443 .await
1444 .map_err(Into::into)
1445 }
1446
1447 async fn load_rooms_with_unsent_requests(&self) -> Result<Vec<OwnedRoomId>, Self::Error> {
1448 self.0.load_rooms_with_unsent_requests().await.map_err(Into::into)
1449 }
1450
1451 async fn save_dependent_queued_request(
1452 &self,
1453 room_id: &RoomId,
1454 parent_txn_id: &TransactionId,
1455 own_txn_id: ChildTransactionId,
1456 created_at: MilliSecondsSinceUnixEpoch,
1457 content: DependentQueuedRequestKind,
1458 ) -> Result<(), Self::Error> {
1459 self.0
1460 .save_dependent_queued_request(room_id, parent_txn_id, own_txn_id, created_at, content)
1461 .await
1462 .map_err(Into::into)
1463 }
1464
1465 async fn mark_dependent_queued_requests_as_ready(
1466 &self,
1467 room_id: &RoomId,
1468 parent_txn_id: &TransactionId,
1469 sent_parent_key: SentRequestKey,
1470 ) -> Result<usize, Self::Error> {
1471 self.0
1472 .mark_dependent_queued_requests_as_ready(room_id, parent_txn_id, sent_parent_key)
1473 .await
1474 .map_err(Into::into)
1475 }
1476
1477 async fn remove_dependent_queued_request(
1478 &self,
1479 room_id: &RoomId,
1480 own_txn_id: &ChildTransactionId,
1481 ) -> Result<bool, Self::Error> {
1482 self.0.remove_dependent_queued_request(room_id, own_txn_id).await.map_err(Into::into)
1483 }
1484
1485 async fn load_dependent_queued_requests(
1486 &self,
1487 room_id: &RoomId,
1488 ) -> Result<Vec<DependentQueuedRequest>, Self::Error> {
1489 self.0.load_dependent_queued_requests(room_id).await.map_err(Into::into)
1490 }
1491
1492 async fn update_dependent_queued_request(
1493 &self,
1494 room_id: &RoomId,
1495 own_transaction_id: &ChildTransactionId,
1496 new_content: DependentQueuedRequestKind,
1497 ) -> Result<bool, Self::Error> {
1498 self.0
1499 .update_dependent_queued_request(room_id, own_transaction_id, new_content)
1500 .await
1501 .map_err(Into::into)
1502 }
1503
1504 async fn upsert_thread_subscriptions(
1505 &self,
1506 updates: Vec<(&RoomId, &EventId, StoredThreadSubscription)>,
1507 ) -> Result<(), Self::Error> {
1508 self.0.upsert_thread_subscriptions(updates).await.map_err(Into::into)
1509 }
1510
1511 async fn load_thread_subscription(
1512 &self,
1513 room: &RoomId,
1514 thread_id: &EventId,
1515 ) -> Result<Option<StoredThreadSubscription>, Self::Error> {
1516 self.0.load_thread_subscription(room, thread_id).await.map_err(Into::into)
1517 }
1518
1519 async fn remove_thread_subscription(
1520 &self,
1521 room: &RoomId,
1522 thread_id: &EventId,
1523 ) -> Result<(), Self::Error> {
1524 self.0.remove_thread_subscription(room, thread_id).await.map_err(Into::into)
1525 }
1526
1527 async fn get_global_profile(
1528 &self,
1529 user_id: &UserId,
1530 ) -> Result<Option<UserProfile>, Self::Error> {
1531 self.0.get_global_profile(user_id).await.map_err(Into::into)
1532 }
1533
1534 async fn get_global_profiles<'a>(
1535 &self,
1536 user_ids: &'a [OwnedUserId],
1537 ) -> Result<BTreeMap<&'a UserId, UserProfile>, Self::Error> {
1538 self.0.get_global_profiles(user_ids).await.map_err(Into::into)
1539 }
1540
1541 async fn close(&self) -> Result<(), Self::Error> {
1542 self.0.close().await.map_err(Into::into)
1543 }
1544
1545 async fn reopen(&self) -> Result<(), Self::Error> {
1546 self.0.reopen().await.map_err(Into::into)
1547 }
1548
1549 async fn optimize(&self) -> Result<(), Self::Error> {
1550 self.0.optimize().await.map_err(Into::into)
1551 }
1552
1553 async fn get_size(&self) -> Result<Option<usize>, Self::Error> {
1554 self.0.get_size().await.map_err(Into::into)
1555 }
1556}
1557
1558#[derive(Debug, Clone)]
1561pub struct SaveLockedStateStore<T = Arc<DynStateStore>> {
1562 store: T,
1563 lock: Arc<Mutex<()>>,
1564}
1565
1566#[derive(Debug, Error)]
1570#[error("a mutex guard was provided, but it does not reference the correct mutex")]
1571pub struct IncorrectMutexGuardError;
1572
1573impl From<IncorrectMutexGuardError> for StoreError {
1574 fn from(value: IncorrectMutexGuardError) -> Self {
1575 Self::backend(value)
1576 }
1577}
1578
1579impl<T> SaveLockedStateStore<T> {
1580 pub fn new(store: T) -> Self {
1582 Self { store, lock: Arc::new(Mutex::new(())) }
1583 }
1584
1585 pub fn lock(&self) -> &Mutex<()> {
1588 self.lock.as_ref()
1589 }
1590}
1591
1592impl<T: StateStore> SaveLockedStateStore<T> {
1593 pub async fn save_changes_with_guard(
1598 &self,
1599 guard: &MutexGuard<'_, ()>,
1600 changes: &StateChanges,
1601 ) -> Result<(), StoreError> {
1602 if !std::ptr::eq(MutexGuard::mutex(guard), self.lock()) {
1603 Err(IncorrectMutexGuardError.into())
1604 } else {
1605 self.store.save_changes(changes).await.map_err(Into::into)
1606 }
1607 }
1608
1609 pub async fn remove_room_with_guard(
1614 &self,
1615 guard: &MutexGuard<'_, ()>,
1616 room_id: &RoomId,
1617 ) -> Result<(), StoreError> {
1618 if !std::ptr::eq(MutexGuard::mutex(guard), self.lock()) {
1619 Err(IncorrectMutexGuardError.into())
1620 } else {
1621 self.store.remove_room(room_id).await.map_err(Into::into)
1622 }
1623 }
1624}
1625
1626#[cfg_attr(target_family = "wasm", async_trait(?Send))]
1627#[cfg_attr(not(target_family = "wasm"), async_trait)]
1628impl<T: StateStore> StateStore for SaveLockedStateStore<T> {
1629 type Error = T::Error;
1630
1631 async fn get_kv_data(
1632 &self,
1633 key: StateStoreDataKey<'_>,
1634 ) -> Result<Option<StateStoreDataValue>, Self::Error> {
1635 self.store.get_kv_data(key).await
1636 }
1637
1638 async fn set_kv_data(
1639 &self,
1640 key: StateStoreDataKey<'_>,
1641 value: StateStoreDataValue,
1642 ) -> Result<(), Self::Error> {
1643 self.store.set_kv_data(key, value).await
1644 }
1645
1646 async fn remove_kv_data(&self, key: StateStoreDataKey<'_>) -> Result<(), Self::Error> {
1647 self.store.remove_kv_data(key).await
1648 }
1649
1650 async fn save_changes(&self, changes: &StateChanges) -> Result<(), Self::Error> {
1651 let _guard = self.lock.lock().await;
1652 self.store.save_changes(changes).await
1653 }
1654
1655 async fn get_presence_event(
1656 &self,
1657 user_id: &UserId,
1658 ) -> Result<Option<Raw<PresenceEvent>>, Self::Error> {
1659 self.store.get_presence_event(user_id).await
1660 }
1661
1662 async fn get_presence_events(
1663 &self,
1664 user_ids: &[OwnedUserId],
1665 ) -> Result<Vec<Raw<PresenceEvent>>, Self::Error> {
1666 self.store.get_presence_events(user_ids).await
1667 }
1668
1669 async fn get_state_event(
1670 &self,
1671 room_id: &RoomId,
1672 event_type: StateEventType,
1673 state_key: &str,
1674 ) -> Result<Option<RawAnySyncOrStrippedState>, Self::Error> {
1675 self.store.get_state_event(room_id, event_type, state_key).await
1676 }
1677
1678 async fn get_state_events(
1679 &self,
1680 room_id: &RoomId,
1681 event_type: StateEventType,
1682 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
1683 self.store.get_state_events(room_id, event_type).await
1684 }
1685
1686 async fn get_state_events_for_keys(
1687 &self,
1688 room_id: &RoomId,
1689 event_type: StateEventType,
1690 state_keys: &[&str],
1691 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
1692 self.store.get_state_events_for_keys(room_id, event_type, state_keys).await
1693 }
1694
1695 async fn get_profile(
1696 &self,
1697 room_id: &RoomId,
1698 user_id: &UserId,
1699 ) -> Result<Option<MinimalRoomMemberEvent>, Self::Error> {
1700 self.store.get_profile(room_id, user_id).await
1701 }
1702
1703 async fn get_profiles<'a>(
1704 &self,
1705 room_id: &RoomId,
1706 user_ids: &'a [OwnedUserId],
1707 ) -> Result<BTreeMap<&'a UserId, MinimalRoomMemberEvent>, Self::Error> {
1708 self.store.get_profiles(room_id, user_ids).await
1709 }
1710
1711 async fn get_user_ids(
1712 &self,
1713 room_id: &RoomId,
1714 memberships: RoomMemberships,
1715 ) -> Result<Vec<OwnedUserId>, Self::Error> {
1716 self.store.get_user_ids(room_id, memberships).await
1717 }
1718
1719 async fn get_room_infos(
1720 &self,
1721 room_load_settings: &RoomLoadSettings,
1722 ) -> Result<Vec<RoomInfo>, Self::Error> {
1723 self.store.get_room_infos(room_load_settings).await
1724 }
1725
1726 async fn get_users_with_display_name(
1727 &self,
1728 room_id: &RoomId,
1729 display_name: &DisplayName,
1730 ) -> Result<BTreeSet<OwnedUserId>, Self::Error> {
1731 self.store.get_users_with_display_name(room_id, display_name).await
1732 }
1733
1734 async fn get_users_with_display_names<'a>(
1735 &self,
1736 room_id: &RoomId,
1737 display_names: &'a [DisplayName],
1738 ) -> Result<HashMap<&'a DisplayName, BTreeSet<OwnedUserId>>, Self::Error> {
1739 self.store.get_users_with_display_names(room_id, display_names).await
1740 }
1741
1742 async fn get_account_data_event(
1743 &self,
1744 event_type: GlobalAccountDataEventType,
1745 ) -> Result<Option<Raw<AnyGlobalAccountDataEvent>>, Self::Error> {
1746 self.store.get_account_data_event(event_type).await
1747 }
1748
1749 async fn get_room_account_data_event(
1750 &self,
1751 room_id: &RoomId,
1752 event_type: RoomAccountDataEventType,
1753 ) -> Result<Option<Raw<AnyRoomAccountDataEvent>>, Self::Error> {
1754 self.store.get_room_account_data_event(room_id, event_type).await
1755 }
1756
1757 async fn get_user_room_receipt_event(
1758 &self,
1759 room_id: &RoomId,
1760 receipt_type: ReceiptType,
1761 thread: ReceiptThread,
1762 user_id: &UserId,
1763 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error> {
1764 self.store.get_user_room_receipt_event(room_id, receipt_type, thread, user_id).await
1765 }
1766
1767 async fn get_event_room_receipt_events(
1768 &self,
1769 room_id: &RoomId,
1770 receipt_type: ReceiptType,
1771 thread: ReceiptThread,
1772 event_id: &EventId,
1773 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error> {
1774 self.store.get_event_room_receipt_events(room_id, receipt_type, thread, event_id).await
1775 }
1776
1777 async fn get_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1778 self.store.get_custom_value(key).await
1779 }
1780
1781 async fn set_custom_value(
1782 &self,
1783 key: &[u8],
1784 value: Vec<u8>,
1785 ) -> Result<Option<Vec<u8>>, Self::Error> {
1786 self.store.set_custom_value(key, value).await
1787 }
1788
1789 async fn remove_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1790 self.store.remove_custom_value(key).await
1791 }
1792
1793 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error> {
1794 let _guard = self.lock.lock().await;
1795 self.store.remove_room(room_id).await
1796 }
1797
1798 async fn save_send_queue_request(
1799 &self,
1800 room_id: &RoomId,
1801 transaction_id: OwnedTransactionId,
1802 created_at: MilliSecondsSinceUnixEpoch,
1803 request: QueuedRequestKind,
1804 priority: usize,
1805 ) -> Result<(), Self::Error> {
1806 self.store
1807 .save_send_queue_request(room_id, transaction_id, created_at, request, priority)
1808 .await
1809 }
1810
1811 async fn update_send_queue_request(
1812 &self,
1813 room_id: &RoomId,
1814 transaction_id: &TransactionId,
1815 content: QueuedRequestKind,
1816 ) -> Result<bool, Self::Error> {
1817 self.store.update_send_queue_request(room_id, transaction_id, content).await
1818 }
1819
1820 async fn remove_send_queue_request(
1821 &self,
1822 room_id: &RoomId,
1823 transaction_id: &TransactionId,
1824 ) -> Result<bool, Self::Error> {
1825 self.store.remove_send_queue_request(room_id, transaction_id).await
1826 }
1827
1828 async fn load_send_queue_requests(
1829 &self,
1830 room_id: &RoomId,
1831 ) -> Result<Vec<QueuedRequest>, Self::Error> {
1832 self.store.load_send_queue_requests(room_id).await
1833 }
1834
1835 async fn update_send_queue_request_status(
1836 &self,
1837 room_id: &RoomId,
1838 transaction_id: &TransactionId,
1839 error: Option<QueueWedgeError>,
1840 ) -> Result<(), Self::Error> {
1841 self.store.update_send_queue_request_status(room_id, transaction_id, error).await
1842 }
1843
1844 async fn load_rooms_with_unsent_requests(&self) -> Result<Vec<OwnedRoomId>, Self::Error> {
1845 self.store.load_rooms_with_unsent_requests().await
1846 }
1847
1848 async fn save_dependent_queued_request(
1849 &self,
1850 room_id: &RoomId,
1851 parent_txn_id: &TransactionId,
1852 own_txn_id: ChildTransactionId,
1853 created_at: MilliSecondsSinceUnixEpoch,
1854 content: DependentQueuedRequestKind,
1855 ) -> Result<(), Self::Error> {
1856 self.store
1857 .save_dependent_queued_request(room_id, parent_txn_id, own_txn_id, created_at, content)
1858 .await
1859 }
1860
1861 async fn mark_dependent_queued_requests_as_ready(
1862 &self,
1863 room_id: &RoomId,
1864 parent_txn_id: &TransactionId,
1865 sent_parent_key: SentRequestKey,
1866 ) -> Result<usize, Self::Error> {
1867 self.store
1868 .mark_dependent_queued_requests_as_ready(room_id, parent_txn_id, sent_parent_key)
1869 .await
1870 }
1871
1872 async fn update_dependent_queued_request(
1873 &self,
1874 room_id: &RoomId,
1875 own_transaction_id: &ChildTransactionId,
1876 new_content: DependentQueuedRequestKind,
1877 ) -> Result<bool, Self::Error> {
1878 self.store.update_dependent_queued_request(room_id, own_transaction_id, new_content).await
1879 }
1880
1881 async fn remove_dependent_queued_request(
1882 &self,
1883 room: &RoomId,
1884 own_txn_id: &ChildTransactionId,
1885 ) -> Result<bool, Self::Error> {
1886 self.store.remove_dependent_queued_request(room, own_txn_id).await
1887 }
1888
1889 async fn load_dependent_queued_requests(
1890 &self,
1891 room: &RoomId,
1892 ) -> Result<Vec<DependentQueuedRequest>, Self::Error> {
1893 self.store.load_dependent_queued_requests(room).await
1894 }
1895
1896 async fn upsert_thread_subscriptions(
1897 &self,
1898 updates: Vec<(&RoomId, &EventId, StoredThreadSubscription)>,
1899 ) -> Result<(), Self::Error> {
1900 self.store.upsert_thread_subscriptions(updates).await
1901 }
1902
1903 async fn load_thread_subscription(
1904 &self,
1905 room: &RoomId,
1906 thread_id: &EventId,
1907 ) -> Result<Option<StoredThreadSubscription>, Self::Error> {
1908 self.store.load_thread_subscription(room, thread_id).await
1909 }
1910
1911 async fn remove_thread_subscription(
1912 &self,
1913 room: &RoomId,
1914 thread_id: &EventId,
1915 ) -> Result<(), Self::Error> {
1916 self.store.remove_thread_subscription(room, thread_id).await
1917 }
1918
1919 async fn get_global_profile(
1920 &self,
1921 user_id: &UserId,
1922 ) -> Result<Option<UserProfile>, Self::Error> {
1923 self.store.get_global_profile(user_id).await
1924 }
1925
1926 async fn get_global_profiles<'a>(
1927 &self,
1928 user_ids: &'a [OwnedUserId],
1929 ) -> Result<BTreeMap<&'a UserId, UserProfile>, Self::Error> {
1930 self.store.get_global_profiles(user_ids).await
1931 }
1932
1933 async fn close(&self) -> Result<(), Self::Error> {
1934 self.store.close().await
1935 }
1936
1937 async fn reopen(&self) -> Result<(), Self::Error> {
1938 self.store.reopen().await
1939 }
1940
1941 async fn optimize(&self) -> Result<(), Self::Error> {
1942 self.store.optimize().await
1943 }
1944
1945 async fn get_size(&self) -> Result<Option<usize>, Self::Error> {
1946 self.store.get_size().await
1947 }
1948}
1949
1950#[cfg_attr(target_family = "wasm", async_trait(?Send))]
1952#[cfg_attr(not(target_family = "wasm"), async_trait)]
1953pub trait StateStoreExt: StateStore {
1954 async fn get_state_event_static<C>(
1960 &self,
1961 room_id: &RoomId,
1962 ) -> Result<Option<RawSyncOrStrippedState<C>>, Self::Error>
1963 where
1964 C: StaticEventContent<IsPrefix = ruma::events::False>
1965 + StaticStateEventContent<StateKey = EmptyStateKey>
1966 + RedactContent,
1967 C::Redacted: RedactedStateEventContent,
1968 {
1969 Ok(self.get_state_event(room_id, C::TYPE.into(), "").await?.map(|raw| raw.cast()))
1970 }
1971
1972 async fn get_state_event_static_for_key<C, K>(
1978 &self,
1979 room_id: &RoomId,
1980 state_key: &K,
1981 ) -> Result<Option<RawSyncOrStrippedState<C>>, Self::Error>
1982 where
1983 C: StaticEventContent<IsPrefix = ruma::events::False>
1984 + StaticStateEventContent
1985 + RedactContent,
1986 C::StateKey: Borrow<K>,
1987 C::Redacted: RedactedStateEventContent,
1988 K: AsRef<str> + ?Sized + Sync,
1989 {
1990 Ok(self
1991 .get_state_event(room_id, C::TYPE.into(), state_key.as_ref())
1992 .await?
1993 .map(|raw| raw.cast()))
1994 }
1995
1996 async fn get_state_events_static<C>(
2002 &self,
2003 room_id: &RoomId,
2004 ) -> Result<Vec<RawSyncOrStrippedState<C>>, Self::Error>
2005 where
2006 C: StaticEventContent<IsPrefix = ruma::events::False>
2007 + StaticStateEventContent
2008 + RedactContent,
2009 C::Redacted: RedactedStateEventContent,
2010 {
2011 Ok(self
2013 .get_state_events(room_id, C::TYPE.into())
2014 .await?
2015 .into_iter()
2016 .map(|raw| raw.cast())
2017 .collect())
2018 }
2019
2020 async fn get_state_events_for_keys_static<'a, C, K, I>(
2029 &self,
2030 room_id: &RoomId,
2031 state_keys: I,
2032 ) -> Result<Vec<RawSyncOrStrippedState<C>>, Self::Error>
2033 where
2034 C: StaticEventContent<IsPrefix = ruma::events::False>
2035 + StaticStateEventContent
2036 + RedactContent,
2037 C::StateKey: Borrow<K>,
2038 C::Redacted: RedactedStateEventContent,
2039 K: AsRef<str> + Sized + Sync + 'a,
2040 I: IntoIterator<Item = &'a K> + Send,
2041 I::IntoIter: Send,
2042 {
2043 Ok(self
2044 .get_state_events_for_keys(
2045 room_id,
2046 C::TYPE.into(),
2047 &state_keys.into_iter().map(|k| k.as_ref()).collect::<Vec<_>>(),
2048 )
2049 .await?
2050 .into_iter()
2051 .map(|raw| raw.cast())
2052 .collect())
2053 }
2054
2055 async fn get_account_data_event_static<C>(
2057 &self,
2058 ) -> Result<Option<Raw<GlobalAccountDataEvent<C>>>, Self::Error>
2059 where
2060 C: StaticEventContent<IsPrefix = ruma::events::False> + GlobalAccountDataEventContent,
2061 {
2062 Ok(self.get_account_data_event(C::TYPE.into()).await?.map(Raw::cast_unchecked))
2063 }
2064
2065 async fn get_room_account_data_event_static<C>(
2073 &self,
2074 room_id: &RoomId,
2075 ) -> Result<Option<Raw<RoomAccountDataEvent<C>>>, Self::Error>
2076 where
2077 C: StaticEventContent<IsPrefix = ruma::events::False> + RoomAccountDataEventContent,
2078 {
2079 Ok(self
2080 .get_room_account_data_event(room_id, C::TYPE.into())
2081 .await?
2082 .map(Raw::cast_unchecked))
2083 }
2084
2085 async fn get_member_event(
2093 &self,
2094 room_id: &RoomId,
2095 state_key: &UserId,
2096 ) -> Result<Option<RawMemberEvent>, Self::Error> {
2097 self.get_state_event_static_for_key(room_id, state_key).await
2098 }
2099}
2100
2101#[cfg_attr(target_family = "wasm", async_trait(?Send))]
2102#[cfg_attr(not(target_family = "wasm"), async_trait)]
2103impl<T: StateStore + ?Sized> StateStoreExt for T {}
2104
2105pub type DynStateStore = dyn StateStore<Error = StoreError>;
2107
2108pub trait IntoStateStore {
2114 #[doc(hidden)]
2115 fn into_state_store(self) -> Arc<DynStateStore>;
2116}
2117
2118impl<T> IntoStateStore for T
2119where
2120 T: StateStore + Sized + 'static,
2121{
2122 fn into_state_store(self) -> Arc<DynStateStore> {
2123 Arc::new(EraseStateStoreError(self))
2124 }
2125}
2126
2127#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
2129pub struct SupportedVersionsResponse {
2130 pub versions: Vec<String>,
2132
2133 pub unstable_features: BTreeMap<String, bool>,
2135}
2136
2137impl SupportedVersionsResponse {
2138 pub fn supported_versions(&self) -> SupportedVersions {
2144 let mut supported_versions =
2145 SupportedVersions::from_parts(&self.versions, &self.unstable_features);
2146
2147 if supported_versions.versions.is_empty() {
2150 supported_versions.versions.insert(MatrixVersion::V1_0);
2151 }
2152
2153 supported_versions
2154 }
2155}
2156
2157#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
2158pub struct WellKnownResponse {
2160 pub homeserver: HomeserverInfo,
2162
2163 pub identity_server: Option<IdentityServerInfo>,
2165
2166 pub tile_server: Option<TileServerInfo>,
2168
2169 pub rtc_foci: Vec<RtcTransport>,
2171}
2172
2173impl From<discover_homeserver::Response> for WellKnownResponse {
2174 fn from(response: discover_homeserver::Response) -> Self {
2175 Self {
2176 homeserver: response.homeserver,
2177 identity_server: response.identity_server,
2178 tile_server: response.tile_server,
2179 rtc_foci: response.rtc_foci,
2180 }
2181 }
2182}
2183
2184#[derive(Debug, Clone)]
2186pub enum StateStoreDataValue {
2187 SyncToken(String),
2189
2190 SupportedVersions(TtlValue<SupportedVersionsResponse>),
2192
2193 WellKnown(TtlValue<Option<WellKnownResponse>>),
2195
2196 Filter(String),
2198
2199 UserAvatarUrl(OwnedMxcUri),
2201
2202 RecentlyVisitedRooms(Vec<OwnedRoomId>),
2204
2205 UtdHookManagerData(GrowableBloom),
2208
2209 OneTimeKeyAlreadyUploaded,
2212
2213 ComposerDraft(ComposerDraft),
2218
2219 SeenKnockRequests(BTreeMap<OwnedEventId, OwnedUserId>),
2221
2222 ThreadSubscriptionsCatchupTokens(Vec<ThreadSubscriptionCatchupToken>),
2227
2228 HomeserverCapabilities(TtlValue<Capabilities>),
2230}
2231
2232#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2242pub struct ThreadSubscriptionCatchupToken {
2243 pub from: String,
2249
2250 pub to: Option<String>,
2256}
2257
2258#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2260pub struct ComposerDraft {
2261 pub plain_text: String,
2263 pub html_text: Option<String>,
2266 pub draft_type: ComposerDraftType,
2268 #[serde(default)]
2270 pub attachments: Vec<DraftAttachment>,
2271}
2272
2273#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2275pub struct DraftAttachment {
2276 pub filename: String,
2278 pub content: DraftAttachmentContent,
2280}
2281
2282#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2284#[serde(tag = "type")]
2285pub enum DraftAttachmentContent {
2286 Image {
2288 data: Vec<u8>,
2290 mimetype: Option<String>,
2292 size: Option<u64>,
2294 width: Option<u64>,
2296 height: Option<u64>,
2298 blurhash: Option<String>,
2300 thumbnail: Option<DraftThumbnail>,
2302 },
2303 Video {
2305 data: Vec<u8>,
2307 mimetype: Option<String>,
2309 size: Option<u64>,
2311 width: Option<u64>,
2313 height: Option<u64>,
2315 duration: Option<std::time::Duration>,
2317 blurhash: Option<String>,
2319 thumbnail: Option<DraftThumbnail>,
2321 },
2322 Audio {
2324 data: Vec<u8>,
2326 mimetype: Option<String>,
2328 size: Option<u64>,
2330 duration: Option<std::time::Duration>,
2332 },
2333 File {
2335 data: Vec<u8>,
2337 mimetype: Option<String>,
2339 size: Option<u64>,
2341 },
2342}
2343
2344#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2346pub struct DraftThumbnail {
2347 pub filename: String,
2349 pub data: Vec<u8>,
2351 pub mimetype: Option<String>,
2353 pub width: Option<u64>,
2355 pub height: Option<u64>,
2357 pub size: Option<u64>,
2359}
2360
2361#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2363pub enum ComposerDraftType {
2364 NewMessage,
2366 Reply {
2368 event_id: OwnedEventId,
2370 },
2371 Edit {
2373 event_id: OwnedEventId,
2375 },
2376}
2377
2378impl StateStoreDataValue {
2379 pub fn into_sync_token(self) -> Option<String> {
2381 as_variant!(self, Self::SyncToken)
2382 }
2383
2384 pub fn into_filter(self) -> Option<String> {
2386 as_variant!(self, Self::Filter)
2387 }
2388
2389 pub fn into_user_avatar_url(self) -> Option<OwnedMxcUri> {
2391 as_variant!(self, Self::UserAvatarUrl)
2392 }
2393
2394 pub fn into_recently_visited_rooms(self) -> Option<Vec<OwnedRoomId>> {
2396 as_variant!(self, Self::RecentlyVisitedRooms)
2397 }
2398
2399 pub fn into_utd_hook_manager_data(self) -> Option<GrowableBloom> {
2401 as_variant!(self, Self::UtdHookManagerData)
2402 }
2403
2404 pub fn into_composer_draft(self) -> Option<ComposerDraft> {
2406 as_variant!(self, Self::ComposerDraft)
2407 }
2408
2409 pub fn into_supported_versions(self) -> Option<TtlValue<SupportedVersionsResponse>> {
2411 as_variant!(self, Self::SupportedVersions)
2412 }
2413
2414 pub fn into_well_known(self) -> Option<TtlValue<Option<WellKnownResponse>>> {
2416 as_variant!(self, Self::WellKnown)
2417 }
2418
2419 pub fn into_seen_knock_requests(self) -> Option<BTreeMap<OwnedEventId, OwnedUserId>> {
2421 as_variant!(self, Self::SeenKnockRequests)
2422 }
2423
2424 pub fn into_thread_subscriptions_catchup_tokens(
2427 self,
2428 ) -> Option<Vec<ThreadSubscriptionCatchupToken>> {
2429 as_variant!(self, Self::ThreadSubscriptionsCatchupTokens)
2430 }
2431
2432 pub fn into_homeserver_capabilities(self) -> Option<TtlValue<Capabilities>> {
2435 as_variant!(self, Self::HomeserverCapabilities)
2436 }
2437}
2438
2439#[derive(Debug, Clone, Copy)]
2441pub enum StateStoreDataKey<'a> {
2442 SyncToken,
2444
2445 SupportedVersions,
2447
2448 WellKnown,
2450
2451 Filter(&'a str),
2453
2454 UserAvatarUrl(&'a UserId),
2456
2457 RecentlyVisitedRooms(&'a UserId),
2459
2460 UtdHookManagerData,
2463
2464 OneTimeKeyAlreadyUploaded,
2467
2468 ComposerDraft(&'a RoomId, Option<&'a EventId>),
2473
2474 SeenKnockRequests(&'a RoomId),
2476
2477 ThreadSubscriptionsCatchupTokens,
2479
2480 HomeserverCapabilities,
2482}
2483
2484impl StateStoreDataKey<'_> {
2485 pub const SYNC_TOKEN: &'static str = "sync_token";
2487
2488 pub const SUPPORTED_VERSIONS: &'static str = "server_capabilities"; pub const WELL_KNOWN: &'static str = "well_known";
2495
2496 pub const FILTER: &'static str = "filter";
2498
2499 pub const USER_AVATAR_URL: &'static str = "user_avatar_url";
2502
2503 pub const RECENTLY_VISITED_ROOMS: &'static str = "recently_visited_rooms";
2506
2507 pub const UTD_HOOK_MANAGER_DATA: &'static str = "utd_hook_manager_data";
2510
2511 pub const ONE_TIME_KEY_ALREADY_UPLOADED: &'static str = "one_time_key_already_uploaded";
2514
2515 pub const COMPOSER_DRAFT: &'static str = "composer_draft";
2518
2519 pub const SEEN_KNOCK_REQUESTS: &'static str = "seen_knock_requests";
2522
2523 pub const THREAD_SUBSCRIPTIONS_CATCHUP_TOKENS: &'static str =
2526 "thread_subscriptions_catchup_tokens";
2527
2528 pub const HOMESERVER_CAPABILITIES: &'static str = "homeserver_capabilities";
2530}
2531
2532pub fn compare_thread_subscription_bump_stamps(
2541 previous: Option<u64>,
2542 new: &mut Option<u64>,
2543) -> bool {
2544 match (previous, &new) {
2545 (Some(prev_bump), None) => {
2548 *new = Some(prev_bump);
2549 }
2550
2551 (Some(prev_bump), Some(new_bump)) if *new_bump <= prev_bump => {
2553 return false;
2554 }
2555
2556 _ => {}
2558 }
2559
2560 true
2561}
2562
2563#[cfg(test)]
2564mod tests {
2565 mod save_locked_state_store {
2566 use std::time::Duration;
2567
2568 use assert_matches::assert_matches;
2569 use futures_util::future::{self, Either};
2570 #[cfg(all(target_family = "wasm", target_os = "unknown"))]
2571 use gloo_timers::future::sleep;
2572 use matrix_sdk_common::executor::spawn;
2573 use matrix_sdk_test::async_test;
2574 use ruma::room_id;
2575 use tokio::sync::Mutex;
2576 #[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
2577 use tokio::time::sleep;
2578
2579 use crate::{
2580 StateChanges, StateStore,
2581 store::{IntoStateStore, MemoryStore, Result, SaveLockedStateStore},
2582 };
2583
2584 async fn get_store() -> Result<impl StateStore> {
2585 Ok(SaveLockedStateStore::new(MemoryStore::new()))
2586 }
2587
2588 statestore_integration_tests!();
2589
2590 #[async_test]
2591 async fn test_save_changes_only_accepts_guard_for_underlying_mutex() {
2592 let state_store = SaveLockedStateStore::new(MemoryStore::new());
2593 let state_changes = StateChanges::default();
2594 state_store
2595 .save_changes_with_guard(&state_store.lock().lock().await, &state_changes)
2596 .await
2597 .expect("state store accepts guard for underlying mutex");
2598
2599 let mutex = Mutex::new(());
2600 state_store
2601 .save_changes_with_guard(&mutex.lock().await, &state_changes)
2602 .await
2603 .expect_err("state store does not accept guard for unknown mutex");
2604 }
2605
2606 #[async_test]
2607 async fn test_remove_room_only_accepts_guard_for_underlying_mutex() {
2608 let state_store = SaveLockedStateStore::new(MemoryStore::new());
2609 let room_id = room_id!("!room");
2610 state_store
2611 .remove_room_with_guard(&state_store.lock().lock().await, room_id)
2612 .await
2613 .expect("state store accepts guard for underlying mutex");
2614
2615 let mutex = Mutex::new(());
2616 state_store
2617 .remove_room_with_guard(&mutex.lock().await, room_id)
2618 .await
2619 .expect_err("state store does not accept guard for unknown mutex");
2620 }
2621
2622 #[derive(Debug)]
2623 struct Elapsed;
2624
2625 async fn timeout<F: Future + Unpin>(
2626 duration: Duration,
2627 f: F,
2628 ) -> Result<F::Output, Elapsed> {
2629 #[cfg(all(target_family = "wasm", target_os = "unknown"))]
2630 {
2631 match future::select(sleep(duration), f).await {
2632 Either::Left(_) => return Err(Elapsed),
2633 Either::Right((output, _)) => Ok(output),
2634 }
2635 }
2636 #[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
2637 {
2638 tokio::time::timeout(duration, f).await.map_err(|_| Elapsed)
2639 }
2640 }
2641
2642 #[async_test]
2643 async fn test_state_store_waits_to_acquire_lock_before_saving_changes() {
2644 let state_store = SaveLockedStateStore::new(MemoryStore::new().into_state_store());
2645
2646 let lock_task = spawn({
2648 let state_store = state_store.clone();
2649 async move {
2650 let lock = state_store.lock();
2651 let _guard = lock.lock().await;
2652 sleep(Duration::from_secs(5)).await;
2653 }
2654 });
2655
2656 let save_task =
2658 spawn(async move { state_store.save_changes(&StateChanges::default()).await });
2659
2660 assert_matches!(future::select(lock_task, save_task).await, Either::Left((_, save_task)) => {
2663 timeout(Duration::from_millis(100), save_task)
2664 .await
2665 .expect("task completes before timeout")
2666 .expect("task completes successfully")
2667 .expect("task saves changes");
2668 });
2669 }
2670
2671 #[async_test]
2672 async fn test_state_store_waits_to_acquire_lock_before_removing_room() {
2673 let state_store = SaveLockedStateStore::new(MemoryStore::new().into_state_store());
2674
2675 let lock_task = spawn({
2677 let state_store = state_store.clone();
2678 async move {
2679 let lock = state_store.lock();
2680 let _guard = lock.lock().await;
2681 sleep(Duration::from_secs(5)).await;
2682 }
2683 });
2684
2685 let remove_task =
2688 spawn(async move { state_store.remove_room(room_id!("!room")).await });
2689
2690 assert_matches!(future::select(lock_task, remove_task).await, Either::Left((_, remove_task)) => {
2693 timeout(Duration::from_millis(100), remove_task)
2694 .await
2695 .expect("task completes before timeout")
2696 .expect("task completes successfully")
2697 .expect("task saves changes");
2698 });
2699 }
2700 }
2701}