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 close(&self) -> Result<(), Self::Error>;
540
541 async fn reopen(&self) -> Result<(), Self::Error>;
544
545 #[doc(hidden)]
551 async fn optimize(&self) -> Result<(), Self::Error>;
552
553 async fn get_size(&self) -> Result<Option<usize>, Self::Error>;
555}
556
557#[cfg_attr(target_family = "wasm", async_trait(?Send))]
558#[cfg_attr(not(target_family = "wasm"), async_trait)]
559impl<T: StateStore> StateStore for &T {
560 type Error = T::Error;
561
562 async fn get_kv_data(
563 &self,
564 key: StateStoreDataKey<'_>,
565 ) -> Result<Option<StateStoreDataValue>, Self::Error> {
566 (*self).get_kv_data(key).await
567 }
568
569 async fn set_kv_data(
570 &self,
571 key: StateStoreDataKey<'_>,
572 value: StateStoreDataValue,
573 ) -> Result<(), Self::Error> {
574 (*self).set_kv_data(key, value).await
575 }
576
577 async fn remove_kv_data(&self, key: StateStoreDataKey<'_>) -> Result<(), Self::Error> {
578 (*self).remove_kv_data(key).await
579 }
580
581 async fn save_changes(&self, changes: &StateChanges) -> Result<(), Self::Error> {
582 (*self).save_changes(changes).await
583 }
584
585 async fn get_presence_event(
586 &self,
587 user_id: &UserId,
588 ) -> Result<Option<Raw<PresenceEvent>>, Self::Error> {
589 (*self).get_presence_event(user_id).await
590 }
591
592 async fn get_presence_events(
593 &self,
594 user_ids: &[OwnedUserId],
595 ) -> Result<Vec<Raw<PresenceEvent>>, Self::Error> {
596 (*self).get_presence_events(user_ids).await
597 }
598
599 async fn get_state_event(
600 &self,
601 room_id: &RoomId,
602 event_type: StateEventType,
603 state_key: &str,
604 ) -> Result<Option<RawAnySyncOrStrippedState>, Self::Error> {
605 (*self).get_state_event(room_id, event_type, state_key).await
606 }
607
608 async fn get_state_events(
609 &self,
610 room_id: &RoomId,
611 event_type: StateEventType,
612 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
613 (*self).get_state_events(room_id, event_type).await
614 }
615
616 async fn get_state_events_for_keys(
617 &self,
618 room_id: &RoomId,
619 event_type: StateEventType,
620 state_keys: &[&str],
621 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
622 (*self).get_state_events_for_keys(room_id, event_type, state_keys).await
623 }
624
625 async fn get_profile(
626 &self,
627 room_id: &RoomId,
628 user_id: &UserId,
629 ) -> Result<Option<MinimalRoomMemberEvent>, Self::Error> {
630 (*self).get_profile(room_id, user_id).await
631 }
632
633 async fn get_profiles<'a>(
634 &self,
635 room_id: &RoomId,
636 user_ids: &'a [OwnedUserId],
637 ) -> Result<BTreeMap<&'a UserId, MinimalRoomMemberEvent>, Self::Error> {
638 (*self).get_profiles(room_id, user_ids).await
639 }
640
641 async fn get_user_ids(
642 &self,
643 room_id: &RoomId,
644 memberships: RoomMemberships,
645 ) -> Result<Vec<OwnedUserId>, Self::Error> {
646 (*self).get_user_ids(room_id, memberships).await
647 }
648
649 async fn get_room_infos(
650 &self,
651 room_load_settings: &RoomLoadSettings,
652 ) -> Result<Vec<RoomInfo>, Self::Error> {
653 (*self).get_room_infos(room_load_settings).await
654 }
655
656 async fn get_users_with_display_name(
657 &self,
658 room_id: &RoomId,
659 display_name: &DisplayName,
660 ) -> Result<BTreeSet<OwnedUserId>, Self::Error> {
661 (*self).get_users_with_display_name(room_id, display_name).await
662 }
663
664 async fn get_users_with_display_names<'a>(
665 &self,
666 room_id: &RoomId,
667 display_names: &'a [DisplayName],
668 ) -> Result<HashMap<&'a DisplayName, BTreeSet<OwnedUserId>>, Self::Error> {
669 (*self).get_users_with_display_names(room_id, display_names).await
670 }
671
672 async fn get_account_data_event(
673 &self,
674 event_type: GlobalAccountDataEventType,
675 ) -> Result<Option<Raw<AnyGlobalAccountDataEvent>>, Self::Error> {
676 (*self).get_account_data_event(event_type).await
677 }
678
679 async fn get_room_account_data_event(
680 &self,
681 room_id: &RoomId,
682 event_type: RoomAccountDataEventType,
683 ) -> Result<Option<Raw<AnyRoomAccountDataEvent>>, Self::Error> {
684 (*self).get_room_account_data_event(room_id, event_type).await
685 }
686
687 async fn get_user_room_receipt_event(
688 &self,
689 room_id: &RoomId,
690 receipt_type: ReceiptType,
691 receipt_thread: &ReceiptThread,
692 user_id: &UserId,
693 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error> {
694 (*self).get_user_room_receipt_event(room_id, receipt_type, receipt_thread, user_id).await
695 }
696
697 async fn get_event_room_receipt_events(
698 &self,
699 room_id: &RoomId,
700 receipt_type: ReceiptType,
701 receipt_thread: &ReceiptThread,
702 event_id: &EventId,
703 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error> {
704 (*self).get_event_room_receipt_events(room_id, receipt_type, receipt_thread, event_id).await
705 }
706
707 async fn get_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
708 (*self).get_custom_value(key).await
709 }
710
711 async fn set_custom_value(
712 &self,
713 key: &[u8],
714 value: Vec<u8>,
715 ) -> Result<Option<Vec<u8>>, Self::Error> {
716 (*self).set_custom_value(key, value).await
717 }
718
719 async fn remove_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
720 (*self).remove_custom_value(key).await
721 }
722
723 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error> {
724 (*self).remove_room(room_id).await
725 }
726
727 async fn save_send_queue_request(
728 &self,
729 room_id: &RoomId,
730 transaction_id: OwnedTransactionId,
731 created_at: MilliSecondsSinceUnixEpoch,
732 request: QueuedRequestKind,
733 priority: usize,
734 ) -> Result<(), Self::Error> {
735 (*self)
736 .save_send_queue_request(room_id, transaction_id, created_at, request, priority)
737 .await
738 }
739
740 async fn update_send_queue_request(
741 &self,
742 room_id: &RoomId,
743 transaction_id: &TransactionId,
744 content: QueuedRequestKind,
745 ) -> Result<bool, Self::Error> {
746 (*self).update_send_queue_request(room_id, transaction_id, content).await
747 }
748
749 async fn remove_send_queue_request(
750 &self,
751 room_id: &RoomId,
752 transaction_id: &TransactionId,
753 ) -> Result<bool, Self::Error> {
754 (*self).remove_send_queue_request(room_id, transaction_id).await
755 }
756
757 async fn load_send_queue_requests(
758 &self,
759 room_id: &RoomId,
760 ) -> Result<Vec<QueuedRequest>, Self::Error> {
761 (*self).load_send_queue_requests(room_id).await
762 }
763
764 async fn update_send_queue_request_status(
765 &self,
766 room_id: &RoomId,
767 transaction_id: &TransactionId,
768 error: Option<QueueWedgeError>,
769 ) -> Result<(), Self::Error> {
770 (*self).update_send_queue_request_status(room_id, transaction_id, error).await
771 }
772
773 async fn load_rooms_with_unsent_requests(&self) -> Result<Vec<OwnedRoomId>, Self::Error> {
774 (*self).load_rooms_with_unsent_requests().await
775 }
776
777 async fn save_dependent_queued_request(
778 &self,
779 room_id: &RoomId,
780 parent_txn_id: &TransactionId,
781 own_txn_id: ChildTransactionId,
782 created_at: MilliSecondsSinceUnixEpoch,
783 content: DependentQueuedRequestKind,
784 ) -> Result<(), Self::Error> {
785 (*self)
786 .save_dependent_queued_request(room_id, parent_txn_id, own_txn_id, created_at, content)
787 .await
788 }
789
790 async fn mark_dependent_queued_requests_as_ready(
791 &self,
792 room_id: &RoomId,
793 parent_txn_id: &TransactionId,
794 sent_parent_key: SentRequestKey,
795 ) -> Result<usize, Self::Error> {
796 (*self)
797 .mark_dependent_queued_requests_as_ready(room_id, parent_txn_id, sent_parent_key)
798 .await
799 }
800
801 async fn update_dependent_queued_request(
802 &self,
803 room_id: &RoomId,
804 own_transaction_id: &ChildTransactionId,
805 new_content: DependentQueuedRequestKind,
806 ) -> Result<bool, Self::Error> {
807 (*self).update_dependent_queued_request(room_id, own_transaction_id, new_content).await
808 }
809
810 async fn remove_dependent_queued_request(
811 &self,
812 room: &RoomId,
813 own_txn_id: &ChildTransactionId,
814 ) -> Result<bool, Self::Error> {
815 (*self).remove_dependent_queued_request(room, own_txn_id).await
816 }
817
818 async fn load_dependent_queued_requests(
819 &self,
820 room: &RoomId,
821 ) -> Result<Vec<DependentQueuedRequest>, Self::Error> {
822 (*self).load_dependent_queued_requests(room).await
823 }
824
825 async fn upsert_thread_subscriptions(
826 &self,
827 updates: Vec<(&RoomId, &EventId, StoredThreadSubscription)>,
828 ) -> Result<(), Self::Error> {
829 (*self).upsert_thread_subscriptions(updates).await
830 }
831
832 async fn remove_thread_subscription(
833 &self,
834 room: &RoomId,
835 thread_id: &EventId,
836 ) -> Result<(), Self::Error> {
837 (*self).remove_thread_subscription(room, thread_id).await
838 }
839
840 async fn load_thread_subscription(
841 &self,
842 room: &RoomId,
843 thread_id: &EventId,
844 ) -> Result<Option<StoredThreadSubscription>, Self::Error> {
845 (*self).load_thread_subscription(room, thread_id).await
846 }
847
848 async fn get_global_profile(
849 &self,
850 user_id: &UserId,
851 ) -> Result<Option<UserProfile>, Self::Error> {
852 (*self).get_global_profile(user_id).await
853 }
854
855 async fn get_global_profiles<'a>(
856 &self,
857 user_ids: &'a [OwnedUserId],
858 ) -> Result<BTreeMap<&'a UserId, UserProfile>, Self::Error> {
859 (*self).get_global_profiles(user_ids).await
860 }
861
862 async fn close(&self) -> Result<(), Self::Error> {
863 (*self).close().await
864 }
865
866 async fn reopen(&self) -> Result<(), Self::Error> {
867 (*self).reopen().await
868 }
869
870 async fn optimize(&self) -> Result<(), Self::Error> {
871 (*self).optimize().await
872 }
873
874 async fn get_size(&self) -> Result<Option<usize>, Self::Error> {
875 (*self).get_size().await
876 }
877}
878
879#[cfg_attr(target_family = "wasm", async_trait(?Send))]
880#[cfg_attr(not(target_family = "wasm"), async_trait)]
881impl<T: StateStore + ?Sized> StateStore for Arc<T> {
882 type Error = T::Error;
883
884 async fn get_kv_data(
885 &self,
886 key: StateStoreDataKey<'_>,
887 ) -> Result<Option<StateStoreDataValue>, Self::Error> {
888 self.deref().get_kv_data(key).await
889 }
890
891 async fn set_kv_data(
892 &self,
893 key: StateStoreDataKey<'_>,
894 value: StateStoreDataValue,
895 ) -> Result<(), Self::Error> {
896 self.deref().set_kv_data(key, value).await
897 }
898
899 async fn remove_kv_data(&self, key: StateStoreDataKey<'_>) -> Result<(), Self::Error> {
900 self.deref().remove_kv_data(key).await
901 }
902
903 async fn save_changes(&self, changes: &StateChanges) -> Result<(), Self::Error> {
904 self.deref().save_changes(changes).await
905 }
906
907 async fn get_presence_event(
908 &self,
909 user_id: &UserId,
910 ) -> Result<Option<Raw<PresenceEvent>>, Self::Error> {
911 self.deref().get_presence_event(user_id).await
912 }
913
914 async fn get_presence_events(
915 &self,
916 user_ids: &[OwnedUserId],
917 ) -> Result<Vec<Raw<PresenceEvent>>, Self::Error> {
918 self.deref().get_presence_events(user_ids).await
919 }
920
921 async fn get_state_event(
922 &self,
923 room_id: &RoomId,
924 event_type: StateEventType,
925 state_key: &str,
926 ) -> Result<Option<RawAnySyncOrStrippedState>, Self::Error> {
927 self.deref().get_state_event(room_id, event_type, state_key).await
928 }
929
930 async fn get_state_events(
931 &self,
932 room_id: &RoomId,
933 event_type: StateEventType,
934 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
935 self.deref().get_state_events(room_id, event_type).await
936 }
937
938 async fn get_state_events_for_keys(
939 &self,
940 room_id: &RoomId,
941 event_type: StateEventType,
942 state_keys: &[&str],
943 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
944 self.deref().get_state_events_for_keys(room_id, event_type, state_keys).await
945 }
946
947 async fn get_profile(
948 &self,
949 room_id: &RoomId,
950 user_id: &UserId,
951 ) -> Result<Option<MinimalRoomMemberEvent>, Self::Error> {
952 self.deref().get_profile(room_id, user_id).await
953 }
954
955 async fn get_profiles<'a>(
956 &self,
957 room_id: &RoomId,
958 user_ids: &'a [OwnedUserId],
959 ) -> Result<BTreeMap<&'a UserId, MinimalRoomMemberEvent>, Self::Error> {
960 self.deref().get_profiles(room_id, user_ids).await
961 }
962
963 async fn get_user_ids(
964 &self,
965 room_id: &RoomId,
966 memberships: RoomMemberships,
967 ) -> Result<Vec<OwnedUserId>, Self::Error> {
968 self.deref().get_user_ids(room_id, memberships).await
969 }
970
971 async fn get_room_infos(
972 &self,
973 room_load_settings: &RoomLoadSettings,
974 ) -> Result<Vec<RoomInfo>, Self::Error> {
975 self.deref().get_room_infos(room_load_settings).await
976 }
977
978 async fn get_users_with_display_name(
979 &self,
980 room_id: &RoomId,
981 display_name: &DisplayName,
982 ) -> Result<BTreeSet<OwnedUserId>, Self::Error> {
983 self.deref().get_users_with_display_name(room_id, display_name).await
984 }
985
986 async fn get_users_with_display_names<'a>(
987 &self,
988 room_id: &RoomId,
989 display_names: &'a [DisplayName],
990 ) -> Result<HashMap<&'a DisplayName, BTreeSet<OwnedUserId>>, Self::Error> {
991 self.deref().get_users_with_display_names(room_id, display_names).await
992 }
993
994 async fn get_account_data_event(
995 &self,
996 event_type: GlobalAccountDataEventType,
997 ) -> Result<Option<Raw<AnyGlobalAccountDataEvent>>, Self::Error> {
998 self.deref().get_account_data_event(event_type).await
999 }
1000
1001 async fn get_room_account_data_event(
1002 &self,
1003 room_id: &RoomId,
1004 event_type: RoomAccountDataEventType,
1005 ) -> Result<Option<Raw<AnyRoomAccountDataEvent>>, Self::Error> {
1006 self.deref().get_room_account_data_event(room_id, event_type).await
1007 }
1008
1009 async fn get_user_room_receipt_event(
1010 &self,
1011 room_id: &RoomId,
1012 receipt_type: ReceiptType,
1013 receipt_thread: &ReceiptThread,
1014 user_id: &UserId,
1015 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error> {
1016 self.deref()
1017 .get_user_room_receipt_event(room_id, receipt_type, receipt_thread, user_id)
1018 .await
1019 }
1020
1021 async fn get_event_room_receipt_events(
1022 &self,
1023 room_id: &RoomId,
1024 receipt_type: ReceiptType,
1025 receipt_thread: &ReceiptThread,
1026 event_id: &EventId,
1027 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error> {
1028 self.deref()
1029 .get_event_room_receipt_events(room_id, receipt_type, receipt_thread, event_id)
1030 .await
1031 }
1032
1033 async fn get_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1034 self.deref().get_custom_value(key).await
1035 }
1036
1037 async fn set_custom_value(
1038 &self,
1039 key: &[u8],
1040 value: Vec<u8>,
1041 ) -> Result<Option<Vec<u8>>, Self::Error> {
1042 self.deref().set_custom_value(key, value).await
1043 }
1044
1045 async fn remove_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1046 self.deref().remove_custom_value(key).await
1047 }
1048
1049 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error> {
1050 self.deref().remove_room(room_id).await
1051 }
1052
1053 async fn save_send_queue_request(
1054 &self,
1055 room_id: &RoomId,
1056 transaction_id: OwnedTransactionId,
1057 created_at: MilliSecondsSinceUnixEpoch,
1058 request: QueuedRequestKind,
1059 priority: usize,
1060 ) -> Result<(), Self::Error> {
1061 self.deref()
1062 .save_send_queue_request(room_id, transaction_id, created_at, request, priority)
1063 .await
1064 }
1065
1066 async fn update_send_queue_request(
1067 &self,
1068 room_id: &RoomId,
1069 transaction_id: &TransactionId,
1070 content: QueuedRequestKind,
1071 ) -> Result<bool, Self::Error> {
1072 self.deref().update_send_queue_request(room_id, transaction_id, content).await
1073 }
1074
1075 async fn remove_send_queue_request(
1076 &self,
1077 room_id: &RoomId,
1078 transaction_id: &TransactionId,
1079 ) -> Result<bool, Self::Error> {
1080 self.deref().remove_send_queue_request(room_id, transaction_id).await
1081 }
1082
1083 async fn load_send_queue_requests(
1084 &self,
1085 room_id: &RoomId,
1086 ) -> Result<Vec<QueuedRequest>, Self::Error> {
1087 self.deref().load_send_queue_requests(room_id).await
1088 }
1089
1090 async fn update_send_queue_request_status(
1091 &self,
1092 room_id: &RoomId,
1093 transaction_id: &TransactionId,
1094 error: Option<QueueWedgeError>,
1095 ) -> Result<(), Self::Error> {
1096 self.deref().update_send_queue_request_status(room_id, transaction_id, error).await
1097 }
1098
1099 async fn load_rooms_with_unsent_requests(&self) -> Result<Vec<OwnedRoomId>, Self::Error> {
1100 self.deref().load_rooms_with_unsent_requests().await
1101 }
1102
1103 async fn save_dependent_queued_request(
1104 &self,
1105 room_id: &RoomId,
1106 parent_txn_id: &TransactionId,
1107 own_txn_id: ChildTransactionId,
1108 created_at: MilliSecondsSinceUnixEpoch,
1109 content: DependentQueuedRequestKind,
1110 ) -> Result<(), Self::Error> {
1111 self.deref()
1112 .save_dependent_queued_request(room_id, parent_txn_id, own_txn_id, created_at, content)
1113 .await
1114 }
1115
1116 async fn mark_dependent_queued_requests_as_ready(
1117 &self,
1118 room_id: &RoomId,
1119 parent_txn_id: &TransactionId,
1120 sent_parent_key: SentRequestKey,
1121 ) -> Result<usize, Self::Error> {
1122 self.deref()
1123 .mark_dependent_queued_requests_as_ready(room_id, parent_txn_id, sent_parent_key)
1124 .await
1125 }
1126
1127 async fn update_dependent_queued_request(
1128 &self,
1129 room_id: &RoomId,
1130 own_transaction_id: &ChildTransactionId,
1131 new_content: DependentQueuedRequestKind,
1132 ) -> Result<bool, Self::Error> {
1133 self.deref().update_dependent_queued_request(room_id, own_transaction_id, new_content).await
1134 }
1135
1136 async fn remove_dependent_queued_request(
1137 &self,
1138 room: &RoomId,
1139 own_txn_id: &ChildTransactionId,
1140 ) -> Result<bool, Self::Error> {
1141 self.deref().remove_dependent_queued_request(room, own_txn_id).await
1142 }
1143
1144 async fn load_dependent_queued_requests(
1145 &self,
1146 room: &RoomId,
1147 ) -> Result<Vec<DependentQueuedRequest>, Self::Error> {
1148 self.deref().load_dependent_queued_requests(room).await
1149 }
1150
1151 async fn upsert_thread_subscriptions(
1152 &self,
1153 updates: Vec<(&RoomId, &EventId, StoredThreadSubscription)>,
1154 ) -> Result<(), Self::Error> {
1155 self.deref().upsert_thread_subscriptions(updates).await
1156 }
1157
1158 async fn remove_thread_subscription(
1159 &self,
1160 room: &RoomId,
1161 thread_id: &EventId,
1162 ) -> Result<(), Self::Error> {
1163 self.deref().remove_thread_subscription(room, thread_id).await
1164 }
1165
1166 async fn load_thread_subscription(
1167 &self,
1168 room: &RoomId,
1169 thread_id: &EventId,
1170 ) -> Result<Option<StoredThreadSubscription>, Self::Error> {
1171 self.deref().load_thread_subscription(room, thread_id).await
1172 }
1173
1174 async fn get_global_profile(
1175 &self,
1176 user_id: &UserId,
1177 ) -> Result<Option<UserProfile>, Self::Error> {
1178 self.deref().get_global_profile(user_id).await
1179 }
1180
1181 async fn get_global_profiles<'a>(
1182 &self,
1183 user_ids: &'a [OwnedUserId],
1184 ) -> Result<BTreeMap<&'a UserId, UserProfile>, Self::Error> {
1185 self.deref().get_global_profiles(user_ids).await
1186 }
1187
1188 async fn close(&self) -> Result<(), Self::Error> {
1189 self.deref().close().await
1190 }
1191
1192 async fn reopen(&self) -> Result<(), Self::Error> {
1193 self.deref().reopen().await
1194 }
1195
1196 async fn optimize(&self) -> Result<(), Self::Error> {
1197 self.deref().optimize().await
1198 }
1199
1200 async fn get_size(&self) -> Result<Option<usize>, Self::Error> {
1201 self.deref().get_size().await
1202 }
1203}
1204
1205#[repr(transparent)]
1206struct EraseStateStoreError<T>(T);
1207
1208#[cfg(not(tarpaulin_include))]
1209impl<T: fmt::Debug> fmt::Debug for EraseStateStoreError<T> {
1210 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1211 self.0.fmt(f)
1212 }
1213}
1214
1215#[cfg_attr(target_family = "wasm", async_trait(?Send))]
1216#[cfg_attr(not(target_family = "wasm"), async_trait)]
1217impl<T: StateStore> StateStore for EraseStateStoreError<T> {
1218 type Error = StoreError;
1219
1220 async fn get_kv_data(
1221 &self,
1222 key: StateStoreDataKey<'_>,
1223 ) -> Result<Option<StateStoreDataValue>, Self::Error> {
1224 self.0.get_kv_data(key).await.map_err(Into::into)
1225 }
1226
1227 async fn set_kv_data(
1228 &self,
1229 key: StateStoreDataKey<'_>,
1230 value: StateStoreDataValue,
1231 ) -> Result<(), Self::Error> {
1232 self.0.set_kv_data(key, value).await.map_err(Into::into)
1233 }
1234
1235 async fn remove_kv_data(&self, key: StateStoreDataKey<'_>) -> Result<(), Self::Error> {
1236 self.0.remove_kv_data(key).await.map_err(Into::into)
1237 }
1238
1239 async fn save_changes(&self, changes: &StateChanges) -> Result<(), Self::Error> {
1240 self.0.save_changes(changes).await.map_err(Into::into)
1241 }
1242
1243 async fn get_presence_event(
1244 &self,
1245 user_id: &UserId,
1246 ) -> Result<Option<Raw<PresenceEvent>>, Self::Error> {
1247 self.0.get_presence_event(user_id).await.map_err(Into::into)
1248 }
1249
1250 async fn get_presence_events(
1251 &self,
1252 user_ids: &[OwnedUserId],
1253 ) -> Result<Vec<Raw<PresenceEvent>>, Self::Error> {
1254 self.0.get_presence_events(user_ids).await.map_err(Into::into)
1255 }
1256
1257 async fn get_state_event(
1258 &self,
1259 room_id: &RoomId,
1260 event_type: StateEventType,
1261 state_key: &str,
1262 ) -> Result<Option<RawAnySyncOrStrippedState>, Self::Error> {
1263 self.0.get_state_event(room_id, event_type, state_key).await.map_err(Into::into)
1264 }
1265
1266 async fn get_state_events(
1267 &self,
1268 room_id: &RoomId,
1269 event_type: StateEventType,
1270 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
1271 self.0.get_state_events(room_id, event_type).await.map_err(Into::into)
1272 }
1273
1274 async fn get_state_events_for_keys(
1275 &self,
1276 room_id: &RoomId,
1277 event_type: StateEventType,
1278 state_keys: &[&str],
1279 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
1280 self.0.get_state_events_for_keys(room_id, event_type, state_keys).await.map_err(Into::into)
1281 }
1282
1283 async fn get_profile(
1284 &self,
1285 room_id: &RoomId,
1286 user_id: &UserId,
1287 ) -> Result<Option<MinimalRoomMemberEvent>, Self::Error> {
1288 self.0.get_profile(room_id, user_id).await.map_err(Into::into)
1289 }
1290
1291 async fn get_profiles<'a>(
1292 &self,
1293 room_id: &RoomId,
1294 user_ids: &'a [OwnedUserId],
1295 ) -> Result<BTreeMap<&'a UserId, MinimalRoomMemberEvent>, Self::Error> {
1296 self.0.get_profiles(room_id, user_ids).await.map_err(Into::into)
1297 }
1298
1299 async fn get_user_ids(
1300 &self,
1301 room_id: &RoomId,
1302 memberships: RoomMemberships,
1303 ) -> Result<Vec<OwnedUserId>, Self::Error> {
1304 self.0.get_user_ids(room_id, memberships).await.map_err(Into::into)
1305 }
1306
1307 async fn get_room_infos(
1308 &self,
1309 room_load_settings: &RoomLoadSettings,
1310 ) -> Result<Vec<RoomInfo>, Self::Error> {
1311 self.0.get_room_infos(room_load_settings).await.map_err(Into::into)
1312 }
1313
1314 async fn get_users_with_display_name(
1315 &self,
1316 room_id: &RoomId,
1317 display_name: &DisplayName,
1318 ) -> Result<BTreeSet<OwnedUserId>, Self::Error> {
1319 self.0.get_users_with_display_name(room_id, display_name).await.map_err(Into::into)
1320 }
1321
1322 async fn get_users_with_display_names<'a>(
1323 &self,
1324 room_id: &RoomId,
1325 display_names: &'a [DisplayName],
1326 ) -> Result<HashMap<&'a DisplayName, BTreeSet<OwnedUserId>>, Self::Error> {
1327 self.0.get_users_with_display_names(room_id, display_names).await.map_err(Into::into)
1328 }
1329
1330 async fn get_account_data_event(
1331 &self,
1332 event_type: GlobalAccountDataEventType,
1333 ) -> Result<Option<Raw<AnyGlobalAccountDataEvent>>, Self::Error> {
1334 self.0.get_account_data_event(event_type).await.map_err(Into::into)
1335 }
1336
1337 async fn get_room_account_data_event(
1338 &self,
1339 room_id: &RoomId,
1340 event_type: RoomAccountDataEventType,
1341 ) -> Result<Option<Raw<AnyRoomAccountDataEvent>>, Self::Error> {
1342 self.0.get_room_account_data_event(room_id, event_type).await.map_err(Into::into)
1343 }
1344
1345 async fn get_user_room_receipt_event(
1346 &self,
1347 room_id: &RoomId,
1348 receipt_type: ReceiptType,
1349 receipt_thread: &ReceiptThread,
1350 user_id: &UserId,
1351 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error> {
1352 self.0
1353 .get_user_room_receipt_event(room_id, receipt_type, receipt_thread, user_id)
1354 .await
1355 .map_err(Into::into)
1356 }
1357
1358 async fn get_event_room_receipt_events(
1359 &self,
1360 room_id: &RoomId,
1361 receipt_type: ReceiptType,
1362 receipt_thread: &ReceiptThread,
1363 event_id: &EventId,
1364 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error> {
1365 self.0
1366 .get_event_room_receipt_events(room_id, receipt_type, receipt_thread, event_id)
1367 .await
1368 .map_err(Into::into)
1369 }
1370
1371 async fn get_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1372 self.0.get_custom_value(key).await.map_err(Into::into)
1373 }
1374
1375 async fn set_custom_value(
1376 &self,
1377 key: &[u8],
1378 value: Vec<u8>,
1379 ) -> Result<Option<Vec<u8>>, Self::Error> {
1380 self.0.set_custom_value(key, value).await.map_err(Into::into)
1381 }
1382
1383 async fn remove_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1384 self.0.remove_custom_value(key).await.map_err(Into::into)
1385 }
1386
1387 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error> {
1388 self.0.remove_room(room_id).await.map_err(Into::into)
1389 }
1390
1391 async fn save_send_queue_request(
1392 &self,
1393 room_id: &RoomId,
1394 transaction_id: OwnedTransactionId,
1395 created_at: MilliSecondsSinceUnixEpoch,
1396 content: QueuedRequestKind,
1397 priority: usize,
1398 ) -> Result<(), Self::Error> {
1399 self.0
1400 .save_send_queue_request(room_id, transaction_id, created_at, content, priority)
1401 .await
1402 .map_err(Into::into)
1403 }
1404
1405 async fn update_send_queue_request(
1406 &self,
1407 room_id: &RoomId,
1408 transaction_id: &TransactionId,
1409 content: QueuedRequestKind,
1410 ) -> Result<bool, Self::Error> {
1411 self.0.update_send_queue_request(room_id, transaction_id, content).await.map_err(Into::into)
1412 }
1413
1414 async fn remove_send_queue_request(
1415 &self,
1416 room_id: &RoomId,
1417 transaction_id: &TransactionId,
1418 ) -> Result<bool, Self::Error> {
1419 self.0.remove_send_queue_request(room_id, transaction_id).await.map_err(Into::into)
1420 }
1421
1422 async fn load_send_queue_requests(
1423 &self,
1424 room_id: &RoomId,
1425 ) -> Result<Vec<QueuedRequest>, Self::Error> {
1426 self.0.load_send_queue_requests(room_id).await.map_err(Into::into)
1427 }
1428
1429 async fn update_send_queue_request_status(
1430 &self,
1431 room_id: &RoomId,
1432 transaction_id: &TransactionId,
1433 error: Option<QueueWedgeError>,
1434 ) -> Result<(), Self::Error> {
1435 self.0
1436 .update_send_queue_request_status(room_id, transaction_id, error)
1437 .await
1438 .map_err(Into::into)
1439 }
1440
1441 async fn load_rooms_with_unsent_requests(&self) -> Result<Vec<OwnedRoomId>, Self::Error> {
1442 self.0.load_rooms_with_unsent_requests().await.map_err(Into::into)
1443 }
1444
1445 async fn save_dependent_queued_request(
1446 &self,
1447 room_id: &RoomId,
1448 parent_txn_id: &TransactionId,
1449 own_txn_id: ChildTransactionId,
1450 created_at: MilliSecondsSinceUnixEpoch,
1451 content: DependentQueuedRequestKind,
1452 ) -> Result<(), Self::Error> {
1453 self.0
1454 .save_dependent_queued_request(room_id, parent_txn_id, own_txn_id, created_at, content)
1455 .await
1456 .map_err(Into::into)
1457 }
1458
1459 async fn mark_dependent_queued_requests_as_ready(
1460 &self,
1461 room_id: &RoomId,
1462 parent_txn_id: &TransactionId,
1463 sent_parent_key: SentRequestKey,
1464 ) -> Result<usize, Self::Error> {
1465 self.0
1466 .mark_dependent_queued_requests_as_ready(room_id, parent_txn_id, sent_parent_key)
1467 .await
1468 .map_err(Into::into)
1469 }
1470
1471 async fn remove_dependent_queued_request(
1472 &self,
1473 room_id: &RoomId,
1474 own_txn_id: &ChildTransactionId,
1475 ) -> Result<bool, Self::Error> {
1476 self.0.remove_dependent_queued_request(room_id, own_txn_id).await.map_err(Into::into)
1477 }
1478
1479 async fn load_dependent_queued_requests(
1480 &self,
1481 room_id: &RoomId,
1482 ) -> Result<Vec<DependentQueuedRequest>, Self::Error> {
1483 self.0.load_dependent_queued_requests(room_id).await.map_err(Into::into)
1484 }
1485
1486 async fn update_dependent_queued_request(
1487 &self,
1488 room_id: &RoomId,
1489 own_transaction_id: &ChildTransactionId,
1490 new_content: DependentQueuedRequestKind,
1491 ) -> Result<bool, Self::Error> {
1492 self.0
1493 .update_dependent_queued_request(room_id, own_transaction_id, new_content)
1494 .await
1495 .map_err(Into::into)
1496 }
1497
1498 async fn upsert_thread_subscriptions(
1499 &self,
1500 updates: Vec<(&RoomId, &EventId, StoredThreadSubscription)>,
1501 ) -> Result<(), Self::Error> {
1502 self.0.upsert_thread_subscriptions(updates).await.map_err(Into::into)
1503 }
1504
1505 async fn load_thread_subscription(
1506 &self,
1507 room: &RoomId,
1508 thread_id: &EventId,
1509 ) -> Result<Option<StoredThreadSubscription>, Self::Error> {
1510 self.0.load_thread_subscription(room, thread_id).await.map_err(Into::into)
1511 }
1512
1513 async fn remove_thread_subscription(
1514 &self,
1515 room: &RoomId,
1516 thread_id: &EventId,
1517 ) -> Result<(), Self::Error> {
1518 self.0.remove_thread_subscription(room, thread_id).await.map_err(Into::into)
1519 }
1520
1521 async fn get_global_profile(
1522 &self,
1523 user_id: &UserId,
1524 ) -> Result<Option<UserProfile>, Self::Error> {
1525 self.0.get_global_profile(user_id).await.map_err(Into::into)
1526 }
1527
1528 async fn get_global_profiles<'a>(
1529 &self,
1530 user_ids: &'a [OwnedUserId],
1531 ) -> Result<BTreeMap<&'a UserId, UserProfile>, Self::Error> {
1532 self.0.get_global_profiles(user_ids).await.map_err(Into::into)
1533 }
1534
1535 async fn close(&self) -> Result<(), Self::Error> {
1536 self.0.close().await.map_err(Into::into)
1537 }
1538
1539 async fn reopen(&self) -> Result<(), Self::Error> {
1540 self.0.reopen().await.map_err(Into::into)
1541 }
1542
1543 async fn optimize(&self) -> Result<(), Self::Error> {
1544 self.0.optimize().await.map_err(Into::into)
1545 }
1546
1547 async fn get_size(&self) -> Result<Option<usize>, Self::Error> {
1548 self.0.get_size().await.map_err(Into::into)
1549 }
1550}
1551
1552#[derive(Debug, Clone)]
1555pub struct SaveLockedStateStore<T = Arc<DynStateStore>> {
1556 store: T,
1557 lock: Arc<Mutex<()>>,
1558}
1559
1560#[derive(Debug, Error)]
1564#[error("a mutex guard was provided, but it does not reference the correct mutex")]
1565pub struct IncorrectMutexGuardError;
1566
1567impl From<IncorrectMutexGuardError> for StoreError {
1568 fn from(value: IncorrectMutexGuardError) -> Self {
1569 Self::backend(value)
1570 }
1571}
1572
1573impl<T> SaveLockedStateStore<T> {
1574 pub fn new(store: T) -> Self {
1576 Self { store, lock: Arc::new(Mutex::new(())) }
1577 }
1578
1579 pub fn lock(&self) -> &Mutex<()> {
1582 self.lock.as_ref()
1583 }
1584}
1585
1586impl<T: StateStore> SaveLockedStateStore<T> {
1587 pub async fn save_changes_with_guard(
1591 &self,
1592 guard: &MutexGuard<'_, ()>,
1593 changes: &StateChanges,
1594 ) -> Result<(), StoreError> {
1595 if !std::ptr::eq(MutexGuard::mutex(guard), self.lock()) {
1596 Err(IncorrectMutexGuardError.into())
1597 } else {
1598 self.store.save_changes(changes).await.map_err(Into::into)
1599 }
1600 }
1601
1602 pub async fn remove_room_with_guard(
1606 &self,
1607 guard: &MutexGuard<'_, ()>,
1608 room_id: &RoomId,
1609 ) -> Result<(), StoreError> {
1610 if !std::ptr::eq(MutexGuard::mutex(guard), self.lock()) {
1611 Err(IncorrectMutexGuardError.into())
1612 } else {
1613 self.store.remove_room(room_id).await.map_err(Into::into)
1614 }
1615 }
1616}
1617
1618#[cfg_attr(target_family = "wasm", async_trait(?Send))]
1619#[cfg_attr(not(target_family = "wasm"), async_trait)]
1620impl<T: StateStore> StateStore for SaveLockedStateStore<T> {
1621 type Error = T::Error;
1622
1623 async fn get_kv_data(
1624 &self,
1625 key: StateStoreDataKey<'_>,
1626 ) -> Result<Option<StateStoreDataValue>, Self::Error> {
1627 self.store.get_kv_data(key).await
1628 }
1629
1630 async fn set_kv_data(
1631 &self,
1632 key: StateStoreDataKey<'_>,
1633 value: StateStoreDataValue,
1634 ) -> Result<(), Self::Error> {
1635 self.store.set_kv_data(key, value).await
1636 }
1637
1638 async fn remove_kv_data(&self, key: StateStoreDataKey<'_>) -> Result<(), Self::Error> {
1639 self.store.remove_kv_data(key).await
1640 }
1641
1642 async fn save_changes(&self, changes: &StateChanges) -> Result<(), Self::Error> {
1643 let _guard = self.lock.lock().await;
1644 self.store.save_changes(changes).await
1645 }
1646
1647 async fn get_presence_event(
1648 &self,
1649 user_id: &UserId,
1650 ) -> Result<Option<Raw<PresenceEvent>>, Self::Error> {
1651 self.store.get_presence_event(user_id).await
1652 }
1653
1654 async fn get_presence_events(
1655 &self,
1656 user_ids: &[OwnedUserId],
1657 ) -> Result<Vec<Raw<PresenceEvent>>, Self::Error> {
1658 self.store.get_presence_events(user_ids).await
1659 }
1660
1661 async fn get_state_event(
1662 &self,
1663 room_id: &RoomId,
1664 event_type: StateEventType,
1665 state_key: &str,
1666 ) -> Result<Option<RawAnySyncOrStrippedState>, Self::Error> {
1667 self.store.get_state_event(room_id, event_type, state_key).await
1668 }
1669
1670 async fn get_state_events(
1671 &self,
1672 room_id: &RoomId,
1673 event_type: StateEventType,
1674 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
1675 self.store.get_state_events(room_id, event_type).await
1676 }
1677
1678 async fn get_state_events_for_keys(
1679 &self,
1680 room_id: &RoomId,
1681 event_type: StateEventType,
1682 state_keys: &[&str],
1683 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
1684 self.store.get_state_events_for_keys(room_id, event_type, state_keys).await
1685 }
1686
1687 async fn get_profile(
1688 &self,
1689 room_id: &RoomId,
1690 user_id: &UserId,
1691 ) -> Result<Option<MinimalRoomMemberEvent>, Self::Error> {
1692 self.store.get_profile(room_id, user_id).await
1693 }
1694
1695 async fn get_profiles<'a>(
1696 &self,
1697 room_id: &RoomId,
1698 user_ids: &'a [OwnedUserId],
1699 ) -> Result<BTreeMap<&'a UserId, MinimalRoomMemberEvent>, Self::Error> {
1700 self.store.get_profiles(room_id, user_ids).await
1701 }
1702
1703 async fn get_user_ids(
1704 &self,
1705 room_id: &RoomId,
1706 memberships: RoomMemberships,
1707 ) -> Result<Vec<OwnedUserId>, Self::Error> {
1708 self.store.get_user_ids(room_id, memberships).await
1709 }
1710
1711 async fn get_room_infos(
1712 &self,
1713 room_load_settings: &RoomLoadSettings,
1714 ) -> Result<Vec<RoomInfo>, Self::Error> {
1715 self.store.get_room_infos(room_load_settings).await
1716 }
1717
1718 async fn get_users_with_display_name(
1719 &self,
1720 room_id: &RoomId,
1721 display_name: &DisplayName,
1722 ) -> Result<BTreeSet<OwnedUserId>, Self::Error> {
1723 self.store.get_users_with_display_name(room_id, display_name).await
1724 }
1725
1726 async fn get_users_with_display_names<'a>(
1727 &self,
1728 room_id: &RoomId,
1729 display_names: &'a [DisplayName],
1730 ) -> Result<HashMap<&'a DisplayName, BTreeSet<OwnedUserId>>, Self::Error> {
1731 self.store.get_users_with_display_names(room_id, display_names).await
1732 }
1733
1734 async fn get_account_data_event(
1735 &self,
1736 event_type: GlobalAccountDataEventType,
1737 ) -> Result<Option<Raw<AnyGlobalAccountDataEvent>>, Self::Error> {
1738 self.store.get_account_data_event(event_type).await
1739 }
1740
1741 async fn get_room_account_data_event(
1742 &self,
1743 room_id: &RoomId,
1744 event_type: RoomAccountDataEventType,
1745 ) -> Result<Option<Raw<AnyRoomAccountDataEvent>>, Self::Error> {
1746 self.store.get_room_account_data_event(room_id, event_type).await
1747 }
1748
1749 async fn get_user_room_receipt_event(
1750 &self,
1751 room_id: &RoomId,
1752 receipt_type: ReceiptType,
1753 receipt_thread: &ReceiptThread,
1754 user_id: &UserId,
1755 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error> {
1756 self.store.get_user_room_receipt_event(room_id, receipt_type, receipt_thread, user_id).await
1757 }
1758
1759 async fn get_event_room_receipt_events(
1760 &self,
1761 room_id: &RoomId,
1762 receipt_type: ReceiptType,
1763 receipt_thread: &ReceiptThread,
1764 event_id: &EventId,
1765 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error> {
1766 self.store
1767 .get_event_room_receipt_events(room_id, receipt_type, receipt_thread, event_id)
1768 .await
1769 }
1770
1771 async fn get_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1772 self.store.get_custom_value(key).await
1773 }
1774
1775 async fn set_custom_value(
1776 &self,
1777 key: &[u8],
1778 value: Vec<u8>,
1779 ) -> Result<Option<Vec<u8>>, Self::Error> {
1780 self.store.set_custom_value(key, value).await
1781 }
1782
1783 async fn remove_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
1784 self.store.remove_custom_value(key).await
1785 }
1786
1787 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error> {
1788 let _guard = self.lock.lock().await;
1789 self.store.remove_room(room_id).await
1790 }
1791
1792 async fn save_send_queue_request(
1793 &self,
1794 room_id: &RoomId,
1795 transaction_id: OwnedTransactionId,
1796 created_at: MilliSecondsSinceUnixEpoch,
1797 request: QueuedRequestKind,
1798 priority: usize,
1799 ) -> Result<(), Self::Error> {
1800 self.store
1801 .save_send_queue_request(room_id, transaction_id, created_at, request, priority)
1802 .await
1803 }
1804
1805 async fn update_send_queue_request(
1806 &self,
1807 room_id: &RoomId,
1808 transaction_id: &TransactionId,
1809 content: QueuedRequestKind,
1810 ) -> Result<bool, Self::Error> {
1811 self.store.update_send_queue_request(room_id, transaction_id, content).await
1812 }
1813
1814 async fn remove_send_queue_request(
1815 &self,
1816 room_id: &RoomId,
1817 transaction_id: &TransactionId,
1818 ) -> Result<bool, Self::Error> {
1819 self.store.remove_send_queue_request(room_id, transaction_id).await
1820 }
1821
1822 async fn load_send_queue_requests(
1823 &self,
1824 room_id: &RoomId,
1825 ) -> Result<Vec<QueuedRequest>, Self::Error> {
1826 self.store.load_send_queue_requests(room_id).await
1827 }
1828
1829 async fn update_send_queue_request_status(
1830 &self,
1831 room_id: &RoomId,
1832 transaction_id: &TransactionId,
1833 error: Option<QueueWedgeError>,
1834 ) -> Result<(), Self::Error> {
1835 self.store.update_send_queue_request_status(room_id, transaction_id, error).await
1836 }
1837
1838 async fn load_rooms_with_unsent_requests(&self) -> Result<Vec<OwnedRoomId>, Self::Error> {
1839 self.store.load_rooms_with_unsent_requests().await
1840 }
1841
1842 async fn save_dependent_queued_request(
1843 &self,
1844 room_id: &RoomId,
1845 parent_txn_id: &TransactionId,
1846 own_txn_id: ChildTransactionId,
1847 created_at: MilliSecondsSinceUnixEpoch,
1848 content: DependentQueuedRequestKind,
1849 ) -> Result<(), Self::Error> {
1850 self.store
1851 .save_dependent_queued_request(room_id, parent_txn_id, own_txn_id, created_at, content)
1852 .await
1853 }
1854
1855 async fn mark_dependent_queued_requests_as_ready(
1856 &self,
1857 room_id: &RoomId,
1858 parent_txn_id: &TransactionId,
1859 sent_parent_key: SentRequestKey,
1860 ) -> Result<usize, Self::Error> {
1861 self.store
1862 .mark_dependent_queued_requests_as_ready(room_id, parent_txn_id, sent_parent_key)
1863 .await
1864 }
1865
1866 async fn update_dependent_queued_request(
1867 &self,
1868 room_id: &RoomId,
1869 own_transaction_id: &ChildTransactionId,
1870 new_content: DependentQueuedRequestKind,
1871 ) -> Result<bool, Self::Error> {
1872 self.store.update_dependent_queued_request(room_id, own_transaction_id, new_content).await
1873 }
1874
1875 async fn remove_dependent_queued_request(
1876 &self,
1877 room: &RoomId,
1878 own_txn_id: &ChildTransactionId,
1879 ) -> Result<bool, Self::Error> {
1880 self.store.remove_dependent_queued_request(room, own_txn_id).await
1881 }
1882
1883 async fn load_dependent_queued_requests(
1884 &self,
1885 room: &RoomId,
1886 ) -> Result<Vec<DependentQueuedRequest>, Self::Error> {
1887 self.store.load_dependent_queued_requests(room).await
1888 }
1889
1890 async fn upsert_thread_subscriptions(
1891 &self,
1892 updates: Vec<(&RoomId, &EventId, StoredThreadSubscription)>,
1893 ) -> Result<(), Self::Error> {
1894 self.store.upsert_thread_subscriptions(updates).await
1895 }
1896
1897 async fn load_thread_subscription(
1898 &self,
1899 room: &RoomId,
1900 thread_id: &EventId,
1901 ) -> Result<Option<StoredThreadSubscription>, Self::Error> {
1902 self.store.load_thread_subscription(room, thread_id).await
1903 }
1904
1905 async fn remove_thread_subscription(
1906 &self,
1907 room: &RoomId,
1908 thread_id: &EventId,
1909 ) -> Result<(), Self::Error> {
1910 self.store.remove_thread_subscription(room, thread_id).await
1911 }
1912
1913 async fn get_global_profile(
1914 &self,
1915 user_id: &UserId,
1916 ) -> Result<Option<UserProfile>, Self::Error> {
1917 self.store.get_global_profile(user_id).await
1918 }
1919
1920 async fn get_global_profiles<'a>(
1921 &self,
1922 user_ids: &'a [OwnedUserId],
1923 ) -> Result<BTreeMap<&'a UserId, UserProfile>, Self::Error> {
1924 self.store.get_global_profiles(user_ids).await
1925 }
1926
1927 async fn close(&self) -> Result<(), Self::Error> {
1928 self.store.close().await
1929 }
1930
1931 async fn reopen(&self) -> Result<(), Self::Error> {
1932 self.store.reopen().await
1933 }
1934
1935 async fn optimize(&self) -> Result<(), Self::Error> {
1936 self.store.optimize().await
1937 }
1938
1939 async fn get_size(&self) -> Result<Option<usize>, Self::Error> {
1940 self.store.get_size().await
1941 }
1942}
1943
1944#[cfg_attr(target_family = "wasm", async_trait(?Send))]
1946#[cfg_attr(not(target_family = "wasm"), async_trait)]
1947pub trait StateStoreExt: StateStore {
1948 async fn get_state_event_static<C>(
1954 &self,
1955 room_id: &RoomId,
1956 ) -> Result<Option<RawSyncOrStrippedState<C>>, Self::Error>
1957 where
1958 C: StaticEventContent<IsPrefix = ruma::events::False>
1959 + StaticStateEventContent<StateKey = EmptyStateKey>
1960 + RedactContent,
1961 C::Redacted: RedactedStateEventContent,
1962 {
1963 Ok(self.get_state_event(room_id, C::TYPE.into(), "").await?.map(|raw| raw.cast()))
1964 }
1965
1966 async fn get_state_event_static_for_key<C, K>(
1972 &self,
1973 room_id: &RoomId,
1974 state_key: &K,
1975 ) -> Result<Option<RawSyncOrStrippedState<C>>, Self::Error>
1976 where
1977 C: StaticEventContent<IsPrefix = ruma::events::False>
1978 + StaticStateEventContent
1979 + RedactContent,
1980 C::StateKey: Borrow<K>,
1981 C::Redacted: RedactedStateEventContent,
1982 K: AsRef<str> + ?Sized + Sync,
1983 {
1984 Ok(self
1985 .get_state_event(room_id, C::TYPE.into(), state_key.as_ref())
1986 .await?
1987 .map(|raw| raw.cast()))
1988 }
1989
1990 async fn get_state_events_static<C>(
1996 &self,
1997 room_id: &RoomId,
1998 ) -> Result<Vec<RawSyncOrStrippedState<C>>, Self::Error>
1999 where
2000 C: StaticEventContent<IsPrefix = ruma::events::False>
2001 + StaticStateEventContent
2002 + RedactContent,
2003 C::Redacted: RedactedStateEventContent,
2004 {
2005 Ok(self
2008 .get_state_events(room_id, C::TYPE.into())
2009 .await?
2010 .into_iter()
2011 .map(|raw| raw.cast())
2012 .collect())
2013 }
2014
2015 async fn get_state_events_for_keys_static<'a, C, K, I>(
2023 &self,
2024 room_id: &RoomId,
2025 state_keys: I,
2026 ) -> Result<Vec<RawSyncOrStrippedState<C>>, Self::Error>
2027 where
2028 C: StaticEventContent<IsPrefix = ruma::events::False>
2029 + StaticStateEventContent
2030 + RedactContent,
2031 C::StateKey: Borrow<K>,
2032 C::Redacted: RedactedStateEventContent,
2033 K: AsRef<str> + Sized + Sync + 'a,
2034 I: IntoIterator<Item = &'a K> + Send,
2035 I::IntoIter: Send,
2036 {
2037 Ok(self
2038 .get_state_events_for_keys(
2039 room_id,
2040 C::TYPE.into(),
2041 &state_keys.into_iter().map(|k| k.as_ref()).collect::<Vec<_>>(),
2042 )
2043 .await?
2044 .into_iter()
2045 .map(|raw| raw.cast())
2046 .collect())
2047 }
2048
2049 async fn get_account_data_event_static<C>(
2051 &self,
2052 ) -> Result<Option<Raw<GlobalAccountDataEvent<C>>>, Self::Error>
2053 where
2054 C: StaticEventContent<IsPrefix = ruma::events::False> + GlobalAccountDataEventContent,
2055 {
2056 Ok(self.get_account_data_event(C::TYPE.into()).await?.map(Raw::cast_unchecked))
2057 }
2058
2059 async fn get_room_account_data_event_static<C>(
2067 &self,
2068 room_id: &RoomId,
2069 ) -> Result<Option<Raw<RoomAccountDataEvent<C>>>, Self::Error>
2070 where
2071 C: StaticEventContent<IsPrefix = ruma::events::False> + RoomAccountDataEventContent,
2072 {
2073 Ok(self
2074 .get_room_account_data_event(room_id, C::TYPE.into())
2075 .await?
2076 .map(Raw::cast_unchecked))
2077 }
2078
2079 async fn get_member_event(
2087 &self,
2088 room_id: &RoomId,
2089 state_key: &UserId,
2090 ) -> Result<Option<RawMemberEvent>, Self::Error> {
2091 self.get_state_event_static_for_key(room_id, state_key).await
2092 }
2093}
2094
2095#[cfg_attr(target_family = "wasm", async_trait(?Send))]
2096#[cfg_attr(not(target_family = "wasm"), async_trait)]
2097impl<T: StateStore + ?Sized> StateStoreExt for T {}
2098
2099pub type DynStateStore = dyn StateStore<Error = StoreError>;
2101
2102pub trait IntoStateStore {
2108 #[doc(hidden)]
2109 fn into_state_store(self) -> Arc<DynStateStore>;
2110}
2111
2112impl<T> IntoStateStore for T
2113where
2114 T: StateStore + Sized + 'static,
2115{
2116 fn into_state_store(self) -> Arc<DynStateStore> {
2117 Arc::new(EraseStateStoreError(self))
2118 }
2119}
2120
2121#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
2123pub struct SupportedVersionsResponse {
2124 pub versions: Vec<String>,
2126
2127 pub unstable_features: BTreeMap<String, bool>,
2129}
2130
2131impl SupportedVersionsResponse {
2132 pub fn supported_versions(&self) -> SupportedVersions {
2138 let mut supported_versions =
2139 SupportedVersions::from_parts(&self.versions, &self.unstable_features);
2140
2141 if supported_versions.versions.is_empty() {
2144 supported_versions.versions.insert(MatrixVersion::V1_0);
2145 }
2146
2147 supported_versions
2148 }
2149}
2150
2151#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
2152pub struct WellKnownResponse {
2154 pub homeserver: HomeserverInfo,
2156
2157 pub identity_server: Option<IdentityServerInfo>,
2159
2160 pub tile_server: Option<TileServerInfo>,
2162
2163 pub rtc_foci: Vec<RtcTransport>,
2165}
2166
2167impl From<discover_homeserver::Response> for WellKnownResponse {
2168 fn from(response: discover_homeserver::Response) -> Self {
2169 Self {
2170 homeserver: response.homeserver,
2171 identity_server: response.identity_server,
2172 tile_server: response.tile_server,
2173 rtc_foci: response.rtc_foci,
2174 }
2175 }
2176}
2177
2178#[derive(Debug, Clone)]
2180pub enum StateStoreDataValue {
2181 SyncToken(String),
2183
2184 SupportedVersions(TtlValue<SupportedVersionsResponse>),
2186
2187 WellKnown(TtlValue<Option<WellKnownResponse>>),
2189
2190 Filter(String),
2192
2193 UserAvatarUrl(OwnedMxcUri),
2195
2196 RecentlyVisitedRooms(Vec<OwnedRoomId>),
2198
2199 UtdHookManagerData(GrowableBloom),
2202
2203 OneTimeKeyAlreadyUploaded,
2206
2207 ComposerDraft(ComposerDraft),
2211
2212 SeenKnockRequests(BTreeMap<OwnedEventId, OwnedUserId>),
2214
2215 ThreadSubscriptionsCatchupTokens(Vec<ThreadSubscriptionCatchupToken>),
2220
2221 HomeserverCapabilities(TtlValue<Capabilities>),
2223}
2224
2225#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2235pub struct ThreadSubscriptionCatchupToken {
2236 pub from: String,
2242
2243 pub to: Option<String>,
2249}
2250
2251#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2253pub struct ComposerDraft {
2254 pub plain_text: String,
2256 pub html_text: Option<String>,
2259 pub draft_type: ComposerDraftType,
2261 #[serde(default)]
2263 pub attachments: Vec<DraftAttachment>,
2264}
2265
2266#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2268pub struct DraftAttachment {
2269 pub filename: String,
2271 pub content: DraftAttachmentContent,
2273}
2274
2275#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2277#[serde(tag = "type")]
2278pub enum DraftAttachmentContent {
2279 Image {
2281 #[serde(with = "serde_bytes")]
2283 data: Vec<u8>,
2284 mimetype: Option<String>,
2286 size: Option<u64>,
2288 width: Option<u64>,
2290 height: Option<u64>,
2292 blurhash: Option<String>,
2294 thumbnail: Option<DraftThumbnail>,
2296 },
2297 Video {
2299 #[serde(with = "serde_bytes")]
2301 data: Vec<u8>,
2302 mimetype: Option<String>,
2304 size: Option<u64>,
2306 width: Option<u64>,
2308 height: Option<u64>,
2310 duration: Option<std::time::Duration>,
2312 blurhash: Option<String>,
2314 thumbnail: Option<DraftThumbnail>,
2316 },
2317 Audio {
2319 #[serde(with = "serde_bytes")]
2321 data: Vec<u8>,
2322 mimetype: Option<String>,
2324 size: Option<u64>,
2326 duration: Option<std::time::Duration>,
2328 },
2329 File {
2331 #[serde(with = "serde_bytes")]
2333 data: Vec<u8>,
2334 mimetype: Option<String>,
2336 size: Option<u64>,
2338 },
2339}
2340
2341#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2343pub struct DraftThumbnail {
2344 pub filename: String,
2346 #[serde(with = "serde_bytes")]
2348 pub data: Vec<u8>,
2349 pub mimetype: Option<String>,
2351 pub width: Option<u64>,
2353 pub height: Option<u64>,
2355 pub size: Option<u64>,
2357}
2358
2359#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2361pub enum ComposerDraftType {
2362 NewMessage,
2364 Reply {
2366 event_id: OwnedEventId,
2368 },
2369 Edit {
2371 event_id: OwnedEventId,
2373 },
2374}
2375
2376impl StateStoreDataValue {
2377 pub fn into_sync_token(self) -> Option<String> {
2379 as_variant!(self, Self::SyncToken)
2380 }
2381
2382 pub fn into_filter(self) -> Option<String> {
2384 as_variant!(self, Self::Filter)
2385 }
2386
2387 pub fn into_user_avatar_url(self) -> Option<OwnedMxcUri> {
2389 as_variant!(self, Self::UserAvatarUrl)
2390 }
2391
2392 pub fn into_recently_visited_rooms(self) -> Option<Vec<OwnedRoomId>> {
2394 as_variant!(self, Self::RecentlyVisitedRooms)
2395 }
2396
2397 pub fn into_utd_hook_manager_data(self) -> Option<GrowableBloom> {
2399 as_variant!(self, Self::UtdHookManagerData)
2400 }
2401
2402 pub fn into_composer_draft(self) -> Option<ComposerDraft> {
2404 as_variant!(self, Self::ComposerDraft)
2405 }
2406
2407 pub fn into_supported_versions(self) -> Option<TtlValue<SupportedVersionsResponse>> {
2409 as_variant!(self, Self::SupportedVersions)
2410 }
2411
2412 pub fn into_well_known(self) -> Option<TtlValue<Option<WellKnownResponse>>> {
2414 as_variant!(self, Self::WellKnown)
2415 }
2416
2417 pub fn into_seen_knock_requests(self) -> Option<BTreeMap<OwnedEventId, OwnedUserId>> {
2419 as_variant!(self, Self::SeenKnockRequests)
2420 }
2421
2422 pub fn into_thread_subscriptions_catchup_tokens(
2425 self,
2426 ) -> Option<Vec<ThreadSubscriptionCatchupToken>> {
2427 as_variant!(self, Self::ThreadSubscriptionsCatchupTokens)
2428 }
2429
2430 pub fn into_homeserver_capabilities(self) -> Option<TtlValue<Capabilities>> {
2433 as_variant!(self, Self::HomeserverCapabilities)
2434 }
2435}
2436
2437#[derive(Debug, Clone, Copy)]
2439pub enum StateStoreDataKey<'a> {
2440 SyncToken,
2442
2443 SupportedVersions,
2445
2446 WellKnown,
2448
2449 Filter(&'a str),
2451
2452 UserAvatarUrl(&'a UserId),
2454
2455 RecentlyVisitedRooms(&'a UserId),
2457
2458 UtdHookManagerData,
2461
2462 OneTimeKeyAlreadyUploaded,
2465
2466 ComposerDraft(&'a RoomId, Option<&'a EventId>),
2470
2471 SeenKnockRequests(&'a RoomId),
2473
2474 ThreadSubscriptionsCatchupTokens,
2476
2477 HomeserverCapabilities,
2479}
2480
2481impl StateStoreDataKey<'_> {
2482 pub const SYNC_TOKEN: &'static str = "sync_token";
2484
2485 pub const SUPPORTED_VERSIONS: &'static str = "server_capabilities";
2489
2490 pub const WELL_KNOWN: &'static str = "well_known";
2492
2493 pub const FILTER: &'static str = "filter";
2495
2496 pub const USER_AVATAR_URL: &'static str = "user_avatar_url";
2499
2500 pub const RECENTLY_VISITED_ROOMS: &'static str = "recently_visited_rooms";
2503
2504 pub const UTD_HOOK_MANAGER_DATA: &'static str = "utd_hook_manager_data";
2507
2508 pub const ONE_TIME_KEY_ALREADY_UPLOADED: &'static str = "one_time_key_already_uploaded";
2511
2512 pub const COMPOSER_DRAFT: &'static str = "composer_draft";
2515
2516 pub const SEEN_KNOCK_REQUESTS: &'static str = "seen_knock_requests";
2519
2520 pub const THREAD_SUBSCRIPTIONS_CATCHUP_TOKENS: &'static str =
2524 "thread_subscriptions_catchup_tokens";
2525
2526 pub const HOMESERVER_CAPABILITIES: &'static str = "homeserver_capabilities";
2528}
2529
2530pub fn compare_thread_subscription_bump_stamps(
2539 previous: Option<u64>,
2540 new: &mut Option<u64>,
2541) -> bool {
2542 match (previous, &new) {
2543 (Some(prev_bump), None) => {
2547 *new = Some(prev_bump);
2548 }
2549
2550 (Some(prev_bump), Some(new_bump)) if *new_bump <= prev_bump => {
2552 return false;
2553 }
2554
2555 _ => {}
2557 }
2558
2559 true
2560}
2561
2562#[cfg(test)]
2563mod tests {
2564 mod save_locked_state_store {
2565 use std::time::Duration;
2566
2567 use assert_matches::assert_matches;
2568 use futures_util::future::{self, Either};
2569 #[cfg(all(target_family = "wasm", target_os = "unknown"))]
2570 use gloo_timers::future::sleep;
2571 use matrix_sdk_common::executor::spawn;
2572 use matrix_sdk_test::async_test;
2573 use ruma::room_id;
2574 use tokio::sync::Mutex;
2575 #[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
2576 use tokio::time::sleep;
2577
2578 use crate::{
2579 StateChanges, StateStore,
2580 store::{IntoStateStore, MemoryStore, Result, SaveLockedStateStore},
2581 };
2582
2583 async fn get_store() -> Result<impl StateStore> {
2584 Ok(SaveLockedStateStore::new(MemoryStore::new()))
2585 }
2586
2587 statestore_integration_tests!();
2588
2589 #[async_test]
2590 async fn test_save_changes_only_accepts_guard_for_underlying_mutex() {
2591 let state_store = SaveLockedStateStore::new(MemoryStore::new());
2592 let state_changes = StateChanges::default();
2593 state_store
2594 .save_changes_with_guard(&state_store.lock().lock().await, &state_changes)
2595 .await
2596 .expect("state store accepts guard for underlying mutex");
2597
2598 let mutex = Mutex::new(());
2599 state_store
2600 .save_changes_with_guard(&mutex.lock().await, &state_changes)
2601 .await
2602 .expect_err("state store does not accept guard for unknown mutex");
2603 }
2604
2605 #[async_test]
2606 async fn test_remove_room_only_accepts_guard_for_underlying_mutex() {
2607 let state_store = SaveLockedStateStore::new(MemoryStore::new());
2608 let room_id = room_id!("!room");
2609 state_store
2610 .remove_room_with_guard(&state_store.lock().lock().await, room_id)
2611 .await
2612 .expect("state store accepts guard for underlying mutex");
2613
2614 let mutex = Mutex::new(());
2615 state_store
2616 .remove_room_with_guard(&mutex.lock().await, room_id)
2617 .await
2618 .expect_err("state store does not accept guard for unknown mutex");
2619 }
2620
2621 #[derive(Debug)]
2622 struct Elapsed;
2623
2624 async fn timeout<F: Future + Unpin>(
2625 duration: Duration,
2626 f: F,
2627 ) -> Result<F::Output, Elapsed> {
2628 #[cfg(all(target_family = "wasm", target_os = "unknown"))]
2629 {
2630 match future::select(sleep(duration), f).await {
2631 Either::Left(_) => return Err(Elapsed),
2632 Either::Right((output, _)) => Ok(output),
2633 }
2634 }
2635 #[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
2636 {
2637 tokio::time::timeout(duration, f).await.map_err(|_| Elapsed)
2638 }
2639 }
2640
2641 #[async_test]
2642 async fn test_state_store_waits_to_acquire_lock_before_saving_changes() {
2643 let state_store = SaveLockedStateStore::new(MemoryStore::new().into_state_store());
2644
2645 let lock_task = spawn({
2647 let state_store = state_store.clone();
2648 async move {
2649 let lock = state_store.lock();
2650 let _guard = lock.lock().await;
2651 sleep(Duration::from_secs(5)).await;
2652 }
2653 });
2654
2655 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}