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}