use crate::{ body::{Body, BoxBody}, clone_box_service::CloneBoxService, }; use http::{Request, Response}; use pin_project_lite::pin_project; use std::{ convert::Infallible, fmt, future::Future, pin::Pin, task::{Context, Poll}, }; use tower::{util::Oneshot, ServiceExt}; use tower_service::Service; /// How routes are stored inside a [`Router`](super::Router). /// /// You normally shouldn't need to care about this type. pub struct Route(CloneBoxService, Response, Infallible>); impl Route { pub(super) fn new(svc: T) -> Self where T: Service, Response = Response, Error = Infallible> + Clone + Send + 'static, T::Future: Send + 'static, { Self(CloneBoxService::new(svc)) } } impl Clone for Route { fn clone(&self) -> Self { Self(self.0.clone()) } } impl fmt::Debug for Route { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Route").finish() } } impl Service> for Route { type Response = Response; type Error = Infallible; type Future = RouteFuture; #[inline] fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) } #[inline] fn call(&mut self, req: Request) -> Self::Future { RouteFuture::new(self.0.clone().oneshot(req)) } } pin_project! { /// Response future for [`Route`]. pub struct RouteFuture { #[pin] future: Oneshot< CloneBoxService, Response, Infallible>, Request, > } } impl RouteFuture { pub(crate) fn new( future: Oneshot, Response, Infallible>, Request>, ) -> Self { RouteFuture { future } } } impl Future for RouteFuture { type Output = Result, Infallible>; #[inline] fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { self.project().future.poll(cx) } } #[cfg(test)] mod tests { use super::*; #[test] fn traits() { use crate::tests::*; assert_send::>(); } }