Browse Source

Wrap RoomState in RoomEntry inside map.

main
Titouan Rigoudy 2 years ago
parent
commit
a30c2c0fa8
5 changed files with 62 additions and 40 deletions
  1. +2
    -2
      client/src/client.rs
  2. +2
    -1
      client/src/handlers/room_join_request_handler.rs
  3. +1
    -1
      client/src/handlers/room_join_response_handler.rs
  4. +2
    -2
      client/src/handlers/room_message_response_handler.rs
  5. +55
    -34
      client/src/room/map.rs

+ 2
- 2
client/src/client.rs View File

@ -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 {


+ 2
- 1
client/src/handlers/room_join_request_handler.rs View File

@ -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
);


+ 1
- 1
client/src/handlers/room_join_response_handler.rs View File

@ -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


+ 2
- 2
client/src/handlers/room_message_response_handler.rs View File

@ -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),


+ 55
- 34
client/src/room/map.rs View File

@ -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<String, RoomState>,
map: HashMap<String, RoomEntry>,
}
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<RoomState> {
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<String, RoomState>,
old_map: &mut HashMap<String, RoomEntry>,
) {
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<String>,
mut operators: Vec<String>,
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)
);
}
}

Loading…
Cancel
Save