1#![no_std]
3#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)]
4
5pub mod prelude;
6
7#[doc(no_inline)]
8pub use core::future::Future;
9#[doc(no_inline)]
10pub use core::pin::Pin;
11#[doc(no_inline)]
12pub use core::task::{Context, Poll, Waker};
13
14use core::fmt;
15
16use pin_project_lite::pin_project;
17
18#[inline(always)]
38pub fn poll_fn<F, T>(inner: F) -> PollFn<F>
39where
40 F: FnMut(&mut Context<'_>) -> Poll<T>,
41{
42 PollFn { inner }
43}
44
45pin_project! {
46 #[must_use = "futures do nothing unless you `.await` or poll them"]
48 pub struct PollFn<F> {
49 inner: F,
50 }
51}
52
53impl<F> fmt::Debug for PollFn<F> {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 f.debug_struct("PollFn").finish()
56 }
57}
58
59impl<F, T> Future for PollFn<F>
60where
61 F: FnMut(&mut Context<'_>) -> Poll<T>,
62{
63 type Output = T;
64 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<T> {
65 let this = self.project();
66 (this.inner)(ctx)
67 }
68}
69
70pin_project! {
71 #[derive(Debug)]
73 #[must_use = "futures do nothing unless you `.await` or poll them"]
74 pub struct Or<F1, F2> {
75 #[pin]
76 future1: F1,
77 #[pin]
78 future2: F2,
79 }
80}
81
82impl<F1, F2> Or<F1, F2>
83where
84 F1: Future,
85 F2: Future,
86{
87 pub fn new(future1: F1, future2: F2) -> Self {
89 Or { future1, future2 }
90 }
91}
92
93impl<T, F1, F2> Future for Or<F1, F2>
94where
95 F1: Future<Output = T>,
96 F2: Future<Output = T>,
97{
98 type Output = T;
99
100 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
101 let this = self.project();
102
103 if let Poll::Ready(t) = this.future1.poll(cx) {
104 Poll::Ready(t)
105 } else if let Poll::Ready(t) = this.future2.poll(cx) {
106 Poll::Ready(t)
107 } else {
108 Poll::Pending
109 }
110 }
111}
112
113pin_project! {
114 #[derive(Debug)]
116 #[must_use = "futures do nothing unless you `.await` or poll them"]
117 pub struct Zip<F1, F2>
118 where
119 F1: Future,
120 F2: Future,
121 {
122 #[pin]
123 future1: F1,
124 output1: Option<F1::Output>,
125 #[pin]
126 future2: F2,
127 output2: Option<F2::Output>,
128 }
129}
130
131impl<F1, F2> Zip<F1, F2>
132where
133 F1: Future,
134 F2: Future,
135{
136 pub fn new(future1: F1, future2: F2) -> Self {
151 Zip {
152 future1,
153 future2,
154 output1: None,
155 output2: None,
156 }
157 }
158}
159
160impl<F1, F2> Future for Zip<F1, F2>
161where
162 F1: Future,
163 F2: Future,
164{
165 type Output = (F1::Output, F2::Output);
166
167 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
168 let this = self.project();
169
170 if this.output1.is_none() {
171 if let Poll::Ready(out) = this.future1.poll(cx) {
172 *this.output1 = Some(out);
173 }
174 }
175
176 if this.output2.is_none() {
177 if let Poll::Ready(out) = this.future2.poll(cx) {
178 *this.output2 = Some(out);
179 }
180 }
181
182 if this.output1.is_some() && this.output2.is_some() {
183 Poll::Ready((this.output1.take().unwrap(), this.output2.take().unwrap()))
184 } else {
185 Poll::Pending
186 }
187 }
188}
189
190pub fn waker() -> impl Future<Output = Waker> {
207 poll_fn(|ctx| Poll::Ready(ctx.waker().clone()))
208}
209
210pub fn sleep() -> impl Future<Output = ()> {
226 let mut done = false;
227 poll_fn(move |_| {
228 if done {
229 Poll::Ready(())
230 } else {
231 done = true;
232 Poll::Pending
233 }
234 })
235}
236
237
238pub fn yield_once() -> impl Future<Output = ()> {
241 let mut done = false;
242 poll_fn(move |ctx| {
243 if done {
244 Poll::Ready(())
245 } else {
246 done = true;
247 ctx.waker().wake_by_ref();
248 Poll::Pending }
249 })
250}
251
252#[doc(hidden)]
256#[macro_export]
257macro_rules! __internal_fold_with {
258 ($func:path, $e:expr) => { $e };
259 ($func:path, $e:expr, $($es:expr),+) => {
260 $func($e, $crate::__internal_fold_with!($func, $($es),+))
261 };
262}
263
264#[macro_export]
269macro_rules! or {
270 ($($es:expr),+$(,)?) => { $crate::__internal_fold_with!($crate::Or::new, $($es),+) };
271}
272
273#[macro_export]
292macro_rules! pin {
293 ($($x:ident),* $(,)?) => {
294 $(
295 let mut $x = $x;
296 #[allow(unused_mut)]
297 let mut $x = unsafe {
298 core::pin::Pin::new_unchecked(&mut $x)
299 };
300 )*
301 }
302}
303
304#[macro_export]
323macro_rules! ready {
324 ($e:expr $(,)?) => {
325 match $e {
326 core::task::Poll::Ready(t) => t,
327 t @ core::task::Poll::Pending => return t,
328 }
329 };
330}
331
332#[macro_export]
347macro_rules! zip {
348 ($($es:expr),+ $(,)?) => {{
349 let mut zips = $crate::__internal_fold_with!($crate::Zip::new, $($es),+);
350 $crate::poll_fn(move |ctx| {
351 use ::core::pin::Pin;
352 use ::core::task::Poll;
353
354 let zips = unsafe { Pin::new_unchecked(&mut zips) };
355 if let Poll::Ready(val) = ::core::future::Future::poll(zips, ctx) {
356 Poll::Ready($crate::zip!(@flatten; ; val; $($es),+))
357 } else {
358 Poll::Pending
359 }
360 })
361 }};
362
363 (@flatten; $($prev:expr,)*; $tuple:expr; $e:expr) => {
364 ($($prev,)* $tuple)
365 };
366
367 (@flatten; $($prev:expr,)*; $tuple:expr; $e:expr, $($es:expr),+) => {
368 $crate::zip!(@flatten; $($prev,)* $tuple.0,; $tuple.1; $($es),+)
369 };
370}