tower_util/boxed/
unsync.rs

1use tower_service::Service;
2
3use std::fmt;
4use std::{
5    future::Future,
6    pin::Pin,
7    task::{Context, Poll},
8};
9
10/// A boxed `Service` trait object.
11pub struct UnsyncBoxService<T, U, E> {
12    inner: Box<dyn Service<T, Response = U, Error = E, Future = UnsyncBoxFuture<U, E>>>,
13}
14
15/// A boxed `Future` trait object.
16///
17/// This type alias represents a boxed future that is *not* `Send` and must
18/// remain on the current thread.
19type UnsyncBoxFuture<T, E> = Pin<Box<dyn Future<Output = Result<T, E>>>>;
20
21#[derive(Debug)]
22struct UnsyncBoxed<S> {
23    inner: S,
24}
25
26impl<T, U, E> UnsyncBoxService<T, U, E> {
27    #[allow(missing_docs)]
28    pub fn new<S>(inner: S) -> Self
29    where
30        S: Service<T, Response = U, Error = E> + 'static,
31        S::Future: 'static,
32    {
33        let inner = Box::new(UnsyncBoxed { inner });
34        UnsyncBoxService { inner }
35    }
36}
37
38impl<T, U, E> Service<T> for UnsyncBoxService<T, U, E> {
39    type Response = U;
40    type Error = E;
41    type Future = UnsyncBoxFuture<U, E>;
42
43    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), E>> {
44        self.inner.poll_ready(cx)
45    }
46
47    fn call(&mut self, request: T) -> UnsyncBoxFuture<U, E> {
48        self.inner.call(request)
49    }
50}
51
52impl<T, U, E> fmt::Debug for UnsyncBoxService<T, U, E>
53where
54    T: fmt::Debug,
55    U: fmt::Debug,
56    E: fmt::Debug,
57{
58    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
59        fmt.debug_struct("UnsyncBoxService").finish()
60    }
61}
62
63impl<S, Request> Service<Request> for UnsyncBoxed<S>
64where
65    S: Service<Request> + 'static,
66    S::Future: 'static,
67{
68    type Response = S::Response;
69    type Error = S::Error;
70    type Future = Pin<Box<dyn Future<Output = Result<S::Response, S::Error>>>>;
71
72    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
73        self.inner.poll_ready(cx)
74    }
75
76    fn call(&mut self, request: Request) -> Self::Future {
77        Box::pin(self.inner.call(request))
78    }
79}