1use std::{
2    fmt::{self},
3    io::{Read, Write},
4    net::{Shutdown, TcpListener, TcpStream},
5    sync::Mutex,
6};
7
8use crate::{Packet, ReadingError};
9
10#[derive(Clone, Debug)]
24pub struct ServerError(String);
25
26impl fmt::Display for ServerError {
27    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28        write!(f, "{}", self.0)
29    }
30}
31
32pub struct LogicalClient {
34    address: String,
35    stream: TcpStream,
36}
37
38impl LogicalClient {
39    pub fn send(&mut self, packet: Packet) -> Result<usize, std::io::Error> {
41        let size = self.stream.write(packet.encode().as_slice())?;
42        Ok(size)
43    }
44
45    pub fn read(&mut self) -> Result<Packet, ReadingError> {
47        let mut data = [0; 64];
48
49        match self.stream.read(&mut data) {
50            Ok(_) => {
51                if let Ok(packet) = Packet::decode(data.to_vec()) {
52                    Ok(packet)
53                } else {
54                    Err(ReadingError::Decode)
55                }
56            }
57            Err(_) => Err(ReadingError::Reading),
58        }
59    }
60
61    pub fn address(&self) -> String {
63        self.address.clone()
64    }
65
66    pub fn disconnect(&self) -> Result<(), std::io::Error> {
68        self.stream.shutdown(Shutdown::Both)?;
69
70        Ok(())
71    }
72}
73
74pub enum LogStage {
76    SERVER,
77    CLIENT,
78}
79
80pub enum LogLevel {
82    INFO,
83    WARN,
84    ERROR,
85}
86
87pub struct Server<'a> {
89    pub address: &'a str,
90    pub port: u16,
91    listener: Option<TcpListener>,
92    error_handler: Option<Box<dyn Fn(ServerError) -> () + Send + Sync>>,
93    client_handler: Box<dyn Fn(LogicalClient) -> () + Send + Sync>,
94}
95
96impl<'a> Server<'a> {
97    pub fn new(address: &'a str, port: u16) -> Self {
99        Self {
100            address,
101            port,
102            listener: None,
103            error_handler: None,
104            client_handler: Box::new(|c| println!("{} connected.", c.address())),
105        }
106    }
107
108    pub fn run(&mut self) {
110        self.listener =
111            if let Ok(listener) = TcpListener::bind(format!("{}:{}", self.address, self.port)) {
112                Some(listener)
113            } else {
114                self.handle_error(ServerError(format!(
115                    "failed to bind listener to address {}:{}",
116                    self.address, self.port,
117                )));
118                None
119            };
120
121        let handler = Mutex::new(&self.client_handler);
122
123        if let Err(_) = crossbeam::thread::scope(|s| {
124            s.spawn(|_| {
125                if let Some(listener) = &self.listener {
126                    for stream in listener.incoming() {
127                        match stream {
128                            Ok(stream) => {
129                                let client = LogicalClient {
130                                    address: stream.local_addr().unwrap().to_string(),
131                                    stream,
132                                };
133                                handler.lock().unwrap()(client);
134                            }
135                            Err(e) => {
136                                self.handle_error(ServerError(format!("Connection failed: {}", e)))
137                            }
138                        }
139                    }
140                }
141            });
142        }) {
143            self.handle_error(ServerError("Failed to spawn listener thread".to_string()));
144        }
145    }
146
147    fn handle_error(&self, error: ServerError) {
150        if let Some(handler) = &self.error_handler {
151            handler(error);
152        } else {
153            println!("{}", error);
154        }
155    }
156}
157
158pub struct ServerBuilder<'a> {
167    address: &'a str,
168    port: u16,
169    error_handler: Option<Box<dyn Fn(ServerError) -> () + Send + Sync>>,
170    client_handler: Box<dyn Fn(LogicalClient) -> () + Send + Sync>,
171}
172
173impl<'a> ServerBuilder<'a> {
174    pub fn new() -> Self {
176        Self {
177            address: "0.0.0.0",
178            port: 4444,
179            error_handler: None,
180            client_handler: Box::new(|c| println!("{} connected.", c.address())),
181        }
182    }
183
184    pub fn address(mut self, address: &'a str) -> Self {
186        Self {
187            address: address,
188            port: self.port,
189            error_handler: std::mem::replace(&mut self.error_handler, None),
190            client_handler: self.client_handler,
191        }
192    }
193
194    pub fn port(mut self, port: u16) -> Self {
196        Self {
197            address: self.address,
198            port: port,
199            error_handler: std::mem::replace(&mut self.error_handler, None),
200            client_handler: self.client_handler,
201        }
202    }
203
204    pub fn error_handler(self, handler: Box<dyn Fn(ServerError) -> () + Send + Sync>) -> Self {
206        Self {
207            address: self.address,
208            port: self.port,
209            error_handler: Some(handler),
210            client_handler: self.client_handler,
211        }
212    }
213
214    pub fn client_handler(
216        mut self,
217        handler: Box<dyn Fn(LogicalClient) -> () + Send + Sync>,
218    ) -> Self {
219        Self {
220            address: self.address,
221            port: self.port,
222            error_handler: std::mem::replace(&mut self.error_handler, None),
223            client_handler: handler,
224        }
225    }
226
227    pub fn build(mut self) -> Server<'a> {
229        Server {
230            address: self.address,
231            port: self.port,
232            listener: None,
233            error_handler: std::mem::replace(&mut self.error_handler, None),
234            client_handler: self.client_handler,
235        }
236    }
237}