From 68161b2f8b2500a6c1deccc1a55424ea01271f2e Mon Sep 17 00:00:00 2001 From: Titouan Rigoudy Date: Sun, 11 Dec 2022 22:11:51 +0000 Subject: [PATCH] Introduce generic EventHandler trait. --- client/src/control/listener.rs | 4 ++-- client/src/dispatcher.rs | 26 +++------------------- client/src/event.rs | 40 ++++++++++++++++++++++++++++++++++ client/src/main.rs | 5 +++-- client/src/room/event.rs | 31 +++++++++++--------------- 5 files changed, 61 insertions(+), 45 deletions(-) create mode 100644 client/src/event.rs diff --git a/client/src/control/listener.rs b/client/src/control/listener.rs index ab1eb25..13e8eed 100644 --- a/client/src/control/listener.rs +++ b/client/src/control/listener.rs @@ -13,7 +13,7 @@ use tokio_tungstenite::WebSocketStream; use crate::control::request::*; use crate::control::response::*; -use crate::dispatcher::Message; +use crate::event::Message; async fn forward_incoming( mut incoming: SplitStream>, @@ -185,7 +185,7 @@ mod tests { use tokio_tungstenite::tungstenite::Message as WebSocketMessage; use crate::control::{Request, Response, RoomLeaveResponse}; - use crate::dispatcher::Message; + use crate::event::Message; // A bound `Listener` packaged with the channels it needs to run. // Convenient for tests. diff --git a/client/src/dispatcher.rs b/client/src/dispatcher.rs index eabaf9b..7bf3584 100644 --- a/client/src/dispatcher.rs +++ b/client/src/dispatcher.rs @@ -1,38 +1,18 @@ //! This module defines the central message dispatcher to the client process. -use std::fmt::Debug; - use log::{error, warn}; use solstice_proto::server::ServerResponse; use crate::context::Context; use crate::control::Request as ControlRequest; +use crate::event::{Message, EventHandler}; use crate::handlers::*; use crate::message_handler::MessageHandler; -use crate::room::{HandleRoomEvent, RoomEvent, RoomEventHandler}; - -/// The type of messages dispatched by a dispatcher. -#[derive(Debug, Eq, PartialEq)] -pub enum Message { - ControlRequest(ControlRequest), - ServerResponse(ServerResponse), -} - -impl From for Message { - fn from(response: ServerResponse) -> Self { - Self::ServerResponse(response) - } -} - -impl From for Message { - fn from(request: ControlRequest) -> Self { - Self::ControlRequest(request) - } -} +use crate::room::{RoomEvent, RoomEventHandler}; /// Subsystem event handlers to which the `Dispatcher` dispatches events. pub trait DispatcherHandlers { - type RoomEventHandler: HandleRoomEvent; + type RoomEventHandler: EventHandler; fn room_event_handler(&mut self) -> &mut Self::RoomEventHandler; } diff --git a/client/src/event.rs b/client/src/event.rs new file mode 100644 index 0000000..ff8c3f0 --- /dev/null +++ b/client/src/event.rs @@ -0,0 +1,40 @@ +//! Defines the root event model for the client application. + +use solstice_proto::ServerResponse; + +use crate::context::Context; +use crate::control; + +// TODO: Rename to `Event`. +/// The type of messages dispatched by a dispatcher. +#[derive(Debug, Eq, PartialEq)] +pub enum Message { + ControlRequest(control::Request), + ServerResponse(ServerResponse), +} + +impl From for Message { + fn from(response: ServerResponse) -> Self { + Self::ServerResponse(response) + } +} + +impl From for Message { + fn from(request: control::Request) -> Self { + Self::ControlRequest(request) + } +} + +/// An interface for event handlers. +/// +/// Allows mocking of handlers in tests. +pub trait EventHandler { + type Event; + + /// Handles the given `event` against the given global `context`. + fn handle( + &mut self, + context: &mut Context, + event: Self::Event, + ) -> anyhow::Result<()>; +} diff --git a/client/src/main.rs b/client/src/main.rs index ebcba79..cf6dbb8 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -13,6 +13,7 @@ mod config; mod context; mod control; mod dispatcher; +mod event; mod handlers; mod login; mod message_handler; @@ -43,7 +44,7 @@ fn old_main(config: Config) { async fn run_client( config: Config, request_rx: mpsc::Receiver, - dispatcher_tx: mpsc::Sender, + dispatcher_tx: mpsc::Sender, ) -> anyhow::Result<()> { info!("Connecting to server at {}.", config.server_address); let stream = TcpStream::connect(&config.server_address) @@ -62,7 +63,7 @@ async fn run_client( let forwarder_task = tokio::spawn(async move { while let Some(response) = response_rx.recv().await { dispatcher_tx - .send(dispatcher::Message::ServerResponse(response)) + .send(event::Message::ServerResponse(response)) .await .expect("dispatcher channel closed"); } diff --git a/client/src/room/event.rs b/client/src/room/event.rs index 9180677..fef0db9 100644 --- a/client/src/room/event.rs +++ b/client/src/room/event.rs @@ -7,6 +7,7 @@ use solstice_proto::ServerRequest; use crate::context::Context; use crate::control; +use crate::event::EventHandler; use crate::room::RoomMessage; /// An event affecting the chat room module. @@ -20,19 +21,7 @@ pub enum RoomEvent { MessageResponse(server::RoomMessageResponse), } -/// An interface for room event handlers. -/// -/// Allows mocking of handlers in tests. -pub trait HandleRoomEvent { - /// Handles the given `event` against the given global `context`. - fn handle( - &mut self, - context: &mut Context, - event: RoomEvent, - ) -> anyhow::Result<()>; -} - -/// The real, default implementation of `HandleRoomEvent`. +/// The real, default room event handler. #[derive(Default)] pub struct RoomEventHandler; @@ -168,7 +157,9 @@ fn handle_message_response( .context("sending control response") } -impl HandleRoomEvent for RoomEventHandler { +impl EventHandler for RoomEventHandler { + type Event = RoomEvent; + fn handle( &mut self, context: &mut Context, @@ -199,19 +190,22 @@ impl HandleRoomEvent for RoomEventHandler { #[cfg(test)] pub mod testing { use crate::context::Context; + use crate::event::EventHandler; - use super::{HandleRoomEvent, RoomEvent}; + use super::RoomEvent; #[derive(Default)] pub struct FakeRoomEventHandler { pub events: Vec, } - impl HandleRoomEvent for FakeRoomEventHandler { + impl EventHandler for FakeRoomEventHandler { + type Event = RoomEvent; + fn handle( &mut self, _context: &mut Context, - event: RoomEvent, + event: Self::Event, ) -> anyhow::Result<()> { self.events.push(event); Ok(()) @@ -229,9 +223,10 @@ mod tests { use crate::clock::SimulatedSystemClock; use crate::context::{ContextBundle, ContextOptions}; use crate::control; + use crate::event::EventHandler; use crate::room::{RoomMembership, RoomMessage, RoomState, RoomVisibility}; - use super::{HandleRoomEvent, RoomEvent, RoomEventHandler}; + use super::{RoomEvent, RoomEventHandler}; #[test] fn handle_join_request_failure() {