1#[macro_export]
31macro_rules! always_ready {
32    () => {
33        #[inline]
34        fn poll_ready(
35            &self,
36            _: &mut ::core::task::Context<'_>,
37        ) -> ::core::task::Poll<Result<(), Self::Error>> {
38            ::core::task::Poll::Ready(Ok(()))
39        }
40    };
41}
42
43#[macro_export]
75macro_rules! forward_ready {
76    ($field:ident) => {
77        #[inline]
78        fn poll_ready(
79            &self,
80            cx: &mut ::core::task::Context<'_>,
81        ) -> ::core::task::Poll<Result<(), Self::Error>> {
82            self.$field
83                .poll_ready(cx)
84                .map_err(::core::convert::Into::into)
85        }
86    };
87}
88
89#[cfg(test)]
90mod tests {
91    use core::{
92        cell::Cell,
93        convert::Infallible,
94        task::{self, Context, Poll},
95    };
96
97    use futures_util::{
98        future::{ready, Ready},
99        task::noop_waker,
100    };
101
102    use crate::Service;
103
104    struct IdentityService;
105
106    impl Service<u32> for IdentityService {
107        type Response = u32;
108        type Error = Infallible;
109        type Future = Ready<Result<Self::Response, Self::Error>>;
110
111        always_ready!();
112
113        fn call(&self, req: u32) -> Self::Future {
114            ready(Ok(req))
115        }
116    }
117
118    struct CountdownService(Cell<u32>);
119
120    impl Service<()> for CountdownService {
121        type Response = ();
122        type Error = Infallible;
123        type Future = Ready<Result<Self::Response, Self::Error>>;
124
125        fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
126            let count = self.0.get();
127
128            if count == 0 {
129                Poll::Ready(Ok(()))
130            } else {
131                self.0.set(count - 1);
132                cx.waker().wake_by_ref();
133                Poll::Pending
134            }
135        }
136
137        fn call(&self, _: ()) -> Self::Future {
138            ready(Ok(()))
139        }
140    }
141
142    struct WrapperService<S> {
143        inner: S,
144    }
145
146    impl<S> Service<()> for WrapperService<S>
147    where
148        S: Service<()>,
149    {
150        type Response = S::Response;
151        type Error = S::Error;
152        type Future = S::Future;
153
154        forward_ready!(inner);
155
156        fn call(&self, _: ()) -> Self::Future {
157            self.inner.call(())
158        }
159    }
160
161    #[test]
162    fn test_always_ready_macro() {
163        let waker = noop_waker();
164        let mut cx = task::Context::from_waker(&waker);
165
166        let svc = IdentityService;
167
168        assert!(svc.poll_ready(&mut cx).is_ready());
169        assert!(svc.poll_ready(&mut cx).is_ready());
170        assert!(svc.poll_ready(&mut cx).is_ready());
171    }
172
173    #[test]
174    fn test_forward_ready_macro() {
175        let waker = noop_waker();
176        let mut cx = task::Context::from_waker(&waker);
177
178        let svc = WrapperService {
179            inner: CountdownService(Cell::new(3)),
180        };
181
182        assert!(svc.poll_ready(&mut cx).is_pending());
183        assert!(svc.poll_ready(&mut cx).is_pending());
184        assert!(svc.poll_ready(&mut cx).is_pending());
185        assert!(svc.poll_ready(&mut cx).is_ready());
186    }
187}