use hyper::server::conn::Http; use hyper::service::Service; use hyper::{Body, Request, Response}; use tokio::net::TcpListener; use std::future::Future; use std::net::SocketAddr; use std::pin::Pin; use std::task::{Context, Poll}; type Counter = i32; #[tokio::main] async fn main() -> Result<(), Box> { let addr: SocketAddr = ([127, 0, 0, 1], 3000).into(); let listener = TcpListener::bind(addr).await?; println!("Listening on http://{}", addr); loop { let (stream, _) = listener.accept().await?; tokio::task::spawn(async move { if let Err(err) = Http::new() .serve_connection(stream, Svc { counter: 81818 }) .await { println!("Failed to serve connection: {:?}", err); } }); } } struct Svc { counter: Counter, } impl Service> for Svc { type Response = Response; type Error = hyper::Error; type Future = Pin> + Send>>; fn poll_ready(&mut self, _: &mut Context) -> Poll> { Poll::Ready(Ok(())) } fn call(&mut self, req: Request) -> Self::Future { fn mk_response(s: String) -> Result, hyper::Error> { Ok(Response::builder().body(Body::from(s)).unwrap()) } let res = match req.uri().path() { "/" => mk_response(format!("home! counter = {:?}", self.counter)), "/posts" => mk_response(format!("posts, of course! counter = {:?}", self.counter)), "/authors" => mk_response(format!( "authors extraordinare! counter = {:?}", self.counter )), // Return the 404 Not Found for other routes, and don't increment counter. _ => return Box::pin(async { mk_response("oh no! not found".into()) }), }; if req.uri().path() != "/favicon.ico" { self.counter += 1; } Box::pin(async { res }) } }