use std::convert::Infallible;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use std::time::Duration;
use hyper::body::Incoming;
use hyper::service::Service;
use crate::{Body, Request, Response, Router};
#[derive(Clone)]
pub struct RouterService {
router: Arc<Router>,
pub(crate) shutdown_timeout: Duration,
}
impl RouterService {
pub fn new(router: Router) -> Self {
const DEFAULT_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(30);
Self {
router: Arc::new(router),
shutdown_timeout: DEFAULT_SHUTDOWN_TIMEOUT,
}
}
#[must_use]
pub fn shutdown_timeout(mut self, timeout: Duration) -> Self {
self.shutdown_timeout = timeout;
self
}
}
impl From<Router> for RouterService {
fn from(router: Router) -> Self {
Self::new(router)
}
}
impl Service<Request<Incoming>> for RouterService {
type Response = Response;
type Error = Infallible;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
fn call(&self, request: Request<Incoming>) -> Self::Future {
let router = self.router.clone();
Box::pin(async move { Ok(router.handle(request.map(Body::new)).await) })
}
}