diff --git a/client/src/dispatcher.rs b/client/src/dispatcher.rs index 3b544fc..5d10e03 100644 --- a/client/src/dispatcher.rs +++ b/client/src/dispatcher.rs @@ -9,8 +9,8 @@ use crate::context::Context; use crate::control::Request as ControlRequest; use crate::executor::Job; use crate::handlers::{ - RoomListRequestHandler, RoomMessageRequestHandler, SetPrivilegedUsersHandler, - SetRoomListHandler, + RoomJoinRequestHandler, RoomJoinResponseHandler, RoomListRequestHandler, + RoomMessageRequestHandler, SetPrivilegedUsersHandler, SetRoomListHandler, }; use crate::message_handler::MessageHandler; @@ -75,6 +75,12 @@ impl Dispatcher { message: response, handler: SetPrivilegedUsersHandler::default(), })), + Message::ServerResponse(ServerResponse::RoomJoinResponse(response)) => { + Some(Box::new(DispatchedMessage { + message: response, + handler: RoomJoinResponseHandler::default(), + })) + } Message::ServerResponse(ServerResponse::RoomListResponse(response)) => { Some(Box::new(DispatchedMessage { message: response, @@ -97,6 +103,12 @@ impl Dispatcher { handler: RoomMessageRequestHandler::default(), })) } + Message::ControlRequest(ControlRequest::RoomJoinRequest(room_name)) => { + Some(Box::new(DispatchedMessage { + message: room_name, + handler: RoomJoinRequestHandler::default(), + })) + } Message::ControlRequest(request) => { warn!("Unhandled control request: {:?}", request); None @@ -110,7 +122,7 @@ mod tests { use crate::control; use crate::dispatcher::Message; - use solstice_proto::server::{self, ServerResponse}; + use solstice_proto::server; use super::*; @@ -138,6 +150,21 @@ mod tests { .is_some()); } + #[test] + fn dispatches_room_join_response() { + assert!(Dispatcher::new() + .dispatch(Message::ServerResponse( + server::RoomJoinResponse { + room_name: "bleep".to_string(), + owner: None, + operators: Vec::new(), + users: Vec::new(), + } + .into() + )) + .is_some()); + } + #[test] fn dispatches_room_list_response() { assert!(Dispatcher::new() @@ -153,6 +180,15 @@ mod tests { .is_some()); } + #[test] + fn dispatches_room_join_request() { + assert!(Dispatcher::new() + .dispatch(Message::ControlRequest( + control::Request::RoomJoinRequest("bleep".to_string()).into() + )) + .is_some()); + } + #[test] fn dispatches_room_message_request() { assert!(Dispatcher::new() diff --git a/client/src/handlers/mod.rs b/client/src/handlers/mod.rs index f22b17a..4fbec5e 100644 --- a/client/src/handlers/mod.rs +++ b/client/src/handlers/mod.rs @@ -1,10 +1,12 @@ mod room_join_request_handler; +mod room_join_response_handler; mod room_list_request_handler; mod room_message_request_handler; mod set_privileged_users_handler; mod set_room_list_handler; pub use room_join_request_handler::RoomJoinRequestHandler; +pub use room_join_response_handler::RoomJoinResponseHandler; pub use room_list_request_handler::RoomListRequestHandler; pub use room_message_request_handler::RoomMessageRequestHandler; pub use set_privileged_users_handler::SetPrivilegedUsersHandler; diff --git a/client/src/handlers/room_join_response_handler.rs b/client/src/handlers/room_join_response_handler.rs new file mode 100644 index 0000000..7965009 --- /dev/null +++ b/client/src/handlers/room_join_response_handler.rs @@ -0,0 +1,93 @@ +use anyhow::Context as AnyhowContext; +use solstice_proto::server::RoomJoinResponse; + +use crate::context::Context; +use crate::control; +use crate::message_handler::MessageHandler; + +#[derive(Debug, Default)] +pub struct RoomJoinResponseHandler; + +impl MessageHandler for RoomJoinResponseHandler { + type Message = RoomJoinResponse; + + fn run( + self, + context: &Context, + response: &RoomJoinResponse, + ) -> anyhow::Result<()> { + { + let mut guard = context.state.lock(); + let _room = guard + .rooms + .join( + &response.room_name, + response.owner.clone(), + response.operators.clone(), + &response.users, + ) + .context("joining room")?; + + // Send under lock to avoid out-of-order sends. + let control_response = + control::Response::RoomJoinResponse(control::RoomJoinResponse { + room_name: response.room_name.clone(), + }); + + context + .control_response_tx + .blocking_send(control_response) + .context("sending control response")?; + } + Ok(()) + } + + fn name() -> String { + "RoomJoinResponseHandler".to_string() + } +} + +#[cfg(test)] +mod tests { + /* + use solstice_proto::server::RoomJoinResponse; + + use crate::context::ContextBundle; + use crate::message_handler::MessageHandler; + use crate::room::{Room, Visibility}; + + use super::RoomJoinResponseHandler; + + // Cannot get the compiler to be satisfied when borrowing the name... + fn room_name(pair: &(String, Room)) -> String { + pair.0.clone() + } + + #[test] + fn run_sets_room_list() { + let bundle = ContextBundle::default(); + + let response = RoomJoinResponse { + rooms: vec![("potato".to_string(), 123), ("apple".to_string(), 42)], + owned_private_rooms: vec![], + other_private_rooms: vec![], + operated_private_room_names: vec![], + }; + + RoomJoinResponseHandler::default() + .run(&bundle.context, &response) + .unwrap(); + + let mut rooms = bundle.context.state.lock().rooms.get_room_list(); + rooms.sort_by_key(room_name); + + assert_eq!( + rooms, + vec![ + ("apple".to_string(), Room::new(Visibility::Public, 42)), + ("potato".to_string(), Room::new(Visibility::Public, 123)), + ] + ); + } + */ +} diff --git a/client/src/room.rs b/client/src/room.rs index 8746f1b..96d75cc 100644 --- a/client/src/room.rs +++ b/client/src/room.rs @@ -238,7 +238,7 @@ impl RoomMap { owner: Option, mut operators: Vec, members: &[User], - ) -> Result<(), Error> { + ) -> Result<&Room, Error> { // First look up the room struct. let room = self.get_mut_strict(room_name)?; @@ -267,7 +267,7 @@ impl RoomMap { room.members.insert(user.name.clone()); } - Ok(()) + Ok(room) } /// Records that we are now trying to leave the given room.