From aed2af852ef81d07bc21c4437b06039e8ded5251 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 7 May 2018 16:09:40 -0600 Subject: [PATCH] server semi-monad --- Chapter07/monad_pattern.rs | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/Chapter07/monad_pattern.rs b/Chapter07/monad_pattern.rs index e721986..089bb7c 100644 --- a/Chapter07/monad_pattern.rs +++ b/Chapter07/monad_pattern.rs @@ -6,25 +6,36 @@ use std::thread; struct ServerMonad { state: St, - handle: Box bool> + handlers: Vec Option>> } impl ServerMonad { - fn _return(&self, st: St) -> ServerMonad { + fn _return(st: St) -> ServerMonad { ServerMonad { state: st, - handle: Box::new(|st: &mut St, s| false) + handlers: Vec::new() } } - fn listen(&self, address: &str) { + fn listen(&mut self, address: &str) { let listener = TcpListener::bind(address).unwrap(); - for stream in listener.incoming() { let mut st = self.state.clone(); - let mut buffer = String::new(); - stream.unwrap().read_to_string(&mut buffer); - (self.handle)(&mut st,buffer); + let mut buffer = [0; 2048]; + let mut tcp = stream.unwrap(); + tcp.read(&mut buffer); + let buffer = String::from_utf8_lossy(&buffer).into_owned(); + for h in self.handlers.iter() { + if let Some(response) = h(&mut st,&buffer) { + tcp.write(response.as_bytes()); + break + } + } } } + fn bind_handler(mut self, f: F) -> Self + where F: 'static + Fn(&mut St,&String) -> Option { + self.handlers.push(Box::new(f)); + self + } } struct LogMonad(T); @@ -84,5 +95,12 @@ fn main() .bind(|z| format!("{}{}", z, z)); let nowdoit = notyet.apply(222); - println!("nowdoit {}", nowdoit) + println!("nowdoit {}", nowdoit); + + ServerMonad::_return(()) + .bind_handler(|&mut st, ref msg| if msg.len()%2 == 0 { Some("divisible by 2".to_string()) } else { None }) + .bind_handler(|&mut st, ref msg| if msg.len()%3 == 0 { Some("divisible by 3".to_string()) } else { None }) + .bind_handler(|&mut st, ref msg| if msg.len()%5 == 0 { Some("divisible by 5".to_string()) } else { None }) + .bind_handler(|&mut st, ref msg| if msg.len()%7 == 0 { Some("divisible by 7".to_string()) } else { None }) + .listen("127.0.0.1:8888"); }