use hyper::{Request, Response, body::Incoming, service::Service};
use std::future::Future;
use std::net::SocketAddr;
use std::pin::Pin;
use std::sync::Arc;
use crate::{Error, body, handler::RequestHandler};
#[cfg(feature = "metrics")]
use crate::metrics;
#[derive(Clone)]
pub struct RouterService {
builder: RequestServiceBuilder,
}
impl RouterService {
pub fn new(handler: RequestHandler) -> Self {
Self {
builder: RequestServiceBuilder::new(handler),
}
}
pub fn build(&self, remote_addr: Option<SocketAddr>) -> RequestService {
self.builder.build(remote_addr)
}
}
pub struct RequestService {
handler: Arc<RequestHandler>,
remote_addr: Option<SocketAddr>,
}
impl RequestService {
fn new(handler: Arc<RequestHandler>, remote_addr: Option<SocketAddr>) -> Self {
#[cfg(feature = "metrics")]
metrics::inc_connections();
Self {
handler,
remote_addr,
}
}
}
#[cfg(feature = "metrics")]
impl Drop for RequestService {
fn drop(&mut self) {
metrics::dec_connections();
}
}
impl Service<Request<Incoming>> for RequestService {
type Response = Response<body::Body>;
type Error = Error;
type Future =
Pin<Box<dyn Future<Output = Result<Response<body::Body>, Error>> + Send + 'static>>;
fn call(&self, mut req: Request<Incoming>) -> Self::Future {
let handler = self.handler.clone();
let remote_addr = self.remote_addr;
Box::pin(async move { handler.handle(&mut req, remote_addr).await })
}
}
#[derive(Clone)]
pub struct RequestServiceBuilder {
handler: Arc<RequestHandler>,
}
impl RequestServiceBuilder {
pub fn new(handler: RequestHandler) -> Self {
Self {
handler: Arc::new(handler),
}
}
pub fn build(&self, remote_addr: Option<SocketAddr>) -> RequestService {
RequestService::new(self.handler.clone(), remote_addr)
}
}