Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/matrix-sdk-base/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
authors = ["Damir Jelić <[email protected]>"]
description = "The base component to build a Matrix client library."
edition = "2021"
edition = "2024"
homepage = "https://github.com/matrix-org/matrix-rust-sdk"
keywords = ["matrix", "chat", "messaging", "ruma", "nio"]
license = "Apache-2.0"
Expand Down
67 changes: 33 additions & 34 deletions crates/matrix-sdk-base/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,33 +26,34 @@ use eyeball_im::{Vector, VectorDiff};
use futures_util::Stream;
#[cfg(feature = "e2e-encryption")]
use matrix_sdk_crypto::{
store::DynCryptoStore, types::requests::ToDeviceRequest, CollectStrategy, DecryptionSettings,
EncryptionSettings, OlmError, OlmMachine, TrustRequirement,
CollectStrategy, DecryptionSettings, EncryptionSettings, OlmError, OlmMachine,
TrustRequirement, store::DynCryptoStore, types::requests::ToDeviceRequest,
};
#[cfg(feature = "e2e-encryption")]
use ruma::events::room::{history_visibility::HistoryVisibility, member::MembershipState};
#[cfg(doc)]
use ruma::DeviceId;
#[cfg(feature = "e2e-encryption")]
use ruma::events::room::{history_visibility::HistoryVisibility, member::MembershipState};
use ruma::{
MilliSecondsSinceUnixEpoch, OwnedRoomId, OwnedUserId, RoomId, UserId,
api::client::{self as api, sync::sync_events::v5},
events::{
StateEvent, StateEventType,
ignored_user_list::IgnoredUserListEventContent,
push_rules::{PushRulesEvent, PushRulesEventContent},
room::member::SyncRoomMemberEvent,
StateEvent, StateEventType,
},
push::Ruleset,
time::Instant,
MilliSecondsSinceUnixEpoch, OwnedRoomId, OwnedUserId, RoomId, UserId,
};
use tokio::sync::{broadcast, Mutex};
use tokio::sync::{Mutex, broadcast};
#[cfg(feature = "e2e-encryption")]
use tokio::sync::{RwLock, RwLockReadGuard};
use tracing::{debug, enabled, info, instrument, warn, Level};
use tracing::{Level, debug, enabled, info, instrument, warn};

#[cfg(feature = "e2e-encryption")]
use crate::RoomMemberships;
use crate::{
InviteAcceptanceDetails, RoomStateFilter, SessionMeta,
deserialized_responses::DisplayName,
error::{Error, Result},
event_cache::store::EventCacheStoreLock,
Expand All @@ -61,12 +62,11 @@ use crate::{
Room, RoomInfoNotableUpdate, RoomInfoNotableUpdateReasons, RoomMembersUpdate, RoomState,
},
store::{
ambiguity_map::AmbiguityCache, BaseStateStore, DynStateStore, MemoryStore,
Result as StoreResult, RoomLoadSettings, StateChanges, StateStoreDataKey,
StateStoreDataValue, StateStoreExt, StoreConfig,
BaseStateStore, DynStateStore, MemoryStore, Result as StoreResult, RoomLoadSettings,
StateChanges, StateStoreDataKey, StateStoreDataValue, StateStoreExt, StoreConfig,
ambiguity_map::AmbiguityCache,
},
sync::{RoomUpdates, SyncResponse},
InviteAcceptanceDetails, RoomStateFilter, SessionMeta,
};

