flare_im_core/server/
handlers.rs1use flare_core::context::AppContext;
2use flare_core::error::{FlareErr, Result};
3use async_trait::async_trait;
4use log::debug;
5use flare_core::flare_net::net::{Command, ResCode, Response};
6
7use crate::server::auth_handler::{AuthCommandHandler, AuthHandler};
8use crate::server::server::ConnectionInfo;
9use crate::server::server_handler::{ ServerCommandHandler, ServerHandler};
10use crate::server::sys_handler::{SystemCommandHandler, SystemHandler};
11
12#[async_trait]
14pub trait CommandHandler: Send + Sync {
15 async fn handle_command(&self, ctx: &AppContext) -> Result<Response>;
17
18 fn supported_commands(&self) -> Vec<Command>;
20
21 fn supports_command(&self, command: Command) -> bool {
23 self.supported_commands().contains(&command)
24 }
25}
26
27pub struct ServerMessageHandler<S, A, Y>
29where
30 S: ServerHandler,
31 A: AuthHandler,
32 Y: SystemHandler,
33{
34 auth_handler: AuthCommandHandler<A>,
35 server_handler: ServerCommandHandler<S>,
36 system_handler: SystemCommandHandler<Y>,
37}
38
39impl<S, A, Y> ServerMessageHandler<S, A, Y>
40where
41 S: ServerHandler,
42 A: AuthHandler,
43 Y: SystemHandler,
44{
45 pub fn new(
46 auth_handler: AuthCommandHandler<A>,
47 server_handler: ServerCommandHandler<S>,
48 system_handler: SystemCommandHandler<Y>,
49 ) -> Self {
50 Self {
51 auth_handler,
52 server_handler,
53 system_handler,
54 }
55 }
56
57 fn get_handler(&self, command: Command) -> Result<&dyn CommandHandler> {
59 if self.auth_handler.supports_command(command) {
60 Ok(&self.auth_handler)
61 } else if self.server_handler.supports_command(command) {
62 Ok(&self.server_handler)
63 } else if self.system_handler.supports_command(command) {
64 Ok(&self.system_handler)
65 } else {
66 Err(FlareErr::invalid_command(format!(
67 "No handler found for command: {:?}",
68 command
69 )))
70 }
71 }
72 pub async fn handle_new_connection(&self, ctx: &AppContext, conn: &ConnectionInfo) -> Result<Response> {
74 self.system_handler.handle_new_connection(ctx, conn).await
75 }
76 pub async fn handle_auth(&self, ctx: &AppContext) -> Result<Response> {
78 self.auth_handler.handle_login(ctx).await
79 }
80
81}
82
83#[async_trait]
84impl<S, A, Y> CommandHandler for ServerMessageHandler<S, A, Y>
85where
86 S: ServerHandler + Send + Sync + 'static,
87 A: AuthHandler + Send + Sync + 'static,
88 Y: SystemHandler + Send + Sync + 'static,
89{
90 async fn handle_command(&self, ctx: &AppContext) -> Result<Response> {
91 let command = ctx.command().ok_or_else(||
92 FlareErr::invalid_command("Missing command"))?;
93
94 debug!("Handling command: {:?}", command);
95
96 match command {
98 Command::Ping => Ok(Response {
99 code: ResCode::Success as i32,
100 message: "PONG".into(),
101 data: Vec::new(),
102 }),
103 Command::Pong => Ok(Response {
104 code: ResCode::Success as i32,
105 message: "PING received".into(),
106 data: Vec::new(),
107 }),
108 _ => {
109 let handler = self.get_handler(command)?;
111 handler.handle_command(ctx).await
112 }
113 }
114 }
115
116 fn supported_commands(&self) -> Vec<Command> {
117 let mut commands = Vec::new();
118 commands.extend(self.auth_handler.supported_commands());
119 commands.extend(self.server_handler.supported_commands());
120 commands.extend(self.system_handler.supported_commands());
121 commands.push(Command::Ping);
122 commands.push(Command::Pong);
123 commands
124 }
125}
126
127impl<S, A, Y> Default for ServerMessageHandler<S, A, Y>
128where
129 S: ServerHandler + Default + Send + Sync + 'static,
130 A: AuthHandler + Default + Send + Sync + 'static,
131 Y: SystemHandler + Default + Send + Sync + 'static,
132{
133 fn default() -> Self {
134 Self::new(
135 AuthCommandHandler::new(A::default()),
136 ServerCommandHandler::new(S::default()),
137 SystemCommandHandler::new(Y::default())
138 )
139 }
140}
141
142#[cfg(test)]
143mod tests {
144 use super::*;
145 use crate::server::auth_handler::DefAuthHandler;
146 use crate::server::server_handler::DefServerHandler;
147 use crate::server::sys_handler::DefSystemHandler;
148 #[tokio::test]
149 async fn test_message_handler() {
150 let handler = ServerMessageHandler::<DefServerHandler, DefAuthHandler, DefSystemHandler>::default();
151
152 let commands = handler.supported_commands();
154 assert!(commands.contains(&Command::Login));
155 assert!(commands.contains(&Command::ClientSendMessage));
156 assert!(commands.contains(&Command::SetBackground));
157 assert!(commands.contains(&Command::Ping));
158 assert!(commands.contains(&Command::Pong));
159
160 let ctx = AppContext::default();
162 let response = handler.handle_command(&ctx).await.unwrap();
163 assert_eq!(response.code, ResCode::Success as i32);
164 assert_eq!(response.message, "PONG");
165 }
166}