1use std::{
16 borrow::Borrow,
17 collections::{BTreeMap, BTreeSet, HashMap},
18 fmt,
19 sync::Arc,
20};
21
22use as_variant::as_variant;
23use async_trait::async_trait;
24use growable_bloom_filter::GrowableBloom;
25use matrix_sdk_common::{AsyncTraitDeps, ttl::TtlValue};
26use ruma::{
27 EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedMxcUri, OwnedRoomId,
28 OwnedTransactionId, OwnedUserId, RoomId, TransactionId, UserId,
29 api::{
30 MatrixVersion, SupportedVersions,
31 client::discovery::{
32 discover_homeserver::{
33 self, HomeserverInfo, IdentityServerInfo, RtcFocusInfo, TileServerInfo,
34 },
35 get_capabilities::v3::Capabilities,
36 },
37 },
38 events::{
39 AnyGlobalAccountDataEvent, AnyRoomAccountDataEvent, EmptyStateKey, GlobalAccountDataEvent,
40 GlobalAccountDataEventContent, GlobalAccountDataEventType, RedactContent,
41 RedactedStateEventContent, RoomAccountDataEvent, RoomAccountDataEventContent,
42 RoomAccountDataEventType, StateEventType, StaticEventContent, StaticStateEventContent,
43 presence::PresenceEvent,
44 receipt::{Receipt, ReceiptThread, ReceiptType},
45 },
46 serde::Raw,
47};
48use serde::{Deserialize, Serialize};
49
50use super::{
51 ChildTransactionId, DependentQueuedRequest, DependentQueuedRequestKind, QueueWedgeError,
52 QueuedRequest, QueuedRequestKind, RoomLoadSettings, StateChanges, StoreError,
53 send_queue::SentRequestKey,
54};
55use crate::{
56 MinimalRoomMemberEvent, RoomInfo, RoomMemberships,
57 deserialized_responses::{
58 DisplayName, RawAnySyncOrStrippedState, RawMemberEvent, RawSyncOrStrippedState,
59 },
60 store::StoredThreadSubscription,
61};
62
63#[cfg_attr(target_family = "wasm", async_trait(?Send))]
66#[cfg_attr(not(target_family = "wasm"), async_trait)]
67pub trait StateStore: AsyncTraitDeps {
68 type Error: fmt::Debug + Into<StoreError> + From<serde_json::Error>;
70
71 async fn get_kv_data(
77 &self,
78 key: StateStoreDataKey<'_>,
79 ) -> Result<Option<StateStoreDataValue>, Self::Error>;
80
81 async fn set_kv_data(
91 &self,
92 key: StateStoreDataKey<'_>,
93 value: StateStoreDataValue,
94 ) -> Result<(), Self::Error>;
95
96 async fn remove_kv_data(&self, key: StateStoreDataKey<'_>) -> Result<(), Self::Error>;
102
103 async fn save_changes(&self, changes: &StateChanges) -> Result<(), Self::Error>;
105
106 async fn get_presence_event(
113 &self,
114 user_id: &UserId,
115 ) -> Result<Option<Raw<PresenceEvent>>, Self::Error>;
116
117 async fn get_presence_events(
123 &self,
124 user_ids: &[OwnedUserId],
125 ) -> Result<Vec<Raw<PresenceEvent>>, Self::Error>;
126
127 async fn get_state_event(
135 &self,
136 room_id: &RoomId,
137 event_type: StateEventType,
138 state_key: &str,
139 ) -> Result<Option<RawAnySyncOrStrippedState>, Self::Error>;
140
141 async fn get_state_events(
149 &self,
150 room_id: &RoomId,
151 event_type: StateEventType,
152 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error>;
153
154 async fn get_state_events_for_keys(
165 &self,
166 room_id: &RoomId,
167 event_type: StateEventType,
168 state_keys: &[&str],
169 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error>;
170
171 async fn get_profile(
179 &self,
180 room_id: &RoomId,
181 user_id: &UserId,
182 ) -> Result<Option<MinimalRoomMemberEvent>, Self::Error>;
183
184 async fn get_profiles<'a>(
192 &self,
193 room_id: &RoomId,
194 user_ids: &'a [OwnedUserId],
195 ) -> Result<BTreeMap<&'a UserId, MinimalRoomMemberEvent>, Self::Error>;
196
197 async fn get_user_ids(
200 &self,
201 room_id: &RoomId,
202 memberships: RoomMemberships,
203 ) -> Result<Vec<OwnedUserId>, Self::Error>;
204
205 async fn get_room_infos(
207 &self,
208 room_load_settings: &RoomLoadSettings,
209 ) -> Result<Vec<RoomInfo>, Self::Error>;
210
211 async fn get_users_with_display_name(
220 &self,
221 room_id: &RoomId,
222 display_name: &DisplayName,
223 ) -> Result<BTreeSet<OwnedUserId>, Self::Error>;
224
225 async fn get_users_with_display_names<'a>(
233 &self,
234 room_id: &RoomId,
235 display_names: &'a [DisplayName],
236 ) -> Result<HashMap<&'a DisplayName, BTreeSet<OwnedUserId>>, Self::Error>;
237
238 async fn get_account_data_event(
244 &self,
245 event_type: GlobalAccountDataEventType,
246 ) -> Result<Option<Raw<AnyGlobalAccountDataEvent>>, Self::Error>;
247
248 async fn get_room_account_data_event(
258 &self,
259 room_id: &RoomId,
260 event_type: RoomAccountDataEventType,
261 ) -> Result<Option<Raw<AnyRoomAccountDataEvent>>, Self::Error>;
262
263 async fn get_user_room_receipt_event(
276 &self,
277 room_id: &RoomId,
278 receipt_type: ReceiptType,
279 thread: ReceiptThread,
280 user_id: &UserId,
281 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error>;
282
283 async fn get_event_room_receipt_events(
297 &self,
298 room_id: &RoomId,
299 receipt_type: ReceiptType,
300 thread: ReceiptThread,
301 event_id: &EventId,
302 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error>;
303
304 async fn get_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error>;
310
311 async fn set_custom_value(
320 &self,
321 key: &[u8],
322 value: Vec<u8>,
323 ) -> Result<Option<Vec<u8>>, Self::Error>;
324
325 async fn set_custom_value_no_read(
339 &self,
340 key: &[u8],
341 value: Vec<u8>,
342 ) -> Result<(), Self::Error> {
343 self.set_custom_value(key, value).await.map(|_| ())
344 }
345
346 async fn remove_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error>;
352
353 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error>;
359
360 async fn save_send_queue_request(
370 &self,
371 room_id: &RoomId,
372 transaction_id: OwnedTransactionId,
373 created_at: MilliSecondsSinceUnixEpoch,
374 request: QueuedRequestKind,
375 priority: usize,
376 ) -> Result<(), Self::Error>;
377
378 async fn update_send_queue_request(
390 &self,
391 room_id: &RoomId,
392 transaction_id: &TransactionId,
393 content: QueuedRequestKind,
394 ) -> Result<bool, Self::Error>;
395
396 async fn remove_send_queue_request(
402 &self,
403 room_id: &RoomId,
404 transaction_id: &TransactionId,
405 ) -> Result<bool, Self::Error>;
406
407 async fn load_send_queue_requests(
413 &self,
414 room_id: &RoomId,
415 ) -> Result<Vec<QueuedRequest>, Self::Error>;
416
417 async fn update_send_queue_request_status(
420 &self,
421 room_id: &RoomId,
422 transaction_id: &TransactionId,
423 error: Option<QueueWedgeError>,
424 ) -> Result<(), Self::Error>;
425
426 async fn load_rooms_with_unsent_requests(&self) -> Result<Vec<OwnedRoomId>, Self::Error>;
428
429 async fn save_dependent_queued_request(
432 &self,
433 room_id: &RoomId,
434 parent_txn_id: &TransactionId,
435 own_txn_id: ChildTransactionId,
436 created_at: MilliSecondsSinceUnixEpoch,
437 content: DependentQueuedRequestKind,
438 ) -> Result<(), Self::Error>;
439
440 async fn mark_dependent_queued_requests_as_ready(
449 &self,
450 room_id: &RoomId,
451 parent_txn_id: &TransactionId,
452 sent_parent_key: SentRequestKey,
453 ) -> Result<usize, Self::Error>;
454
455 async fn update_dependent_queued_request(
459 &self,
460 room_id: &RoomId,
461 own_transaction_id: &ChildTransactionId,
462 new_content: DependentQueuedRequestKind,
463 ) -> Result<bool, Self::Error>;
464
465 async fn remove_dependent_queued_request(
470 &self,
471 room: &RoomId,
472 own_txn_id: &ChildTransactionId,
473 ) -> Result<bool, Self::Error>;
474
475 async fn load_dependent_queued_requests(
481 &self,
482 room: &RoomId,
483 ) -> Result<Vec<DependentQueuedRequest>, Self::Error>;
484
485 async fn upsert_thread_subscriptions(
495 &self,
496 updates: Vec<(&RoomId, &EventId, StoredThreadSubscription)>,
497 ) -> Result<(), Self::Error>;
498
499 async fn remove_thread_subscription(
503 &self,
504 room: &RoomId,
505 thread_id: &EventId,
506 ) -> Result<(), Self::Error>;
507
508 async fn load_thread_subscription(
512 &self,
513 room: &RoomId,
514 thread_id: &EventId,
515 ) -> Result<Option<StoredThreadSubscription>, Self::Error>;
516
517 #[doc(hidden)]
523 async fn optimize(&self) -> Result<(), Self::Error>;
524
525 async fn get_size(&self) -> Result<Option<usize>, Self::Error>;
527}
528
529#[repr(transparent)]
530struct EraseStateStoreError<T>(T);
531
532#[cfg(not(tarpaulin_include))]
533impl<T: fmt::Debug> fmt::Debug for EraseStateStoreError<T> {
534 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
535 self.0.fmt(f)
536 }
537}
538
539#[cfg_attr(target_family = "wasm", async_trait(?Send))]
540#[cfg_attr(not(target_family = "wasm"), async_trait)]
541impl<T: StateStore> StateStore for EraseStateStoreError<T> {
542 type Error = StoreError;
543
544 async fn get_kv_data(
545 &self,
546 key: StateStoreDataKey<'_>,
547 ) -> Result<Option<StateStoreDataValue>, Self::Error> {
548 self.0.get_kv_data(key).await.map_err(Into::into)
549 }
550
551 async fn set_kv_data(
552 &self,
553 key: StateStoreDataKey<'_>,
554 value: StateStoreDataValue,
555 ) -> Result<(), Self::Error> {
556 self.0.set_kv_data(key, value).await.map_err(Into::into)
557 }
558
559 async fn remove_kv_data(&self, key: StateStoreDataKey<'_>) -> Result<(), Self::Error> {
560 self.0.remove_kv_data(key).await.map_err(Into::into)
561 }
562
563 async fn save_changes(&self, changes: &StateChanges) -> Result<(), Self::Error> {
564 self.0.save_changes(changes).await.map_err(Into::into)
565 }
566
567 async fn get_presence_event(
568 &self,
569 user_id: &UserId,
570 ) -> Result<Option<Raw<PresenceEvent>>, Self::Error> {
571 self.0.get_presence_event(user_id).await.map_err(Into::into)
572 }
573
574 async fn get_presence_events(
575 &self,
576 user_ids: &[OwnedUserId],
577 ) -> Result<Vec<Raw<PresenceEvent>>, Self::Error> {
578 self.0.get_presence_events(user_ids).await.map_err(Into::into)
579 }
580
581 async fn get_state_event(
582 &self,
583 room_id: &RoomId,
584 event_type: StateEventType,
585 state_key: &str,
586 ) -> Result<Option<RawAnySyncOrStrippedState>, Self::Error> {
587 self.0.get_state_event(room_id, event_type, state_key).await.map_err(Into::into)
588 }
589
590 async fn get_state_events(
591 &self,
592 room_id: &RoomId,
593 event_type: StateEventType,
594 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
595 self.0.get_state_events(room_id, event_type).await.map_err(Into::into)
596 }
597
598 async fn get_state_events_for_keys(
599 &self,
600 room_id: &RoomId,
601 event_type: StateEventType,
602 state_keys: &[&str],
603 ) -> Result<Vec<RawAnySyncOrStrippedState>, Self::Error> {
604 self.0.get_state_events_for_keys(room_id, event_type, state_keys).await.map_err(Into::into)
605 }
606
607 async fn get_profile(
608 &self,
609 room_id: &RoomId,
610 user_id: &UserId,
611 ) -> Result<Option<MinimalRoomMemberEvent>, Self::Error> {
612 self.0.get_profile(room_id, user_id).await.map_err(Into::into)
613 }
614
615 async fn get_profiles<'a>(
616 &self,
617 room_id: &RoomId,
618 user_ids: &'a [OwnedUserId],
619 ) -> Result<BTreeMap<&'a UserId, MinimalRoomMemberEvent>, Self::Error> {
620 self.0.get_profiles(room_id, user_ids).await.map_err(Into::into)
621 }
622
623 async fn get_user_ids(
624 &self,
625 room_id: &RoomId,
626 memberships: RoomMemberships,
627 ) -> Result<Vec<OwnedUserId>, Self::Error> {
628 self.0.get_user_ids(room_id, memberships).await.map_err(Into::into)
629 }
630
631 async fn get_room_infos(
632 &self,
633 room_load_settings: &RoomLoadSettings,
634 ) -> Result<Vec<RoomInfo>, Self::Error> {
635 self.0.get_room_infos(room_load_settings).await.map_err(Into::into)
636 }
637
638 async fn get_users_with_display_name(
639 &self,
640 room_id: &RoomId,
641 display_name: &DisplayName,
642 ) -> Result<BTreeSet<OwnedUserId>, Self::Error> {
643 self.0.get_users_with_display_name(room_id, display_name).await.map_err(Into::into)
644 }
645
646 async fn get_users_with_display_names<'a>(
647 &self,
648 room_id: &RoomId,
649 display_names: &'a [DisplayName],
650 ) -> Result<HashMap<&'a DisplayName, BTreeSet<OwnedUserId>>, Self::Error> {
651 self.0.get_users_with_display_names(room_id, display_names).await.map_err(Into::into)
652 }
653
654 async fn get_account_data_event(
655 &self,
656 event_type: GlobalAccountDataEventType,
657 ) -> Result<Option<Raw<AnyGlobalAccountDataEvent>>, Self::Error> {
658 self.0.get_account_data_event(event_type).await.map_err(Into::into)
659 }
660
661 async fn get_room_account_data_event(
662 &self,
663 room_id: &RoomId,
664 event_type: RoomAccountDataEventType,
665 ) -> Result<Option<Raw<AnyRoomAccountDataEvent>>, Self::Error> {
666 self.0.get_room_account_data_event(room_id, event_type).await.map_err(Into::into)
667 }
668
669 async fn get_user_room_receipt_event(
670 &self,
671 room_id: &RoomId,
672 receipt_type: ReceiptType,
673 thread: ReceiptThread,
674 user_id: &UserId,
675 ) -> Result<Option<(OwnedEventId, Receipt)>, Self::Error> {
676 self.0
677 .get_user_room_receipt_event(room_id, receipt_type, thread, user_id)
678 .await
679 .map_err(Into::into)
680 }
681
682 async fn get_event_room_receipt_events(
683 &self,
684 room_id: &RoomId,
685 receipt_type: ReceiptType,
686 thread: ReceiptThread,
687 event_id: &EventId,
688 ) -> Result<Vec<(OwnedUserId, Receipt)>, Self::Error> {
689 self.0
690 .get_event_room_receipt_events(room_id, receipt_type, thread, event_id)
691 .await
692 .map_err(Into::into)
693 }
694
695 async fn get_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
696 self.0.get_custom_value(key).await.map_err(Into::into)
697 }
698
699 async fn set_custom_value(
700 &self,
701 key: &[u8],
702 value: Vec<u8>,
703 ) -> Result<Option<Vec<u8>>, Self::Error> {
704 self.0.set_custom_value(key, value).await.map_err(Into::into)
705 }
706
707 async fn remove_custom_value(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> {
708 self.0.remove_custom_value(key).await.map_err(Into::into)
709 }
710
711 async fn remove_room(&self, room_id: &RoomId) -> Result<(), Self::Error> {
712 self.0.remove_room(room_id).await.map_err(Into::into)
713 }
714
715 async fn save_send_queue_request(
716 &self,
717 room_id: &RoomId,
718 transaction_id: OwnedTransactionId,
719 created_at: MilliSecondsSinceUnixEpoch,
720 content: QueuedRequestKind,
721 priority: usize,
722 ) -> Result<(), Self::Error> {
723 self.0
724 .save_send_queue_request(room_id, transaction_id, created_at, content, priority)
725 .await
726 .map_err(Into::into)
727 }
728
729 async fn update_send_queue_request(
730 &self,
731 room_id: &RoomId,
732 transaction_id: &TransactionId,
733 content: QueuedRequestKind,
734 ) -> Result<bool, Self::Error> {
735 self.0.update_send_queue_request(room_id, transaction_id, content).await.map_err(Into::into)
736 }
737
738 async fn remove_send_queue_request(
739 &self,
740 room_id: &RoomId,
741 transaction_id: &TransactionId,
742 ) -> Result<bool, Self::Error> {
743 self.0.remove_send_queue_request(room_id, transaction_id).await.map_err(Into::into)
744 }
745
746 async fn load_send_queue_requests(
747 &self,
748 room_id: &RoomId,
749 ) -> Result<Vec<QueuedRequest>, Self::Error> {
750 self.0.load_send_queue_requests(room_id).await.map_err(Into::into)
751 }
752
753 async fn update_send_queue_request_status(
754 &self,
755 room_id: &RoomId,
756 transaction_id: &TransactionId,
757 error: Option<QueueWedgeError>,
758 ) -> Result<(), Self::Error> {
759 self.0
760 .update_send_queue_request_status(room_id, transaction_id, error)
761 .await
762 .map_err(Into::into)
763 }
764
765 async fn load_rooms_with_unsent_requests(&self) -> Result<Vec<OwnedRoomId>, Self::Error> {
766 self.0.load_rooms_with_unsent_requests().await.map_err(Into::into)
767 }
768
769 async fn save_dependent_queued_request(
770 &self,
771 room_id: &RoomId,
772 parent_txn_id: &TransactionId,
773 own_txn_id: ChildTransactionId,
774 created_at: MilliSecondsSinceUnixEpoch,
775 content: DependentQueuedRequestKind,
776 ) -> Result<(), Self::Error> {
777 self.0
778 .save_dependent_queued_request(room_id, parent_txn_id, own_txn_id, created_at, content)
779 .await
780 .map_err(Into::into)
781 }
782
783 async fn mark_dependent_queued_requests_as_ready(
784 &self,
785 room_id: &RoomId,
786 parent_txn_id: &TransactionId,
787 sent_parent_key: SentRequestKey,
788 ) -> Result<usize, Self::Error> {
789 self.0
790 .mark_dependent_queued_requests_as_ready(room_id, parent_txn_id, sent_parent_key)
791 .await
792 .map_err(Into::into)
793 }
794
795 async fn remove_dependent_queued_request(
796 &self,
797 room_id: &RoomId,
798 own_txn_id: &ChildTransactionId,
799 ) -> Result<bool, Self::Error> {
800 self.0.remove_dependent_queued_request(room_id, own_txn_id).await.map_err(Into::into)
801 }
802
803 async fn load_dependent_queued_requests(
804 &self,
805 room_id: &RoomId,
806 ) -> Result<Vec<DependentQueuedRequest>, Self::Error> {
807 self.0.load_dependent_queued_requests(room_id).await.map_err(Into::into)
808 }
809
810 async fn update_dependent_queued_request(
811 &self,
812 room_id: &RoomId,
813 own_transaction_id: &ChildTransactionId,
814 new_content: DependentQueuedRequestKind,
815 ) -> Result<bool, Self::Error> {
816 self.0
817 .update_dependent_queued_request(room_id, own_transaction_id, new_content)
818 .await
819 .map_err(Into::into)
820 }
821
822 async fn upsert_thread_subscriptions(
823 &self,
824 updates: Vec<(&RoomId, &EventId, StoredThreadSubscription)>,
825 ) -> Result<(), Self::Error> {
826 self.0.upsert_thread_subscriptions(updates).await.map_err(Into::into)
827 }
828
829 async fn load_thread_subscription(
830 &self,
831 room: &RoomId,
832 thread_id: &EventId,
833 ) -> Result<Option<StoredThreadSubscription>, Self::Error> {
834 self.0.load_thread_subscription(room, thread_id).await.map_err(Into::into)
835 }
836
837 async fn remove_thread_subscription(
838 &self,
839 room: &RoomId,
840 thread_id: &EventId,
841 ) -> Result<(), Self::Error> {
842 self.0.remove_thread_subscription(room, thread_id).await.map_err(Into::into)
843 }
844
845 async fn optimize(&self) -> Result<(), Self::Error> {
846 self.0.optimize().await.map_err(Into::into)
847 }
848
849 async fn get_size(&self) -> Result<Option<usize>, Self::Error> {
850 self.0.get_size().await.map_err(Into::into)
851 }
852}
853
854#[cfg_attr(target_family = "wasm", async_trait(?Send))]
856#[cfg_attr(not(target_family = "wasm"), async_trait)]
857pub trait StateStoreExt: StateStore {
858 async fn get_state_event_static<C>(
864 &self,
865 room_id: &RoomId,
866 ) -> Result<Option<RawSyncOrStrippedState<C>>, Self::Error>
867 where
868 C: StaticEventContent<IsPrefix = ruma::events::False>
869 + StaticStateEventContent<StateKey = EmptyStateKey>
870 + RedactContent,
871 C::Redacted: RedactedStateEventContent,
872 {
873 Ok(self.get_state_event(room_id, C::TYPE.into(), "").await?.map(|raw| raw.cast()))
874 }
875
876 async fn get_state_event_static_for_key<C, K>(
882 &self,
883 room_id: &RoomId,
884 state_key: &K,
885 ) -> Result<Option<RawSyncOrStrippedState<C>>, Self::Error>
886 where
887 C: StaticEventContent<IsPrefix = ruma::events::False>
888 + StaticStateEventContent
889 + RedactContent,
890 C::StateKey: Borrow<K>,
891 C::Redacted: RedactedStateEventContent,
892 K: AsRef<str> + ?Sized + Sync,
893 {
894 Ok(self
895 .get_state_event(room_id, C::TYPE.into(), state_key.as_ref())
896 .await?
897 .map(|raw| raw.cast()))
898 }
899
900 async fn get_state_events_static<C>(
906 &self,
907 room_id: &RoomId,
908 ) -> Result<Vec<RawSyncOrStrippedState<C>>, Self::Error>
909 where
910 C: StaticEventContent<IsPrefix = ruma::events::False>
911 + StaticStateEventContent
912 + RedactContent,
913 C::Redacted: RedactedStateEventContent,
914 {
915 Ok(self
917 .get_state_events(room_id, C::TYPE.into())
918 .await?
919 .into_iter()
920 .map(|raw| raw.cast())
921 .collect())
922 }
923
924 async fn get_state_events_for_keys_static<'a, C, K, I>(
933 &self,
934 room_id: &RoomId,
935 state_keys: I,
936 ) -> Result<Vec<RawSyncOrStrippedState<C>>, Self::Error>
937 where
938 C: StaticEventContent<IsPrefix = ruma::events::False>
939 + StaticStateEventContent
940 + RedactContent,
941 C::StateKey: Borrow<K>,
942 C::Redacted: RedactedStateEventContent,
943 K: AsRef<str> + Sized + Sync + 'a,
944 I: IntoIterator<Item = &'a K> + Send,
945 I::IntoIter: Send,
946 {
947 Ok(self
948 .get_state_events_for_keys(
949 room_id,
950 C::TYPE.into(),
951 &state_keys.into_iter().map(|k| k.as_ref()).collect::<Vec<_>>(),
952 )
953 .await?
954 .into_iter()
955 .map(|raw| raw.cast())
956 .collect())
957 }
958
959 async fn get_account_data_event_static<C>(
961 &self,
962 ) -> Result<Option<Raw<GlobalAccountDataEvent<C>>>, Self::Error>
963 where
964 C: StaticEventContent<IsPrefix = ruma::events::False> + GlobalAccountDataEventContent,
965 {
966 Ok(self.get_account_data_event(C::TYPE.into()).await?.map(Raw::cast_unchecked))
967 }
968
969 async fn get_room_account_data_event_static<C>(
977 &self,
978 room_id: &RoomId,
979 ) -> Result<Option<Raw<RoomAccountDataEvent<C>>>, Self::Error>
980 where
981 C: StaticEventContent<IsPrefix = ruma::events::False> + RoomAccountDataEventContent,
982 {
983 Ok(self
984 .get_room_account_data_event(room_id, C::TYPE.into())
985 .await?
986 .map(Raw::cast_unchecked))
987 }
988
989 async fn get_member_event(
997 &self,
998 room_id: &RoomId,
999 state_key: &UserId,
1000 ) -> Result<Option<RawMemberEvent>, Self::Error> {
1001 self.get_state_event_static_for_key(room_id, state_key).await
1002 }
1003}
1004
1005#[cfg_attr(target_family = "wasm", async_trait(?Send))]
1006#[cfg_attr(not(target_family = "wasm"), async_trait)]
1007impl<T: StateStore + ?Sized> StateStoreExt for T {}
1008
1009pub type DynStateStore = dyn StateStore<Error = StoreError>;
1011
1012pub trait IntoStateStore {
1018 #[doc(hidden)]
1019 fn into_state_store(self) -> Arc<DynStateStore>;
1020}
1021
1022impl<T> IntoStateStore for T
1023where
1024 T: StateStore + Sized + 'static,
1025{
1026 fn into_state_store(self) -> Arc<DynStateStore> {
1027 Arc::new(EraseStateStoreError(self))
1028 }
1029}
1030
1031impl<T> IntoStateStore for Arc<T>
1034where
1035 T: StateStore + 'static,
1036{
1037 fn into_state_store(self) -> Arc<DynStateStore> {
1038 let ptr: *const T = Arc::into_raw(self);
1039 let ptr_erased = ptr as *const EraseStateStoreError<T>;
1040 unsafe { Arc::from_raw(ptr_erased) }
1043 }
1044}
1045
1046#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1048pub struct SupportedVersionsResponse {
1049 pub versions: Vec<String>,
1051
1052 pub unstable_features: BTreeMap<String, bool>,
1054}
1055
1056impl SupportedVersionsResponse {
1057 pub fn supported_versions(&self) -> SupportedVersions {
1063 let mut supported_versions =
1064 SupportedVersions::from_parts(&self.versions, &self.unstable_features);
1065
1066 if supported_versions.versions.is_empty() {
1069 supported_versions.versions.insert(MatrixVersion::V1_0);
1070 }
1071
1072 supported_versions
1073 }
1074}
1075
1076#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1077pub struct WellKnownResponse {
1079 pub homeserver: HomeserverInfo,
1081
1082 pub identity_server: Option<IdentityServerInfo>,
1084
1085 pub tile_server: Option<TileServerInfo>,
1087
1088 pub rtc_foci: Vec<RtcFocusInfo>,
1090}
1091
1092impl From<discover_homeserver::Response> for WellKnownResponse {
1093 fn from(response: discover_homeserver::Response) -> Self {
1094 Self {
1095 homeserver: response.homeserver,
1096 identity_server: response.identity_server,
1097 tile_server: response.tile_server,
1098 rtc_foci: response.rtc_foci,
1099 }
1100 }
1101}
1102
1103#[derive(Debug, Clone)]
1105pub enum StateStoreDataValue {
1106 SyncToken(String),
1108
1109 SupportedVersions(TtlValue<SupportedVersionsResponse>),
1111
1112 WellKnown(TtlValue<Option<WellKnownResponse>>),
1114
1115 Filter(String),
1117
1118 UserAvatarUrl(OwnedMxcUri),
1120
1121 RecentlyVisitedRooms(Vec<OwnedRoomId>),
1123
1124 UtdHookManagerData(GrowableBloom),
1127
1128 OneTimeKeyAlreadyUploaded,
1131
1132 ComposerDraft(ComposerDraft),
1137
1138 SeenKnockRequests(BTreeMap<OwnedEventId, OwnedUserId>),
1140
1141 ThreadSubscriptionsCatchupTokens(Vec<ThreadSubscriptionCatchupToken>),
1146
1147 HomeserverCapabilities(TtlValue<Capabilities>),
1149}
1150
1151#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1161pub struct ThreadSubscriptionCatchupToken {
1162 pub from: String,
1168
1169 pub to: Option<String>,
1175}
1176
1177#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1179pub struct ComposerDraft {
1180 pub plain_text: String,
1182 pub html_text: Option<String>,
1185 pub draft_type: ComposerDraftType,
1187 #[serde(default)]
1189 pub attachments: Vec<DraftAttachment>,
1190}
1191
1192#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1194pub struct DraftAttachment {
1195 pub filename: String,
1197 pub content: DraftAttachmentContent,
1199}
1200
1201#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1203#[serde(tag = "type")]
1204pub enum DraftAttachmentContent {
1205 Image {
1207 data: Vec<u8>,
1209 mimetype: Option<String>,
1211 size: Option<u64>,
1213 width: Option<u64>,
1215 height: Option<u64>,
1217 blurhash: Option<String>,
1219 thumbnail: Option<DraftThumbnail>,
1221 },
1222 Video {
1224 data: Vec<u8>,
1226 mimetype: Option<String>,
1228 size: Option<u64>,
1230 width: Option<u64>,
1232 height: Option<u64>,
1234 duration: Option<std::time::Duration>,
1236 blurhash: Option<String>,
1238 thumbnail: Option<DraftThumbnail>,
1240 },
1241 Audio {
1243 data: Vec<u8>,
1245 mimetype: Option<String>,
1247 size: Option<u64>,
1249 duration: Option<std::time::Duration>,
1251 },
1252 File {
1254 data: Vec<u8>,
1256 mimetype: Option<String>,
1258 size: Option<u64>,
1260 },
1261}
1262
1263#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1265pub struct DraftThumbnail {
1266 pub filename: String,
1268 pub data: Vec<u8>,
1270 pub mimetype: Option<String>,
1272 pub width: Option<u64>,
1274 pub height: Option<u64>,
1276 pub size: Option<u64>,
1278}
1279
1280#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1282pub enum ComposerDraftType {
1283 NewMessage,
1285 Reply {
1287 event_id: OwnedEventId,
1289 },
1290 Edit {
1292 event_id: OwnedEventId,
1294 },
1295}
1296
1297impl StateStoreDataValue {
1298 pub fn into_sync_token(self) -> Option<String> {
1300 as_variant!(self, Self::SyncToken)
1301 }
1302
1303 pub fn into_filter(self) -> Option<String> {
1305 as_variant!(self, Self::Filter)
1306 }
1307
1308 pub fn into_user_avatar_url(self) -> Option<OwnedMxcUri> {
1310 as_variant!(self, Self::UserAvatarUrl)
1311 }
1312
1313 pub fn into_recently_visited_rooms(self) -> Option<Vec<OwnedRoomId>> {
1315 as_variant!(self, Self::RecentlyVisitedRooms)
1316 }
1317
1318 pub fn into_utd_hook_manager_data(self) -> Option<GrowableBloom> {
1320 as_variant!(self, Self::UtdHookManagerData)
1321 }
1322
1323 pub fn into_composer_draft(self) -> Option<ComposerDraft> {
1325 as_variant!(self, Self::ComposerDraft)
1326 }
1327
1328 pub fn into_supported_versions(self) -> Option<TtlValue<SupportedVersionsResponse>> {
1330 as_variant!(self, Self::SupportedVersions)
1331 }
1332
1333 pub fn into_well_known(self) -> Option<TtlValue<Option<WellKnownResponse>>> {
1335 as_variant!(self, Self::WellKnown)
1336 }
1337
1338 pub fn into_seen_knock_requests(self) -> Option<BTreeMap<OwnedEventId, OwnedUserId>> {
1340 as_variant!(self, Self::SeenKnockRequests)
1341 }
1342
1343 pub fn into_thread_subscriptions_catchup_tokens(
1346 self,
1347 ) -> Option<Vec<ThreadSubscriptionCatchupToken>> {
1348 as_variant!(self, Self::ThreadSubscriptionsCatchupTokens)
1349 }
1350
1351 pub fn into_homeserver_capabilities(self) -> Option<TtlValue<Capabilities>> {
1354 as_variant!(self, Self::HomeserverCapabilities)
1355 }
1356}
1357
1358#[derive(Debug, Clone, Copy)]
1360pub enum StateStoreDataKey<'a> {
1361 SyncToken,
1363
1364 SupportedVersions,
1366
1367 WellKnown,
1369
1370 Filter(&'a str),
1372
1373 UserAvatarUrl(&'a UserId),
1375
1376 RecentlyVisitedRooms(&'a UserId),
1378
1379 UtdHookManagerData,
1382
1383 OneTimeKeyAlreadyUploaded,
1386
1387 ComposerDraft(&'a RoomId, Option<&'a EventId>),
1392
1393 SeenKnockRequests(&'a RoomId),
1395
1396 ThreadSubscriptionsCatchupTokens,
1398
1399 HomeserverCapabilities,
1401}
1402
1403impl StateStoreDataKey<'_> {
1404 pub const SYNC_TOKEN: &'static str = "sync_token";
1406
1407 pub const SUPPORTED_VERSIONS: &'static str = "server_capabilities"; pub const WELL_KNOWN: &'static str = "well_known";
1414
1415 pub const FILTER: &'static str = "filter";
1417
1418 pub const USER_AVATAR_URL: &'static str = "user_avatar_url";
1421
1422 pub const RECENTLY_VISITED_ROOMS: &'static str = "recently_visited_rooms";
1425
1426 pub const UTD_HOOK_MANAGER_DATA: &'static str = "utd_hook_manager_data";
1429
1430 pub const ONE_TIME_KEY_ALREADY_UPLOADED: &'static str = "one_time_key_already_uploaded";
1433
1434 pub const COMPOSER_DRAFT: &'static str = "composer_draft";
1437
1438 pub const SEEN_KNOCK_REQUESTS: &'static str = "seen_knock_requests";
1441
1442 pub const THREAD_SUBSCRIPTIONS_CATCHUP_TOKENS: &'static str =
1445 "thread_subscriptions_catchup_tokens";
1446
1447 pub const HOMESERVER_CAPABILITIES: &'static str = "homeserver_capabilities";
1449}
1450
1451pub fn compare_thread_subscription_bump_stamps(
1460 previous: Option<u64>,
1461 new: &mut Option<u64>,
1462) -> bool {
1463 match (previous, &new) {
1464 (Some(prev_bump), None) => {
1467 *new = Some(prev_bump);
1468 }
1469
1470 (Some(prev_bump), Some(new_bump)) if *new_bump <= prev_bump => {
1472 return false;
1473 }
1474
1475 _ => {}
1477 }
1478
1479 true
1480}