ironsbe_server/
handler.rs1use ironsbe_core::header::MessageHeader;
4
5pub trait MessageHandler: Send + Sync {
7 fn on_message(
15 &self,
16 session_id: u64,
17 header: &MessageHeader,
18 buffer: &[u8],
19 responder: &dyn Responder,
20 );
21
22 fn on_session_start(&self, _session_id: u64) {}
27
28 fn on_session_end(&self, _session_id: u64) {}
33
34 fn on_error(&self, _session_id: u64, _error: &str) {}
40}
41
42pub trait Responder: Send + Sync {
44 fn send(&self, message: &[u8]) -> Result<(), SendError>;
52
53 fn send_to(&self, session_id: u64, message: &[u8]) -> Result<(), SendError>;
62}
63
64#[derive(Debug, Clone)]
66pub struct SendError {
67 pub message: String,
69}
70
71impl std::fmt::Display for SendError {
72 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73 write!(f, "send error: {}", self.message)
74 }
75}
76
77impl std::error::Error for SendError {}
78
79pub trait TypedHandler: Send + Sync {
81 fn handle(&self, session_id: u64, buffer: &[u8], responder: &dyn Responder);
88}
89
90pub struct FnHandler<F> {
92 handler: F,
93}
94
95impl<F> FnHandler<F>
96where
97 F: Fn(u64, &[u8], &dyn Responder) + Send + Sync,
98{
99 pub fn new(handler: F) -> Self {
101 Self { handler }
102 }
103}
104
105impl<F> TypedHandler for FnHandler<F>
106where
107 F: Fn(u64, &[u8], &dyn Responder) + Send + Sync,
108{
109 fn handle(&self, session_id: u64, buffer: &[u8], responder: &dyn Responder) {
110 (self.handler)(session_id, buffer, responder);
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117 use std::sync::Arc;
118 use std::sync::atomic::{AtomicBool, Ordering};
119
120 #[test]
121 fn test_send_error_display() {
122 let err = SendError {
123 message: "connection lost".to_string(),
124 };
125 let msg = err.to_string();
126 assert!(msg.contains("connection lost"));
127 assert!(msg.contains("send error"));
128 }
129
130 #[test]
131 fn test_send_error_clone() {
132 let err = SendError {
133 message: "test".to_string(),
134 };
135 let cloned = err.clone();
136 assert_eq!(err.message, cloned.message);
137 }
138
139 #[test]
140 fn test_send_error_debug() {
141 let err = SendError {
142 message: "debug test".to_string(),
143 };
144 let debug_str = format!("{:?}", err);
145 assert!(debug_str.contains("SendError"));
146 assert!(debug_str.contains("debug test"));
147 }
148
149 struct MockResponder;
150
151 impl Responder for MockResponder {
152 fn send(&self, _message: &[u8]) -> Result<(), SendError> {
153 Ok(())
154 }
155
156 fn send_to(&self, _session_id: u64, _message: &[u8]) -> Result<(), SendError> {
157 Ok(())
158 }
159 }
160
161 #[test]
162 fn test_fn_handler() {
163 let called = Arc::new(AtomicBool::new(false));
164 let called_clone = called.clone();
165
166 let handler = FnHandler::new(move |_session_id, _buffer, _responder| {
167 called_clone.store(true, Ordering::SeqCst);
168 });
169
170 let responder = MockResponder;
171 handler.handle(1, &[1, 2, 3], &responder);
172
173 assert!(called.load(Ordering::SeqCst));
174 }
175
176 struct TestMessageHandler {
177 session_started: Arc<AtomicBool>,
178 session_ended: Arc<AtomicBool>,
179 error_received: Arc<AtomicBool>,
180 }
181
182 impl MessageHandler for TestMessageHandler {
183 fn on_message(
184 &self,
185 _session_id: u64,
186 _header: &MessageHeader,
187 _buffer: &[u8],
188 _responder: &dyn Responder,
189 ) {
190 }
191
192 fn on_session_start(&self, _session_id: u64) {
193 self.session_started.store(true, Ordering::SeqCst);
194 }
195
196 fn on_session_end(&self, _session_id: u64) {
197 self.session_ended.store(true, Ordering::SeqCst);
198 }
199
200 fn on_error(&self, _session_id: u64, _error: &str) {
201 self.error_received.store(true, Ordering::SeqCst);
202 }
203 }
204
205 #[test]
206 fn test_message_handler_callbacks() {
207 let handler = TestMessageHandler {
208 session_started: Arc::new(AtomicBool::new(false)),
209 session_ended: Arc::new(AtomicBool::new(false)),
210 error_received: Arc::new(AtomicBool::new(false)),
211 };
212
213 handler.on_session_start(1);
214 assert!(handler.session_started.load(Ordering::SeqCst));
215
216 handler.on_session_end(1);
217 assert!(handler.session_ended.load(Ordering::SeqCst));
218
219 handler.on_error(1, "test error");
220 assert!(handler.error_received.load(Ordering::SeqCst));
221 }
222}