| // Cargo file | |
| // [package] | |
| // name = "simple-tests" | |
| // version = "0.1.0" | |
| // edition = "2018" | |
| // [dependencies] | |
| // tokio = "0.1" | |
| // futures = "0.1" | |
| use futures; | |
| use futures::try_ready; | |
| use tokio; | |
| use tokio::prelude::*; | |
| use tokio::net::TcpListener; | |
| pub fn main() { | |
| let addr = "0.0.0.0:3000".parse().unwrap(); | |
| let listener = TcpListener::bind(&addr).expect("unable to bind TCP listener"); | |
| let mut myFns = FunctionsReturn::new(); | |
| // this can be just a reference to existing function like | |
| // myFns.addCase2Fn(my_func); | |
| myFns.addCase1Fn(Box::new(|arr| { | |
| Box::new(futures::future::ok(String::from("Hello world"))) | |
| })); | |
| let server = listener | |
| .incoming() | |
| .map_err(|e| eprintln!("accept failed = {:?}", e)) | |
| .for_each(move |sock| { | |
| // all logic | |
| let (read, write) = sock.split(); | |
| let process = Reader::new(read) | |
| .map_err(|e| println!("Error is: {}", e)) | |
| .fold(write, |write, data| { | |
| // print received message | |
| println!("{}", String::from_utf8_lossy(&data)); | |
| // THIS IS ERRORED PLACE comment that line to make it work again | |
| // call some function from above | |
| (myFns.case1Fn).unwrap()(data); | |
| // write something | |
| tokio::io::write_all( | |
| write, | |
| &"HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello World!".as_bytes()[..], | |
| ) | |
| .map_err(|e| println!("Error is: {}", e)) | |
| .map(|(w, _)| w) | |
| }) | |
| .map(|_| ()); | |
| tokio::spawn(process) | |
| }); | |
| tokio::run(server); | |
| } | |
| // different cases functions | |
| type Func = Box<Fn(Vec<u8>) -> Box<Future<Item = String, Error = ()>> + Send>; | |
| pub struct FunctionsReturn { | |
| pub case1Fn: Option<Func>, | |
| pub case2Fn: Option<Func>, | |
| } | |
| impl FunctionsReturn { | |
| pub fn new() -> FunctionsReturn { | |
| FunctionsReturn { | |
| case1Fn: None, | |
| case2Fn: None, | |
| } | |
| } | |
| pub fn addCase1Fn(&mut self, func: Func) { | |
| self.case1Fn = Some(func); | |
| } | |
| pub fn addCase2Fn(&mut self, func: Func) { | |
| self.case1Fn = Some(func); | |
| } | |
| } | |
| // Create reader for http | |
| pub struct Reader<S> { | |
| sock: S, | |
| buf: Vec<u8>, | |
| } | |
| impl<S: AsyncRead> Reader<S> { | |
| pub fn new(sock: S) -> Reader<S> { | |
| Reader { | |
| sock, | |
| buf: Vec::new(), | |
| } | |
| } | |
| } | |
| impl<S: AsyncRead> Stream for Reader<S> { | |
| type Item = Vec<u8>; | |
| type Error = std::io::Error; | |
| fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> { | |
| // simple buf reader | |
| loop { | |
| let n = match self.sock.read_buf(&mut self.buf) { | |
| Ok(Async::Ready(0)) => { | |
| return Ok(Async::Ready(None)); | |
| } | |
| Ok(Async::Ready(n)) => n, | |
| Ok(Async::NotReady) => { | |
| break; | |
| } | |
| Err(e) => { | |
| println!("Error reading {}", e); | |
| return Err(e); | |
| } | |
| }; | |
| } | |
| if !self.buf.is_empty() { | |
| return Ok(Async::Ready(Some(self.buf.drain(..).collect()))); | |
| } | |
| Ok(Async::NotReady) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment