1use anyhow::{Context, Result};
7use lazy_static::lazy_static;
8pub use serde::{Deserialize, Serialize};
9
10use std::net::TcpStream;
11use std::sync::Mutex;
12
13pub use std::{thread::sleep, time::Duration};
14pub use tokio;
15
16use tokio::io::{AsyncReadExt, AsyncWriteExt};
17use tokio::net;
18
19pub mod error;
20pub mod logger;
21pub mod prelude;
22pub mod sendable;
23pub mod sockets;
24
25use sendable::Sendable;
26
27lazy_static! {
28 static ref CLIENT: Mutex<Option<TcpStream>> = Mutex::new(None);
29}
30
31const BUFFER_SIZE: usize = 1024;
33pub type Bytes = Vec<u8>;
34
35pub trait ServerConn {
37 type ClientMsg: Serialize + for<'de> Deserialize<'de> + Send + 'static;
38 type ServerMsg: Serialize + for<'de> Deserialize<'de> + Send + 'static;
39
40 fn handle_message(&mut self, message: Self::ClientMsg) -> Self::ServerMsg;
45
46 fn new() -> Self;
48}
49
50pub async fn start_server<T: ServerConn + Send + 'static>(
51 address: impl net::ToSocketAddrs,
52) -> Result<()> {
53 let listener = net::TcpListener::bind(address)
55 .await
56 .context("Failed to bind to address")?;
57
58 while let Ok((socket, _)) = listener.accept().await {
60 tokio::spawn(async move {
61 let res = handle_connection(socket, &mut T::new()).await;
62 eprintln!("{:?}", res);
63 });
64 }
65
66 Ok(())
67}
68
69async fn handle_connection<T: ServerConn + Send + 'static>(
70 mut socket: tokio::net::TcpStream,
71 instance: &mut T,
72) -> Result<()> {
73 let (reader, writer) = socket.split();
74 let mut reader = tokio::io::BufReader::new(reader);
75 let mut writer = tokio::io::BufWriter::new(writer);
76
77 let mut buf = vec![0; BUFFER_SIZE];
78 loop {
79 let n = reader
80 .read(&mut buf)
81 .await
82 .context("Failed to read from socket")?;
83 if n == 0 {
84 break; }
86
87 let message = T::ClientMsg::from_bytes(&buf).context("Failed to parse message")?;
89 let response = instance.handle_message(message);
90
91 let response_bytes = response
92 .to_bytes()
93 .context("Failed to serialize response")?;
94 writer
95 .write_all(&response_bytes)
96 .await
97 .context("Failed to write to socket")?;
98 writer.flush().await.context("Failed to flush writer")?;
99 }
100
101 Ok(())
102}