aws_smithy_http_server/routing/
route.rs1use crate::body::{Body, BoxBody};
36use http::{Request, Response};
37use std::{
38 convert::Infallible,
39 fmt,
40 future::Future,
41 pin::Pin,
42 task::{Context, Poll},
43};
44use tower::{
45 util::{BoxCloneService, Oneshot},
46 Service, ServiceExt,
47};
48
49pub struct Route<B = Body> {
53 service: BoxCloneService<Request<B>, Response<BoxBody>, Infallible>,
54}
55
56impl<B> Route<B> {
57 pub fn new<T>(svc: T) -> Self
59 where
60 T: Service<Request<B>, Response = Response<BoxBody>, Error = Infallible> + Clone + Send + 'static,
61 T::Future: Send + 'static,
62 {
63 Self {
64 service: BoxCloneService::new(svc),
65 }
66 }
67}
68
69impl<ReqBody> Clone for Route<ReqBody> {
70 fn clone(&self) -> Self {
71 Self {
72 service: self.service.clone(),
73 }
74 }
75}
76
77impl<ReqBody> fmt::Debug for Route<ReqBody> {
78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 f.debug_struct("Route").finish()
80 }
81}
82
83impl<B> Service<Request<B>> for Route<B> {
84 type Response = Response<BoxBody>;
85 type Error = Infallible;
86 type Future = RouteFuture<B>;
87
88 #[inline]
89 fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
90 Poll::Ready(Ok(()))
91 }
92
93 #[inline]
94 fn call(&mut self, req: Request<B>) -> Self::Future {
95 RouteFuture::new(self.service.clone().oneshot(req))
96 }
97}
98
99pin_project_lite::pin_project! {
100 pub struct RouteFuture<B> {
102 #[pin]
103 future: Oneshot<BoxCloneService<Request<B>, Response<BoxBody>, Infallible>, Request<B>>,
104 }
105}
106
107impl<B> RouteFuture<B> {
108 pub(crate) fn new(future: Oneshot<BoxCloneService<Request<B>, Response<BoxBody>, Infallible>, Request<B>>) -> Self {
109 RouteFuture { future }
110 }
111}
112
113impl<B> Future for RouteFuture<B> {
114 type Output = Result<Response<BoxBody>, Infallible>;
115
116 #[inline]
117 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
118 self.project().future.poll(cx)
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125
126 #[test]
127 fn traits() {
128 use crate::test_helpers::*;
129
130 assert_send::<Route<()>>();
131 }
132}