/// A no (network) IO client implementation.
Expand All @@ -76,7 +76,7 @@ use crate::{
/// rather through `matrix_sdk::Client`.
///
/// ```rust
/// use matrix_sdk_base::{store::StoreConfig, BaseClient, ThreadingSupport};
/// use matrix_sdk_base::{BaseClient, ThreadingSupport, store::StoreConfig};
///
/// let client = BaseClient::new(
/// StoreConfig::new("cross-process-holder-name".to_owned()),
Expand Down Expand Up @@ -273,7 +273,9 @@ impl BaseClient {

/// Get a stream of all the rooms changes, in addition to the existing
/// rooms.
pub fn rooms_stream(&self) -> (Vector<Room>, impl Stream<Item = Vec<VectorDiff<Room>>>) {
pub fn rooms_stream(
&self,
) -> (Vector<Room>, impl Stream<Item = Vec<VectorDiff<Room>>> + use<>) {
self.state_store.rooms_stream()
}

Expand Down Expand Up @@ -490,14 +492,14 @@ impl BaseClient {
// key bundle shortly after, we might accept it. If we don't do
// this, the homeserver could trick us into accepting any historic room key
// bundle.
if previous_state == RoomState::Invited {
if let Some(inviter) = inviter {
let details = InviteAcceptanceDetails {
invite_accepted_at: MilliSecondsSinceUnixEpoch::now(),
inviter,
};
room_info.set_invite_acceptance_details(details);
}
if previous_state == RoomState::Invited
&& let Some(inviter) = inviter
{
let details = InviteAcceptanceDetails {
invite_accepted_at: MilliSecondsSinceUnixEpoch::now(),
inviter,
};
room_info.set_invite_acceptance_details(details);
}

let mut changes = StateChanges::default();
Expand Down Expand Up @@ -859,14 +861,11 @@ impl BaseClient {
_ => (),
}

if let StateEvent::Original(e) = &member {
if let Some(d) = &e.content.displayname {
let display_name = DisplayName::new(d);
ambiguity_map
.entry(display_name)
.or_default()
.insert(member.state_key().clone());
}
if let StateEvent::Original(e) = &member
&& let Some(d) = &e.content.displayname
{
let display_name = DisplayName::new(d);
ambiguity_map.entry(display_name).or_default().insert(member.state_key().clone());
}

let sync_member: SyncRoomMemberEvent = member.clone().into();
Expand Down Expand Up @@ -1156,13 +1155,13 @@ mod tests {
use assert_matches2::{assert_let, assert_matches};
use futures_util::FutureExt as _;
use matrix_sdk_test::{
async_test, event_factory::EventFactory, ruma_response_from_json, InvitedRoomBuilder,
LeftRoomBuilder, StateTestEvent, StrippedStateTestEvent, SyncResponseBuilder, BOB,
BOB, InvitedRoomBuilder, LeftRoomBuilder, StateTestEvent, StrippedStateTestEvent,
SyncResponseBuilder, async_test, event_factory::EventFactory, ruma_response_from_json,
};
use ruma::{
api::client::{self as api, sync::sync_events::v5},
event_id,
events::{room::member::MembershipState, StateEventType},
events::{StateEventType, room::member::MembershipState},
room_id,
serde::Raw,
user_id,
Expand All @@ -1171,10 +1170,10 @@ mod tests {

use super::{BaseClient, RequestedRequiredStates};
use crate::{
RoomDisplayName, RoomState, SessionMeta,
client::ThreadingSupport,
store::{RoomLoadSettings, StateStoreExt, StoreConfig},
test_utils::logged_in_base_client,
RoomDisplayName, RoomState, SessionMeta,
};

#[test]
Expand Down
8 changes: 4 additions & 4 deletions crates/matrix-sdk-base/src/deserialized_responses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ pub use matrix_sdk_common::deserialized_responses::*;
use once_cell::sync::Lazy;
use regex::Regex;
use ruma::{
EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, OwnedUserId, UInt, UserId,
events::{
AnyStrippedStateEvent, AnySyncStateEvent, AnySyncTimelineEvent, EventContentFromType,
PossiblyRedactedStateEventContent, RedactContent, RedactedStateEventContent,
StateEventContent, StaticStateEventContent, StrippedStateEvent, SyncStateEvent,
room::{
member::{MembershipState, RoomMemberEvent, RoomMemberEventContent},
power_levels::{RoomPowerLevels, RoomPowerLevelsEventContent},
},
AnyStrippedStateEvent, AnySyncStateEvent, AnySyncTimelineEvent, EventContentFromType,
PossiblyRedactedStateEventContent, RedactContent, RedactedStateEventContent,
StateEventContent, StaticStateEventContent, StrippedStateEvent, SyncStateEvent,
},
serde::Raw,
EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, OwnedUserId, UInt, UserId,
};
use serde::Serialize;
use unicode_normalization::UnicodeNormalization;
Expand Down
133 changes: 76 additions & 57 deletions crates/matrix-sdk-base/src/event_cache/store/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,26 @@ use matrix_sdk_common::{
VerificationState,
},
linked_chunk::{
lazy_loader, ChunkContent, ChunkIdentifier as CId, LinkedChunkId, Position, Update,
ChunkContent, ChunkIdentifier as CId, LinkedChunkId, Position, Update, lazy_loader,
},
};
use matrix_sdk_test::{event_factory::EventFactory, ALICE, DEFAULT_TEST_ROOM_ID};
use matrix_sdk_test::{ALICE, DEFAULT_TEST_ROOM_ID, event_factory::EventFactory};
use ruma::{
EventId, RoomId,
api::client::media::get_content_thumbnail::v3::Method,
event_id,
events::{
relation::RelationType,
room::{message::RoomMessageEventContentWithoutRelation, MediaSource},
room::{MediaSource, message::RoomMessageEventContentWithoutRelation},
},
mxc_uri,
push::Action,
room_id, uint, EventId, RoomId,
room_id, uint,
};

use super::{media::IgnoreMediaRetentionPolicy, DynEventCacheStore};
use super::{DynEventCacheStore, media::IgnoreMediaRetentionPolicy};
use crate::{
event_cache::{store::DEFAULT_CHUNK_CAPACITY, Gap},
event_cache::{Gap, store::DEFAULT_CHUNK_CAPACITY},
media::{MediaFormat, MediaRequestParameters, MediaThumbnailSettings},
};

Expand Down Expand Up @@ -760,31 +761,39 @@ impl EventCacheStoreIntegrationTests for DynEventCacheStore {
.unwrap();

// Sanity check: both linked chunks can be reloaded.
assert!(lazy_loader::from_all_chunks::<3, _, _>(
self.load_all_chunks(linked_chunk_id0).await.unwrap()
)
.unwrap()
.is_some());
assert!(lazy_loader::from_all_chunks::<3, _, _>(
self.load_all_chunks(linked_chunk_id1).await.unwrap()
)
.unwrap()
.is_some());
assert!(
lazy_loader::from_all_chunks::<3, _, _>(
self.load_all_chunks(linked_chunk_id0).await.unwrap()
)
.unwrap()
.is_some()
);
assert!(
lazy_loader::from_all_chunks::<3, _, _>(
self.load_all_chunks(linked_chunk_id1).await.unwrap()
)
.unwrap()
.is_some()
);

// Clear the chunks.
self.clear_all_linked_chunks().await.unwrap();

// Both rooms now have no linked chunk.
assert!(lazy_loader::from_all_chunks::<3, _, _>(
self.load_all_chunks(linked_chunk_id0).await.unwrap()
)
.unwrap()
.is_none());
assert!(lazy_loader::from_all_chunks::<3, _, _>(
self.load_all_chunks(linked_chunk_id1).await.unwrap()
)
.unwrap()
.is_none());
assert!(
lazy_loader::from_all_chunks::<3, _, _>(
self.load_all_chunks(linked_chunk_id0).await.unwrap()
)
.unwrap()
.is_none()
);
assert!(
lazy_loader::from_all_chunks::<3, _, _>(
self.load_all_chunks(linked_chunk_id1).await.unwrap()
)
.unwrap()
.is_none()
);
}

async fn test_remove_room(&self) {
Expand Down Expand Up @@ -970,19 +979,21 @@ impl EventCacheStoreIntegrationTests for DynEventCacheStore {
assert_eq!(event.event_id(), event_comte.event_id());

// Now let's try to find an event that exists, but not in the expected room.
assert!(self
.find_event(room_id, event_gruyere.event_id().unwrap().as_ref())
.await
.expect("failed to query for finding an event")
.is_none());
assert!(
self.find_event(room_id, event_gruyere.event_id().unwrap().as_ref())
.await
.expect("failed to query for finding an event")
.is_none()
);

// Clearing the rooms also clears the event's storage.
self.clear_all_linked_chunks().await.expect("failed to clear all rooms chunks");
assert!(self
.find_event(room_id, event_comte.event_id().unwrap().as_ref())
.await
.expect("failed to query for finding an event")
.is_none());
assert!(
self.find_event(room_id, event_comte.event_id().unwrap().as_ref())
.await
.expect("failed to query for finding an event")
.is_none()
);
}

async fn test_find_event_relations(&self) {
Expand Down Expand Up @@ -1029,12 +1040,16 @@ impl EventCacheStoreIntegrationTests for DynEventCacheStore {
let relations = self.find_event_relations(room_id, eid1, None).await.unwrap();
assert_eq!(relations.len(), 2);
// The position is `None` for items outside the linked chunk.
assert!(relations
.iter()
.any(|(ev, pos)| ev.event_id().as_deref() == Some(edit_eid1) && pos.is_none()));
assert!(relations
.iter()
.any(|(ev, pos)| ev.event_id().as_deref() == Some(reaction_eid1) && pos.is_none()));
assert!(
relations
.iter()
.any(|(ev, pos)| ev.event_id().as_deref() == Some(edit_eid1) && pos.is_none())
);
assert!(
relations
.iter()
.any(|(ev, pos)| ev.event_id().as_deref() == Some(reaction_eid1) && pos.is_none())
);

// Finding relations with a filter only returns a subset.
let relations = self
Expand Down Expand Up @@ -1088,9 +1103,11 @@ impl EventCacheStoreIntegrationTests for DynEventCacheStore {
}));

// But it's still not set for the other related events.
assert!(relations
.iter()
.any(|(ev, pos)| ev.event_id().as_deref() == Some(edit_eid1) && pos.is_none()));
assert!(
relations
.iter()
.any(|(ev, pos)| ev.event_id().as_deref() == Some(edit_eid1) && pos.is_none())
);
}

async fn test_save_event(&self) {
Expand Down Expand Up @@ -1123,16 +1140,18 @@ impl EventCacheStoreIntegrationTests for DynEventCacheStore {
assert_eq!(event.event_id(), event_gruyere.event_id());

// But they won't be returned when searching in the wrong room.
assert!(self
.find_event(another_room_id, event_comte.event_id().unwrap().as_ref())
.await
.expect("failed to query for finding an event")
.is_none());
assert!(self
.find_event(room_id, event_gruyere.event_id().unwrap().as_ref())
.await
.expect("failed to query for finding an event")
.is_none());
assert!(
self.find_event(another_room_id, event_comte.event_id().unwrap().as_ref())
.await
.expect("failed to query for finding an event")
.is_none()
);
assert!(
self.find_event(room_id, event_gruyere.event_id().unwrap().as_ref())
.await
.expect("failed to query for finding an event")
.is_none()
);
}
}

Expand All @@ -1155,8 +1174,8 @@ impl EventCacheStoreIntegrationTests for DynEventCacheStore {
/// mod tests {
/// use super::{EventCacheStore, EventCacheStoreResult, MyStore};
///
/// async fn get_event_cache_store(
/// ) -> EventCacheStoreResult<impl EventCacheStore> {
/// async fn get_event_cache_store()
/// -> EventCacheStoreResult<impl EventCacheStore> {
/// Ok(MyStore::new())
/// }
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use ruma::{
};

use super::{
media_service::IgnoreMediaRetentionPolicy, EventCacheStoreMedia, MediaRetentionPolicy,
EventCacheStoreMedia, MediaRetentionPolicy, media_service::IgnoreMediaRetentionPolicy,
};
use crate::media::{MediaFormat, MediaRequestParameters};

Expand Down
Loading
Loading