Last active
December 30, 2018 01:40
-
-
Save goriunov/2e453b4bd93b8198c1216a12b7b95534 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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