use crate::body::Body; use crate::routing::route; use crate::settings::Settings; use hyper::body::Incoming; use hyper::server::conn::http1; use hyper::service::Service; use hyper::{Request, Response}; use hyper_util::rt::TokioIo; use std::future::Future; use std::pin::Pin; use tokio::net::TcpListener; #[derive(Clone)] pub struct Server { settings: Settings, } impl Server { pub fn new(settings: Settings) -> Server { Server { settings } } #[tokio::main] pub async fn run(self) -> Result<(), Box> { let listener = TcpListener::bind(self.settings.address).await?; loop { let (stream, _) = listener.accept().await?; let io = TokioIo::new(stream); let clone = self.clone(); tokio::task::spawn(async move { if let Err(error) = http1::Builder::new().serve_connection(io, clone).await { println!("failed to serve connection: {}", error); } }); } } } impl Service> for Server { type Response = Response; type Error = Box; type Future = Pin> + Send>>; fn call(&self, req: Request) -> Self::Future { let routes = self.settings.routes.clone(); Box::pin(async move { Ok(route(routes, req).await) }) } }