1use std::{
16 fmt,
17 task::{Context, Poll},
18};
19
20use bytes::Bytes;
21use futures_util::future::BoxFuture;
22use tower::{BoxError, Service, ServiceExt};
23
24pub type HttpService = BoxCloneSyncService<http::Request<Bytes>, http::Response<Bytes>, BoxError>;
29
30impl fmt::Debug for HttpService {
31 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
32 fmt.debug_struct("HttpService").finish()
33 }
34}
35
36#[allow(clippy::type_complexity)]
41pub struct BoxCloneSyncService<T, U, E>(
42 Box<
43 dyn CloneSyncService<T, Response = U, Error = E, Future = BoxFuture<'static, Result<U, E>>>,
44 >,
45);
46
47impl<T, U, E> BoxCloneSyncService<T, U, E> {
48 pub fn new<S>(inner: S) -> Self
50 where
51 S: Service<T, Response = U, Error = E> + Clone + Send + Sync + 'static,
52 S::Future: Send + 'static,
53 {
54 let inner = inner.map_future(|f| Box::pin(f) as _);
55 Self(Box::new(inner))
56 }
57}
58
59impl<T, U, E> Service<T> for BoxCloneSyncService<T, U, E> {
60 type Response = U;
61 type Error = E;
62 type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
63
64 #[inline]
65 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
66 self.0.poll_ready(cx)
67 }
68
69 #[inline]
70 fn call(&mut self, request: T) -> Self::Future {
71 self.0.call(request)
72 }
73}
74
75impl<T, U, E> Clone for BoxCloneSyncService<T, U, E> {
76 fn clone(&self) -> Self {
77 Self(self.0.clone_sync_box())
78 }
79}
80
81trait CloneSyncService<R>: Service<R> + Send + Sync {
82 fn clone_sync_box(
83 &self,
84 ) -> Box<
85 dyn CloneSyncService<
86 R,
87 Response = Self::Response,
88 Error = Self::Error,
89 Future = Self::Future,
90 >,
91 >;
92}
93
94impl<R, T> CloneSyncService<R> for T
95where
96 T: Service<R> + Send + Sync + Clone + 'static,
97{
98 fn clone_sync_box(
99 &self,
100 ) -> Box<dyn CloneSyncService<R, Response = T::Response, Error = T::Error, Future = T::Future>>
101 {
102 Box::new(self.clone())
103 }
104}