aerosocket_server/
handler.rs1use aerosocket_core::{Message, Result};
6use std::pin::Pin;
7use std::future::Future;
8
9pub trait Handler: Send + Sync + 'static {
11 fn handle<'a>(&'a self, connection: crate::connection::ConnectionHandle) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'a>>;
13
14 fn clone_box(&self) -> Box<dyn Handler>;
16}
17
18impl Clone for Box<dyn Handler> {
19 fn clone(&self) -> Box<dyn Handler> {
20 self.clone_box()
21 }
22}
23
24pub type BoxedHandler = Box<dyn Handler>;
26
27#[derive(Debug, Clone)]
29pub struct DefaultHandler;
30
31impl DefaultHandler {
32 pub fn new() -> Self {
34 Self
35 }
36}
37
38impl Default for DefaultHandler {
39 fn default() -> Self {
40 Self::new()
41 }
42}
43
44impl Handler for DefaultHandler {
45 fn handle<'a>(&'a self, connection: crate::connection::ConnectionHandle) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'a>> {
46 Box::pin(async move {
47 let mut conn = connection.try_lock().await
49 .map_err(|_| aerosocket_core::Error::Other("Failed to lock connection".to_string()))?;
50
51 while let Some(msg) = conn.next().await? {
52 match msg {
53 Message::Text(text) => {
54 conn.send_text(text.as_str()).await?;
55 }
56 Message::Binary(data) => {
57 conn.send_binary(data.as_bytes().to_vec()).await?;
58 }
59 Message::Ping(_) => {
60 conn.pong(None).await?;
61 }
62 Message::Close(close_msg) => {
63 let code = close_msg.code();
64 let reason = close_msg.reason();
65 conn.close(code, Some(reason)).await?;
66 break;
67 }
68 Message::Pong(_) => {
69 }
71 }
72 }
73
74 Ok(())
75 })
76 }
77
78 fn clone_box(&self) -> Box<dyn Handler> {
79 Box::new(self.clone())
80 }
81}
82
83#[derive(Debug, Clone)]
85pub struct EchoHandler;
86
87impl EchoHandler {
88 pub fn new() -> Self {
90 Self
91 }
92}
93
94impl Default for EchoHandler {
95 fn default() -> Self {
96 Self::new()
97 }
98}
99
100impl Handler for EchoHandler {
101 fn handle<'a>(&'a self, connection: crate::connection::ConnectionHandle) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'a>> {
102 Box::pin(async move {
103 let mut conn = connection.try_lock().await
105 .map_err(|_| aerosocket_core::Error::Other("Failed to lock connection".to_string()))?;
106
107 while let Some(msg) = conn.next().await? {
108 match msg {
109 Message::Text(text) => {
110 let echo_text = format!("Echo: {}", text.as_str());
111 conn.send_text(&echo_text).await?;
112 }
113 Message::Binary(data) => {
114 conn.send_binary(data.as_bytes().to_vec()).await?;
115 }
116 Message::Ping(_) => {
117 conn.pong(None).await?;
118 }
119 Message::Close(close_msg) => {
120 let code = close_msg.code();
121 let reason = close_msg.reason();
122 conn.close(code, Some(reason)).await?;
123 break;
124 }
125 Message::Pong(_) => {
126 }
128 }
129 }
130
131 Ok(())
132 })
133 }
134
135 fn clone_box(&self) -> Box<dyn Handler> {
136 Box::new(self.clone())
137 }
138}
139
140#[derive(Clone)]
142pub struct FnHandler<F> {
143 f: F,
144}
145
146impl<F> FnHandler<F> {
147 pub fn new(f: F) -> Self {
149 Self { f }
150 }
151}
152
153impl<F> Handler for FnHandler<F>
154where
155 F: Fn(crate::connection::ConnectionHandle) -> Pin<Box<dyn Future<Output = Result<()>> + Send>> + Send + Sync + Clone + 'static,
156{
157 fn handle<'a>(&'a self, connection: crate::connection::ConnectionHandle) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'a>> {
158 Box::pin((self.f)(connection))
159 }
160
161 fn clone_box(&self) -> Box<dyn Handler> {
162 Box::new(self.clone())
163 }
164}
165
166impl<F> std::fmt::Debug for FnHandler<F> {
167 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
168 f.debug_struct("FnHandler")
169 .field("f", &"<function>")
170 .finish()
171 }
172}
173
174pub fn from_fn<F, Fut>(f: F) -> FnHandler<F>
176where
177 F: Fn(crate::connection::ConnectionHandle) -> Fut + Send + Sync + Clone + 'static,
178 Fut: Future<Output = Result<()>> + Send + 'static,
179{
180 FnHandler::new(f)
181}
182
183#[cfg(test)]
184mod tests {
185 use super::*;
186 use bytes::Bytes;
187
188 #[tokio::test]
189 async fn test_default_handler() {
190 let handler = DefaultHandler::new();
191 let remote = "127.0.0.1:12345".parse().unwrap();
192 let local = "127.0.0.1:8080".parse().unwrap();
193 let connection = crate::connection::Connection::new(remote, local);
194
195 assert!(true);
198 }
199
200 #[tokio::test]
201 async fn test_echo_handler() {
202 let handler = EchoHandler::new();
203 let remote = "127.0.0.1:12345".parse().unwrap();
204 let local = "127.0.0.1:8080".parse().unwrap();
205 let connection = crate::connection::Connection::new(remote, local);
206
207 assert!(true);
210 }
211
212 #[tokio::test]
213 async fn test_fn_handler() {
214 let handler = from_fn(|_conn| async {
215 Ok(())
216 });
217
218 let remote = "127.0.0.1:12345".parse().unwrap();
219 let local = "127.0.0.1:8080".parse().unwrap();
220 let connection = crate::connection::Connection::new(remote, local);
221
222 assert!(true);
225 }
226}