diff --git a/examples/login.rs b/examples/login.rs index 397766f2..30ac6422 100644 --- a/examples/login.rs +++ b/examples/login.rs @@ -22,7 +22,7 @@ impl EventEmitter for EventCallback { } = event.lock().await.deref() { let rooms = room.lock().await; - let member = rooms.members.get(&sender.to_string()).unwrap(); + let member = rooms.members.get(&sender).unwrap(); println!( "{}: {}", member diff --git a/src/async_client.rs b/src/async_client.rs index 0e5e61e8..0a68f849 100644 --- a/src/async_client.rs +++ b/src/async_client.rs @@ -273,7 +273,7 @@ impl AsyncClient { /// Returns an `Option` of the room name from a `RoomId`. /// /// This is a human readable room name. - pub async fn get_room_name(&self, room_id: &str) -> Option { + pub async fn get_room_name(&self, room_id: &RoomId) -> Option { self.base_client .read() .await @@ -291,7 +291,7 @@ impl AsyncClient { /// Returns the rooms this client knows about. /// /// A `HashMap` of room id to `matrix::models::Room` - pub async fn get_rooms(&self) -> HashMap>> { + pub async fn get_rooms(&self) -> HashMap>> { self.base_client.read().await.joined_rooms.clone() } @@ -354,18 +354,17 @@ impl AsyncClient { let mut response = self.send(request).await?; for (room_id, room) in &mut response.rooms.join { - let room_id_string = room_id.to_string(); let mut client = self.base_client.write().await; let _matrix_room = { for event in &room.state.events { if let EventResult::Ok(e) = event { - client.receive_joined_state_event(&room_id_string, &e).await; + client.receive_joined_state_event(&room_id, &e).await; } } - client.get_or_create_room(&room_id_string).clone() + client.get_or_create_room(&room_id).clone() }; // re looping is not ideal here @@ -395,7 +394,7 @@ impl AsyncClient { for account_data in &mut room.account_data.events { { if let EventResult::Ok(e) = account_data { - client.receive_account_data(&room_id_string, e).await; + client.receive_account_data(&room_id, e).await; client.emit_account_data_event(room_id, e).await; } @@ -410,7 +409,7 @@ impl AsyncClient { for presence in &mut response.presence.events { { if let EventResult::Ok(e) = presence { - client.receive_presence_event(&room_id_string, e).await; + client.receive_presence_event(&room_id, e).await; client.emit_presence_event(room_id, e).await; } diff --git a/src/base_client.rs b/src/base_client.rs index 3b892f7f..e4488c59 100644 --- a/src/base_client.rs +++ b/src/base_client.rs @@ -31,7 +31,7 @@ use crate::events::collections::only::Event as NonRoomEvent; use crate::events::ignored_user_list::IgnoredUserListEvent; use crate::events::push_rules::{PushRulesEvent, Ruleset}; use crate::events::EventResult; -use crate::identifiers::RoomAliasId; +use crate::identifiers::{RoomId, RoomAliasId, UserId}; use crate::models::Room; use crate::session::Session; use crate::EventEmitter; @@ -45,12 +45,10 @@ use ruma_client_api::r0::keys::{ claim_keys::Response as KeysClaimResponse, get_keys::Response as KeysQueryResponse, upload_keys::Response as KeysUploadResponse, DeviceKeys, KeyAlgorithm, }; -use ruma_identifiers::RoomId; #[cfg(feature = "encryption")] -use ruma_identifiers::{DeviceId, UserId as RumaUserId}; +use ruma_identifiers::DeviceId; pub type Token = String; -pub type UserId = String; #[derive(Debug, Default)] /// `RoomName` allows the calculation of a text room name. @@ -74,7 +72,7 @@ pub struct Client { /// The current sync token that should be used for the next sync call. pub sync_token: Option, /// A map of the rooms our user is joined in. - pub joined_rooms: HashMap>>, + pub joined_rooms: HashMap>>, /// A list of ignored users. pub ignored_users: Vec, /// The push ruleset for the logged in user. @@ -167,7 +165,7 @@ impl Client { Ok(()) } - pub(crate) async fn calculate_room_name(&self, room_id: &str) -> Option { + pub(crate) async fn calculate_room_name(&self, room_id: &RoomId) -> Option { if let Some(room) = self.joined_rooms.get(room_id) { let room = room.lock().await; Some(room.room_name.calculate_name(room_id, &room.members)) @@ -185,22 +183,21 @@ impl Client { res } - pub(crate) fn get_or_create_room(&mut self, room_id: &str) -> &mut Arc> { + pub(crate) fn get_or_create_room(&mut self, room_id: &RoomId) -> &mut Arc> { #[allow(clippy::or_fun_call)] self.joined_rooms - .entry(room_id.to_string()) + .entry(room_id.clone()) .or_insert(Arc::new(Mutex::new(Room::new( room_id, &self .session .as_ref() .expect("Receiving events while not being logged in") - .user_id - .to_string(), + .user_id, )))) } - pub(crate) fn get_room(&self, room_id: &str) -> Option<&Arc>> { + pub(crate) fn get_room(&self, room_id: &RoomId) -> Option<&Arc>> { self.joined_rooms.get(room_id) } @@ -208,14 +205,13 @@ impl Client { /// /// Returns true if the room name changed, false otherwise. pub(crate) fn handle_ignored_users(&mut self, event: &IgnoredUserListEvent) -> bool { - // FIXME when UserId becomes more like a &str wrapper in ruma-identifiers - if self.ignored_users + // this avoids cloning every UserId for the eq check + if self.ignored_users.iter().collect::>() == event .content .ignored_users .iter() - .map(|u| u.to_string()) - .collect::>() + .collect::>() { false } else { @@ -223,8 +219,8 @@ impl Client { .content .ignored_users .iter() - .map(|u| u.to_string()) - .collect(); + .cloned() + .collect::>(); true } } @@ -279,7 +275,7 @@ impl Client { } } - let mut room = self.get_or_create_room(&room_id.to_string()).lock().await; + let mut room = self.get_or_create_room(&room_id).lock().await; room.receive_timeline_event(e); decrypted_event } @@ -297,7 +293,7 @@ impl Client { /// * `room_id` - The unique id of the room the event belongs to. /// /// * `event` - The event that should be handled by the client. - pub async fn receive_joined_state_event(&mut self, room_id: &str, event: &StateEvent) -> bool { + pub async fn receive_joined_state_event(&mut self, room_id: &RoomId, event: &StateEvent) -> bool { let mut room = self.get_or_create_room(room_id).lock().await; room.receive_state_event(event) } @@ -312,7 +308,7 @@ impl Client { /// * `room_id` - The unique id of the room the event belongs to. /// /// * `event` - The event that should be handled by the client. - pub async fn receive_presence_event(&mut self, room_id: &str, event: &PresenceEvent) -> bool { + pub async fn receive_presence_event(&mut self, room_id: &RoomId, event: &PresenceEvent) -> bool { // this should be the room that was just created in the `Client::sync` loop. if let Some(room) = self.get_room(room_id) { let mut room = room.lock().await; @@ -332,7 +328,7 @@ impl Client { /// * `room_id` - The unique id of the room the event belongs to. /// /// * `event` - The presence event for a specified room member. - pub async fn receive_account_data(&mut self, room_id: &str, event: &NonRoomEvent) -> bool { + pub async fn receive_account_data(&mut self, room_id: &RoomId, event: &NonRoomEvent) -> bool { match event { NonRoomEvent::IgnoredUserList(iu) => self.handle_ignored_users(iu), NonRoomEvent::Presence(p) => self.receive_presence_event(room_id, p).await, @@ -507,7 +503,7 @@ impl Client { match event { RoomEvent::RoomMember(mem) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_room_member(Arc::clone(&room), Arc::new(Mutex::new(mem.clone()))) @@ -517,7 +513,7 @@ impl Client { } RoomEvent::RoomName(name) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_room_name(Arc::clone(&room), Arc::new(Mutex::new(name.clone()))) @@ -527,7 +523,7 @@ impl Client { } RoomEvent::RoomCanonicalAlias(canonical) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_room_canonical_alias( @@ -540,7 +536,7 @@ impl Client { } RoomEvent::RoomAliases(aliases) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_room_aliases( @@ -553,7 +549,7 @@ impl Client { } RoomEvent::RoomAvatar(avatar) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_room_avatar(Arc::clone(&room), Arc::new(Mutex::new(avatar.clone()))) @@ -563,7 +559,7 @@ impl Client { } RoomEvent::RoomMessage(msg) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_room_message(Arc::clone(&room), Arc::new(Mutex::new(msg.clone()))) @@ -573,7 +569,7 @@ impl Client { } RoomEvent::RoomMessageFeedback(msg_feedback) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_room_message_feedback( @@ -586,7 +582,7 @@ impl Client { } RoomEvent::RoomRedaction(redaction) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_room_redaction( @@ -599,7 +595,7 @@ impl Client { } RoomEvent::RoomPowerLevels(power) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_room_power_levels( @@ -618,7 +614,7 @@ impl Client { match event { StateEvent::RoomMember(member) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_state_member( @@ -631,7 +627,7 @@ impl Client { } StateEvent::RoomName(name) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_state_name(Arc::clone(&room), Arc::new(Mutex::new(name.clone()))) @@ -641,7 +637,7 @@ impl Client { } StateEvent::RoomCanonicalAlias(canonical) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_state_canonical_alias( @@ -654,7 +650,7 @@ impl Client { } StateEvent::RoomAliases(aliases) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_state_aliases( @@ -667,7 +663,7 @@ impl Client { } StateEvent::RoomAvatar(avatar) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_state_avatar( @@ -680,7 +676,7 @@ impl Client { } StateEvent::RoomPowerLevels(power) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_state_power_levels( @@ -693,7 +689,7 @@ impl Client { } StateEvent::RoomJoinRules(rules) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_state_join_rules( @@ -716,7 +712,7 @@ impl Client { match event { NonRoomEvent::Presence(presence) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_account_presence( @@ -729,7 +725,7 @@ impl Client { } NonRoomEvent::IgnoredUserList(ignored) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_account_ignored_users( @@ -742,7 +738,7 @@ impl Client { } NonRoomEvent::PushRules(rules) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_account_push_rules( @@ -755,7 +751,7 @@ impl Client { } NonRoomEvent::FullyRead(full_read) => { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_account_data_fully_read( @@ -776,7 +772,7 @@ impl Client { event: &mut PresenceEvent, ) { if let Some(ee) = &self.event_emitter { - if let Some(room) = self.get_room(&room_id.to_string()) { + if let Some(room) = self.get_room(&room_id) { ee.lock() .await .on_presence_event(Arc::clone(&room), Arc::new(Mutex::new(event.clone()))) diff --git a/src/models/room.rs b/src/models/room.rs index 222f720b..162325b2 100644 --- a/src/models/room.rs +++ b/src/models/room.rs @@ -14,8 +14,9 @@ // limitations under the License. use std::collections::HashMap; +use std::convert::TryFrom; -use super::{RoomMember, UserId}; +use super::RoomMember; use crate::events::collections::all::{RoomEvent, StateEvent}; use crate::events::presence::PresenceEvent; @@ -27,7 +28,7 @@ use crate::events::room::{ name::NameEvent, power_levels::PowerLevelsEvent, }; -use crate::identifiers::RoomAliasId; +use crate::identifiers::{RoomId, RoomAliasId, UserId}; use js_int::UInt; @@ -46,7 +47,7 @@ pub struct RoomName { /// A Matrix rooom. pub struct Room { /// The unique id of the room. - pub room_id: String, + pub room_id: RoomId, /// The name of the room, clients use this to represent a room. pub room_name: RoomName, /// The mxid of our own user. @@ -82,7 +83,7 @@ impl RoomName { true } - pub fn calculate_name(&self, room_id: &str, members: &HashMap) -> String { + pub fn calculate_name(&self, room_id: &RoomId, members: &HashMap) -> String { // https://matrix.org/docs/spec/client_server/latest#calculating-the-display-name-for-a-room. // the order in which we check for a name ^^ if let Some(name) = &self.name { @@ -118,11 +119,11 @@ impl Room { /// * `room_id` - The unique id of the room. /// /// * `own_user_id` - The mxid of our own user. - pub fn new(room_id: &str, own_user_id: &str) -> Self { + pub fn new(room_id: &RoomId, own_user_id: &UserId) -> Self { Room { - room_id: room_id.to_string(), + room_id: room_id.clone(), room_name: RoomName::default(), - own_user_id: own_user_id.to_owned(), + own_user_id: own_user_id.clone(), creator: None, members: HashMap::new(), typing_users: Vec::new(), @@ -143,19 +144,19 @@ impl Room { } fn add_member(&mut self, event: &MemberEvent) -> bool { - if self.members.contains_key(&event.state_key) { + if self.members.contains_key(&UserId::try_from(event.state_key.as_str()).unwrap()) { return false; } let member = RoomMember::new(event); - self.members.insert(event.state_key.clone(), member); + self.members.insert(UserId::try_from(event.state_key.as_str()).unwrap(), member); true } /// Add to the list of `RoomAliasId`s. - fn room_aliases(&mut self, alias: &RoomAliasId) -> bool { + fn push_room_alias(&mut self, alias: &RoomAliasId) -> bool { self.room_name.push_alias(alias.clone()); true } @@ -166,7 +167,7 @@ impl Room { true } - fn name_room(&mut self, name: &str) -> bool { + fn set_name_room(&mut self, name: &str) -> bool { self.room_name.set_name(name); true } @@ -178,7 +179,7 @@ impl Room { match event.membership_change() { MembershipChange::Invited | MembershipChange::Joined => self.add_member(event), _ => { - if let Some(member) = self.members.get_mut(&event.state_key) { + if let Some(member) = self.members.get_mut(&UserId::try_from(event.state_key.as_str()).unwrap()) { member.update_member(event) } else { false @@ -192,8 +193,8 @@ impl Room { /// Returns true if the room name changed, false otherwise. pub fn handle_room_aliases(&mut self, event: &AliasesEvent) -> bool { match event.content.aliases.as_slice() { - [alias] => self.room_aliases(alias), - [alias, ..] => self.room_aliases(alias), + [alias] => self.push_room_alias(alias), + [alias, ..] => self.push_room_alias(alias), _ => false, } } @@ -213,7 +214,7 @@ impl Room { /// Returns true if the room name changed, false otherwise. pub fn handle_room_name(&mut self, event: &NameEvent) -> bool { match event.content.name() { - Some(name) => self.name_room(name), + Some(name) => self.set_name_room(name), _ => false, } } @@ -222,7 +223,7 @@ impl Room { /// /// Returns true if the room name changed, false otherwise. pub fn handle_power_level(&mut self, event: &PowerLevelsEvent) -> bool { - if let Some(member) = self.members.get_mut(&event.state_key) { + if let Some(member) = self.members.get_mut(&UserId::try_from(event.state_key.as_str()).unwrap()) { member.update_power(event) } else { false @@ -285,7 +286,7 @@ impl Room { pub fn receive_presence_event(&mut self, event: &PresenceEvent) -> bool { if let Some(user) = self .members - .get_mut(&event.sender.to_string()) + .get_mut(&event.sender) .map(|m| &mut m.user) { if user.did_update_presence(event) { @@ -304,6 +305,7 @@ impl Room { #[cfg(test)] mod test { + use super::*; use crate::events::room::member::MembershipState; use crate::identifiers::UserId; use crate::{AsyncClient, Session, SyncSettings}; @@ -341,7 +343,7 @@ mod test { let rooms = &client.base_client.read().await.joined_rooms; let room = &rooms - .get("!SVkFJHzfwvuaIEawgC:localhost") + .get(&RoomId::try_from("!SVkFJHzfwvuaIEawgC:localhost").unwrap()) .unwrap() .lock() .await; diff --git a/src/models/room_member.rs b/src/models/room_member.rs index ad93b342..69efcab5 100644 --- a/src/models/room_member.rs +++ b/src/models/room_member.rs @@ -160,7 +160,7 @@ mod test { let mut rooms = client.base_client.write().await.joined_rooms.clone(); let mut room = rooms - .get_mut("!SVkFJHzfwvuaIEawgC:localhost") + .get_mut(&RoomId::try_from("!SVkFJHzfwvuaIEawgC:localhost").unwrap()) .unwrap() .lock() .await; diff --git a/tests/async_client_tests.rs b/tests/async_client_tests.rs index cec0b25b..4feb53c6 100644 --- a/tests/async_client_tests.rs +++ b/tests/async_client_tests.rs @@ -1,4 +1,4 @@ -use matrix_sdk::identifiers::UserId; +use matrix_sdk::identifiers::{RoomId, UserId}; use matrix_sdk::{AsyncClient, Session, SyncSettings}; use mockito::{mock, Matcher}; @@ -84,6 +84,6 @@ async fn room_names() { assert_eq!(vec!["tutorial"], client.get_room_names().await); assert_eq!( Some("tutorial".into()), - client.get_room_name("!SVkFJHzfwvuaIEawgC:localhost").await + client.get_room_name(&RoomId::try_from("!SVkFJHzfwvuaIEawgC:localhost").unwrap()).await ); }