From a30c2c0fa89978d3259f93cbfb8c74669d74312d Mon Sep 17 00:00:00 2001 From: Titouan Rigoudy Date: Wed, 30 Nov 2022 21:06:28 +0000 Subject: [PATCH] Wrap RoomState in RoomEntry inside map. --- client/src/client.rs | 4 +- .../src/handlers/room_join_request_handler.rs | 3 +- .../handlers/room_join_response_handler.rs | 2 +- .../handlers/room_message_response_handler.rs | 4 +- client/src/room/map.rs | 89 ++++++++++++------- 5 files changed, 62 insertions(+), 40 deletions(-) diff --git a/client/src/client.rs b/client/src/client.rs index 2474307..705f48c 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -569,7 +569,7 @@ impl Client { let control_response = control::RoomJoinResponse { room_name: response.room_name, - room: room.clone(), + room: room.clone_state(), }; self.send_to_controller(control::Response::RoomJoinResponse( control_response, @@ -619,7 +619,7 @@ impl Client { message: response.message.clone(), }; - room.messages.insert(message.clone()); + room.insert_message(message.clone()); self.send_to_controller(control::Response::RoomMessageResponse( control::RoomMessageResponse { diff --git a/client/src/handlers/room_join_request_handler.rs b/client/src/handlers/room_join_request_handler.rs index 7e19cf9..e6b0bc4 100644 --- a/client/src/handlers/room_join_request_handler.rs +++ b/client/src/handlers/room_join_request_handler.rs @@ -29,7 +29,7 @@ fn start_joining( let response = control::Response::RoomJoinResponse(control::RoomJoinResponse { room_name: room_name.to_string(), - room: room.clone(), + room: room.clone_state(), }); if let Err(err) = context.control_response_tx.blocking_send(response) { @@ -155,6 +155,7 @@ mod tests { .rooms .get_strict("bleep") .context("getting room")? + .clone_state() .membership, RoomMembership::Joining ); diff --git a/client/src/handlers/room_join_response_handler.rs b/client/src/handlers/room_join_response_handler.rs index 0c74331..3e23dfa 100644 --- a/client/src/handlers/room_join_response_handler.rs +++ b/client/src/handlers/room_join_response_handler.rs @@ -32,7 +32,7 @@ impl MessageHandler for RoomJoinResponseHandler { let control_response = control::Response::RoomJoinResponse(control::RoomJoinResponse { room_name: response.room_name.clone(), - room: room.clone(), + room: room.clone_state(), }); context diff --git a/client/src/handlers/room_message_response_handler.rs b/client/src/handlers/room_message_response_handler.rs index 5cd4b49..5347e8d 100644 --- a/client/src/handlers/room_message_response_handler.rs +++ b/client/src/handlers/room_message_response_handler.rs @@ -29,7 +29,7 @@ impl MessageHandler for RoomMessageResponseHandler { message: response.message.clone(), }; - room.messages.insert(message.clone()); + room.insert_message(message.clone()); context .control_response_tx @@ -145,7 +145,7 @@ mod tests { .expect("looking up room"); assert_eq!( - room.messages.to_vec(), + room.clone_state().messages.to_vec(), vec![ RoomMessage { received_at: system_time_from_secs(42), diff --git a/client/src/room/map.rs b/client/src/room/map.rs index ea76811..5b37b0b 100644 --- a/client/src/room/map.rs +++ b/client/src/room/map.rs @@ -5,7 +5,7 @@ use log::{error, info, warn}; use solstice_proto::{server, User}; use thiserror::Error; -use crate::room::{RoomMembership, RoomState, RoomVisibility}; +use crate::room::{RoomMembership, RoomMessage, RoomState, RoomVisibility}; /// The error returned by RoomMap functions. #[derive(Debug, Error)] @@ -21,12 +21,30 @@ pub enum RoomError { #[error("room {0} not found")] pub struct RoomNotFoundError(String); +/// An entry in the chat room map. +#[derive(Debug)] +pub struct RoomEntry { + state: RoomState, +} + +impl RoomEntry { + /// Returns a copy of the room state contained in this entry. + pub fn clone_state(&self) -> RoomState { + self.state.clone() + } + + /// Inserts the given message in this chat room's history. + pub fn insert_message(&mut self, message: RoomMessage) { + self.state.messages.insert(message) + } +} + /// Contains the mapping from room names to room data and provides a clean /// interface to interact with it. #[derive(Debug, Default)] pub struct RoomMap { /// The actual map from room names to room data. - map: HashMap, + map: HashMap, } impl RoomMap { @@ -38,7 +56,10 @@ impl RoomMap { /// Inserts the given room in the map under the given name. /// Same semantics as `std::collections::HashMap::insert()`. pub fn insert(&mut self, name: String, room: RoomState) -> Option { - self.map.insert(name, room) + self + .map + .insert(name, RoomEntry { state: room }) + .map(|entry| entry.state) } /// Looks up the given room name in the map, returning an immutable @@ -46,7 +67,7 @@ impl RoomMap { pub fn get_strict( &self, room_name: &str, - ) -> Result<&RoomState, RoomNotFoundError> { + ) -> Result<&RoomEntry, RoomNotFoundError> { match self.map.get(room_name) { Some(room) => Ok(room), None => Err(RoomNotFoundError(room_name.to_string())), @@ -58,7 +79,7 @@ impl RoomMap { pub fn get_mut_strict( &mut self, room_name: &str, - ) -> Result<&mut RoomState, RoomNotFoundError> { + ) -> Result<&mut RoomEntry, RoomNotFoundError> { match self.map.get_mut(room_name) { Some(room) => Ok(room), None => Err(RoomNotFoundError(room_name.to_string())), @@ -72,14 +93,14 @@ impl RoomMap { name: String, visibility: RoomVisibility, user_count: u32, - old_map: &mut HashMap, + old_map: &mut HashMap, ) { let room = match old_map.remove(&name) { None => RoomState::new(RoomVisibility::Public, user_count as usize), - Some(mut room) => { - room.visibility = visibility; - room.user_count = user_count as usize; - room + Some(RoomEntry { mut state }) => { + state.visibility = visibility; + state.user_count = user_count as usize; + state } }; if let Some(_) = self.insert(name, room) { @@ -121,7 +142,7 @@ impl RoomMap { // Mark all operated rooms as necessary. for name in response.operated_private_room_names.iter() { match self.map.get_mut(name) { - Some(room) => room.operated = true, + Some(room) => room.state.operated = true, None => error!("Room {} is operated but does not exist", name), } } @@ -131,7 +152,7 @@ impl RoomMap { pub fn get_room_list(&self) -> Vec<(String, RoomState)> { let mut rooms = Vec::new(); for (room_name, room) in self.map.iter() { - rooms.push((room_name.clone(), room.clone())); + rooms.push((room_name.clone(), room.clone_state())); } rooms } @@ -142,9 +163,9 @@ impl RoomMap { pub fn start_joining(&mut self, room_name: &str) -> Result<(), RoomError> { let room = self.get_mut_strict(room_name)?; - match room.membership { + match room.state.membership { RoomMembership::NonMember => { - room.membership = RoomMembership::Joining; + room.state.membership = RoomMembership::Joining; Ok(()) } @@ -163,33 +184,33 @@ impl RoomMap { owner: Option, mut operators: Vec, members: &[User], - ) -> Result<&RoomState, RoomError> { + ) -> Result<&RoomEntry, RoomError> { // First look up the room struct. let room = self.get_mut_strict(room_name)?; // Log what's happening. - if let RoomMembership::Joining = room.membership { + if let RoomMembership::Joining = room.state.membership { info!("Joined room {:?}", room_name); } else { warn!( "Joined room {:?} but membership was already {:?}", - room_name, room.membership + room_name, room.state.membership ); } - // Update the room struct. - room.membership = RoomMembership::Member; - room.user_count = members.len(); - room.owner = owner; + // Update the room state. + room.state.membership = RoomMembership::Member; + room.state.user_count = members.len(); + room.state.owner = owner; - room.operators.clear(); + room.state.operators.clear(); for user_name in operators.drain(..) { - room.operators.insert(user_name); + room.state.operators.insert(user_name); } - room.members.clear(); + room.state.members.clear(); for user in members { - room.members.insert(user.name.clone()); + room.state.members.insert(user.name.clone()); } Ok(room) @@ -202,9 +223,9 @@ impl RoomMap { pub fn start_leaving(&mut self, room_name: &str) -> Result<(), RoomError> { let room = self.get_mut_strict(room_name)?; - match room.membership { + match room.state.membership { RoomMembership::Member => { - room.membership = RoomMembership::Leaving; + room.state.membership = RoomMembership::Leaving; Ok(()) } @@ -219,7 +240,7 @@ impl RoomMap { pub fn leave(&mut self, room_name: &str) -> Result<(), RoomError> { let room = self.get_mut_strict(room_name)?; - match room.membership { + match room.state.membership { RoomMembership::Leaving => info!("Left room {:?}", room_name), membership => warn!( @@ -228,7 +249,7 @@ impl RoomMap { ), } - room.membership = RoomMembership::NonMember; + room.state.membership = RoomMembership::NonMember; Ok(()) } @@ -240,7 +261,7 @@ impl RoomMap { user_name: String, ) -> Result<(), RoomError> { let room = self.get_mut_strict(room_name)?; - room.members.insert(user_name); + room.state.members.insert(user_name); Ok(()) } @@ -252,7 +273,7 @@ impl RoomMap { user_name: &str, ) -> Result<(), RoomError> { let room = self.get_mut_strict(room_name)?; - room.members.remove(user_name); + room.state.members.remove(user_name); Ok(()) } @@ -266,7 +287,7 @@ impl RoomMap { tickers: Vec<(String, String)>, ) -> Result<(), RoomError> { let room = self.get_mut_strict(room_name)?; - room.tickers = tickers; + room.state.tickers = tickers; Ok(()) } } @@ -295,8 +316,8 @@ mod tests { }); assert_eq!( - rooms.get_strict("room a").unwrap(), - &RoomState::new(RoomVisibility::Public, 42) + rooms.get_strict("room a").unwrap().clone_state(), + RoomState::new(RoomVisibility::Public, 42) ); } }