1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//! See [`yield`] and [`Yield`].

use std::{
	future::Future,
	pin::Pin,
	task::{Context, Poll},
};

/// Yields to the executor once.
///
/// # Examples
/// ```
/// # futures_executor::block_on(async {
/// use std::task::Poll;
///
/// use allochronic_util::{poll, r#yield};
///
/// let mut future = async {
/// 	r#yield().await;
/// 	1
/// };
/// futures_util::pin_mut!(future);
///
/// assert_eq!(Poll::Pending, poll(&mut future).await);
/// assert_eq!(Poll::Ready(1), poll(future).await);
/// # });
/// ```
pub const fn r#yield() -> Yield {
	Yield::new()
}

/// Yields to the executor once. See [`yield`] for easier usage.
///
/// # Examples
/// ```
/// # futures_executor::block_on(async {
/// use std::task::Poll;
///
/// use allochronic_util::{poll, Yield};
///
/// let mut future = async {
/// 	Yield::new().await;
/// 	1
/// };
/// futures_util::pin_mut!(future);
///
/// assert_eq!(Poll::Pending, poll(&mut future).await);
/// assert_eq!(Poll::Ready(1), poll(future).await);
/// # });
/// ```
#[allow(missing_copy_implementations)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
#[derive(Debug)]
pub struct Yield(bool);

impl Yield {
	/// Builds a new [`Yield`].
	pub const fn new() -> Self {
		Self(false)
	}
}

impl Future for Yield {
	type Output = ();

	fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
		if self.0 {
			Poll::Ready(())
		} else {
			self.0 = true;
			// the task is ready immediately
			cx.waker().wake_by_ref();
			Poll::Pending
		}
	}
}