1#[cfg(feature = "tcp-binder")]
9mod tcp;
10#[cfg(feature = "tcp-binder")]
11pub use tcp::*;
12
13use log::{debug, error, trace, warn};
14use std::{
15 io,
16 ops::{Deref, DerefMut},
17 sync::{Arc, Mutex},
18 thread,
19 time::Duration,
20};
21
22use crate::{TimerCycle, TimerLoop};
23
24use super::{Request, Response, ThreadSafeTimer, TimerConfig, TimerEvent};
25
26#[derive(Clone, Debug, Default, Eq, PartialEq)]
27pub enum ServerState {
28 Running,
30 Stopping,
32 #[default]
34 Stopped,
35}
36
37pub struct ServerConfig {
38 handler: ServerStateChangedHandler,
39 binders: Vec<Box<dyn ServerBind>>,
40}
41
42impl Default for ServerConfig {
43 fn default() -> Self {
44 Self {
45 handler: Arc::new(|_| Ok(())),
46 binders: Vec::new(),
47 }
48 }
49}
50
51#[derive(Clone, Debug, Eq, PartialEq)]
52pub enum ServerEvent {
53 Started,
54 Stopping,
55 Stopped,
56}
57
58pub type ServerStateChangedHandler =
59 Arc<dyn Fn(ServerEvent) -> io::Result<()> + Sync + Send + 'static>;
60
61#[derive(Clone, Debug, Default)]
65pub struct ThreadSafeState(Arc<Mutex<ServerState>>);
66
67impl ThreadSafeState {
68 pub fn new() -> Self {
69 Self::default()
70 }
71
72 fn set(&self, next_state: ServerState) -> io::Result<()> {
73 match self.lock() {
74 Ok(mut state) => {
75 *state = next_state;
76 Ok(())
77 }
78 Err(err) => Err(io::Error::new(
79 io::ErrorKind::Other,
80 format!("cannot lock server state: {err}"),
81 )),
82 }
83 }
84
85 pub fn set_running(&self) -> io::Result<()> {
86 self.set(ServerState::Running)
87 }
88
89 pub fn set_stopping(&self) -> io::Result<()> {
90 self.set(ServerState::Stopping)
91 }
92
93 pub fn set_stopped(&self) -> io::Result<()> {
94 self.set(ServerState::Stopped)
95 }
96}
97
98impl Deref for ThreadSafeState {
99 type Target = Arc<Mutex<ServerState>>;
100
101 fn deref(&self) -> &Self::Target {
102 &self.0
103 }
104}
105
106impl DerefMut for ThreadSafeState {
107 fn deref_mut(&mut self) -> &mut Self::Target {
108 &mut self.0
109 }
110}
111
112pub trait ServerBind: Sync + Send {
114 fn bind(&self, timer: ThreadSafeTimer) -> io::Result<()>;
117}
118
119pub trait ServerStream<T> {
124 fn read(&self, stream: &T) -> io::Result<Request>;
125 fn write(&self, stream: &mut T, res: Response) -> io::Result<()>;
126
127 fn handle(&self, timer: ThreadSafeTimer, stream: &mut T) -> io::Result<()> {
128 let req = self.read(stream)?;
129 let res = match req {
130 Request::Start => {
131 debug!("starting timer");
132 timer.start()?;
133 Response::Ok
134 }
135 Request::Get => {
136 debug!("getting timer");
137 let timer = timer.get()?;
138 trace!("{timer:#?}");
139 Response::Timer(timer)
140 }
141 Request::Set(duration) => {
142 debug!("setting timer");
143 timer.set(duration)?;
144 Response::Ok
145 }
146 Request::Pause => {
147 debug!("pausing timer");
148 timer.pause()?;
149 Response::Ok
150 }
151 Request::Resume => {
152 debug!("resuming timer");
153 timer.resume()?;
154 Response::Ok
155 }
156 Request::Stop => {
157 debug!("stopping timer");
158 timer.stop()?;
159 Response::Ok
160 }
161 };
162 self.write(stream, res)?;
163 Ok(())
164 }
165}
166
167#[derive(Default)]
168pub struct Server {
169 config: ServerConfig,
170 state: ThreadSafeState,
171 timer: ThreadSafeTimer,
172}
173
174impl Server {
175 pub fn bind_with(self, wait: impl Fn() -> io::Result<()>) -> io::Result<()> {
179 debug!("starting server");
180
181 let fire_event = |event: ServerEvent| {
182 if let Err(err) = (self.config.handler)(event.clone()) {
183 warn!("cannot fire event {event:?}, skipping it");
184 error!("{err}");
185 }
186 };
187
188 self.state.set_running()?;
189 fire_event(ServerEvent::Started);
190
191 let state = self.state.clone();
193 let timer = self.timer.clone();
194 let tick = thread::spawn(move || loop {
195 match state.lock() {
196 Ok(mut state) => match *state {
197 ServerState::Stopping => {
198 *state = ServerState::Stopped;
199 break;
200 }
201 ServerState::Stopped => {
202 break;
203 }
204 ServerState::Running => {
205 if let Err(err) = timer.update() {
206 warn!("cannot update timer, exiting: {err}");
207 debug!("cannot update timer: {err:?}");
208 *state = ServerState::Stopping;
209 break;
210 }
211 }
212 },
213 Err(err) => {
214 warn!("cannot determine if server should stop, exiting: {err}");
215 debug!("cannot determine if server should stop: {err:?}");
216 break;
217 }
218 }
219
220 trace!("timer tick: {timer:#?}");
221 thread::sleep(Duration::from_secs(1));
222 });
223
224 for binder in self.config.binders {
227 let timer = self.timer.clone();
228 thread::spawn(move || {
229 if let Err(err) = binder.bind(timer) {
230 warn!("cannot bind, exiting: {err}");
231 debug!("cannot bind: {err:?}");
232 }
233 });
234 }
235
236 wait()?;
237
238 self.state.set_stopping()?;
239 fire_event(ServerEvent::Stopping);
240
241 tick.join()
243 .map_err(|_| io::Error::new(io::ErrorKind::Other, "cannot wait for timer thread"))?;
244 fire_event(ServerEvent::Stopped);
245
246 Ok(())
247 }
248
249 pub fn bind(self) -> io::Result<()> {
252 self.bind_with(|| loop {
253 thread::sleep(Duration::from_secs(1));
254 })
255 }
256}
257
258#[derive(Default)]
260pub struct ServerBuilder {
261 server_config: ServerConfig,
262 timer_config: TimerConfig,
263}
264
265impl ServerBuilder {
266 pub fn new() -> Self {
267 Self::default()
268 }
269
270 pub fn with_server_config(mut self, config: ServerConfig) -> Self {
271 self.server_config = config;
272 self
273 }
274
275 pub fn with_timer_config(mut self, config: TimerConfig) -> Self {
276 self.timer_config = config;
277 self
278 }
279
280 pub fn with_pomodoro_config(mut self) -> Self {
286 let work = TimerCycle::new("Work", 25 * 60);
287 let short_break = TimerCycle::new("Short break", 5 * 60);
288 let long_break = TimerCycle::new("Long break", 15 * 60);
289
290 *self.timer_config.cycles = vec![
291 work.clone(),
292 short_break.clone(),
293 work.clone(),
294 short_break.clone(),
295 work.clone(),
296 short_break.clone(),
297 work.clone(),
298 short_break.clone(),
299 long_break,
300 ];
301 self
302 }
303
304 pub fn with_52_17_config(mut self) -> Self {
309 let work = TimerCycle::new("Work", 52 * 60);
310 let rest = TimerCycle::new("Rest", 17 * 60);
311
312 *self.timer_config.cycles = vec![work, rest];
313 self
314 }
315
316 pub fn with_server_handler<H>(mut self, handler: H) -> Self
317 where
318 H: Fn(ServerEvent) -> io::Result<()> + Sync + Send + 'static,
319 {
320 self.server_config.handler = Arc::new(handler);
321 self
322 }
323
324 pub fn with_binder(mut self, binder: Box<dyn ServerBind>) -> Self {
325 self.server_config.binders.push(binder);
326 self
327 }
328
329 pub fn with_timer_handler<H>(mut self, handler: H) -> Self
330 where
331 H: Fn(TimerEvent) -> io::Result<()> + Sync + Send + 'static,
332 {
333 self.timer_config.handler = Arc::new(handler);
334 self
335 }
336
337 pub fn with_cycle<C>(mut self, cycle: C) -> Self
338 where
339 C: Into<TimerCycle>,
340 {
341 self.timer_config.cycles.push(cycle.into());
342 self
343 }
344
345 pub fn with_cycles<C, I>(mut self, cycles: I) -> Self
346 where
347 C: Into<TimerCycle>,
348 I: IntoIterator<Item = C>,
349 {
350 for cycle in cycles {
351 self.timer_config.cycles.push(cycle.into());
352 }
353 self
354 }
355
356 pub fn with_cycles_count(mut self, count: impl Into<TimerLoop>) -> Self {
357 self.timer_config.cycles_count = count.into();
358 self
359 }
360
361 pub fn build(self) -> io::Result<Server> {
362 Ok(Server {
363 config: self.server_config,
364 state: ThreadSafeState::new(),
365 timer: ThreadSafeTimer::new(self.timer_config)?,
366 })
367 }
368}