48 lines
1.4 KiB
Rust
48 lines
1.4 KiB
Rust
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<dyn std::error::Error + Send + Sync>> {
|
|
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<Request<Incoming>> for Server {
|
|
type Response = Response<Body>;
|
|
type Error = Box<dyn std::error::Error + Send + Sync>;
|
|
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
|
|
fn call(&self, req: Request<Incoming>) -> Self::Future {
|
|
let routes = self.settings.routes.clone();
|
|
Box::pin(async move { Ok(route(routes, req).await) })
|
|
}
|
|
}
|