1 | use crate::fmt; |
2 | use crate::future::Future; |
3 | use crate::pin::Pin; |
4 | use crate::task::{Context, Poll}; |
5 | |
6 | /// Creates a future that wraps a function returning [`Poll`]. |
7 | /// |
8 | /// Polling the future delegates to the wrapped function. If the returned future is pinned, then the |
9 | /// captured environment of the wrapped function is also pinned in-place, so as long as the closure |
10 | /// does not move out of its captures it can soundly create pinned references to them. |
11 | /// |
12 | /// # Examples |
13 | /// |
14 | /// ``` |
15 | /// # async fn run() { |
16 | /// use core::future::poll_fn; |
17 | /// use std::task::{Context, Poll}; |
18 | /// |
19 | /// fn read_line(_cx: &mut Context<'_>) -> Poll<String> { |
20 | /// Poll::Ready("Hello, World!" .into()) |
21 | /// } |
22 | /// |
23 | /// let read_future = poll_fn(read_line); |
24 | /// assert_eq!(read_future.await, "Hello, World!" .to_owned()); |
25 | /// # } |
26 | /// ``` |
27 | /// |
28 | /// ## Capturing a pinned state |
29 | /// |
30 | /// Example of a closure wrapping inner futures: |
31 | /// |
32 | /// ``` |
33 | /// # async fn run() { |
34 | /// use core::future::{self, Future}; |
35 | /// use core::task::Poll; |
36 | /// |
37 | /// /// Resolves to the first future that completes. In the event of a tie, `a` wins. |
38 | /// fn naive_select<T>( |
39 | /// a: impl Future<Output = T>, |
40 | /// b: impl Future<Output = T>, |
41 | /// ) -> impl Future<Output = T> |
42 | /// { |
43 | /// let (mut a, mut b) = (Box::pin(a), Box::pin(b)); |
44 | /// future::poll_fn(move |cx| { |
45 | /// if let Poll::Ready(r) = a.as_mut().poll(cx) { |
46 | /// Poll::Ready(r) |
47 | /// } else if let Poll::Ready(r) = b.as_mut().poll(cx) { |
48 | /// Poll::Ready(r) |
49 | /// } else { |
50 | /// Poll::Pending |
51 | /// } |
52 | /// }) |
53 | /// } |
54 | /// |
55 | /// let a = async { 42 }; |
56 | /// let b = future::pending(); |
57 | /// let v = naive_select(a, b).await; |
58 | /// assert_eq!(v, 42); |
59 | /// |
60 | /// let a = future::pending(); |
61 | /// let b = async { 27 }; |
62 | /// let v = naive_select(a, b).await; |
63 | /// assert_eq!(v, 27); |
64 | /// |
65 | /// let a = async { 42 }; |
66 | /// let b = async { 27 }; |
67 | /// let v = naive_select(a, b).await; |
68 | /// assert_eq!(v, 42); // biased towards `a` in case of tie! |
69 | /// # } |
70 | /// ``` |
71 | /// |
72 | /// This time without [`Box::pin`]ning: |
73 | /// |
74 | /// [`Box::pin`]: ../../std/boxed/struct.Box.html#method.pin |
75 | /// |
76 | /// ``` |
77 | /// # async fn run() { |
78 | /// use core::future::{self, Future}; |
79 | /// use core::pin::pin; |
80 | /// use core::task::Poll; |
81 | /// |
82 | /// /// Resolves to the first future that completes. In the event of a tie, `a` wins. |
83 | /// fn naive_select<T>( |
84 | /// a: impl Future<Output = T>, |
85 | /// b: impl Future<Output = T>, |
86 | /// ) -> impl Future<Output = T> |
87 | /// { |
88 | /// async { |
89 | /// let (mut a, mut b) = (pin!(a), pin!(b)); |
90 | /// future::poll_fn(move |cx| { |
91 | /// if let Poll::Ready(r) = a.as_mut().poll(cx) { |
92 | /// Poll::Ready(r) |
93 | /// } else if let Poll::Ready(r) = b.as_mut().poll(cx) { |
94 | /// Poll::Ready(r) |
95 | /// } else { |
96 | /// Poll::Pending |
97 | /// } |
98 | /// }).await |
99 | /// } |
100 | /// } |
101 | /// |
102 | /// let a = async { 42 }; |
103 | /// let b = future::pending(); |
104 | /// let v = naive_select(a, b).await; |
105 | /// assert_eq!(v, 42); |
106 | /// # } |
107 | /// ``` |
108 | /// |
109 | /// - Notice how, by virtue of being in an `async` context, we have been able to make the [`pin!`] |
110 | /// macro work, thereby avoiding any need for the `unsafe` |
111 | /// <code>[Pin::new_unchecked](&mut fut)</code> constructor. |
112 | /// |
113 | /// [`pin!`]: crate::pin::pin! |
114 | #[stable (feature = "future_poll_fn" , since = "1.64.0" )] |
115 | pub fn poll_fn<T, F>(f: F) -> PollFn<F> |
116 | where |
117 | F: FnMut(&mut Context<'_>) -> Poll<T>, |
118 | { |
119 | PollFn { f } |
120 | } |
121 | |
122 | /// A Future that wraps a function returning [`Poll`]. |
123 | /// |
124 | /// This `struct` is created by [`poll_fn()`]. See its |
125 | /// documentation for more. |
126 | #[must_use = "futures do nothing unless you `.await` or poll them" ] |
127 | #[stable (feature = "future_poll_fn" , since = "1.64.0" )] |
128 | pub struct PollFn<F> { |
129 | f: F, |
130 | } |
131 | |
132 | #[stable (feature = "future_poll_fn" , since = "1.64.0" )] |
133 | impl<F: Unpin> Unpin for PollFn<F> {} |
134 | |
135 | #[stable (feature = "future_poll_fn" , since = "1.64.0" )] |
136 | impl<F> fmt::Debug for PollFn<F> { |
137 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
138 | f.debug_struct(name:"PollFn" ).finish() |
139 | } |
140 | } |
141 | |
142 | #[stable (feature = "future_poll_fn" , since = "1.64.0" )] |
143 | impl<T, F> Future for PollFn<F> |
144 | where |
145 | F: FnMut(&mut Context<'_>) -> Poll<T>, |
146 | { |
147 | type Output = T; |
148 | |
149 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> { |
150 | // SAFETY: We are not moving out of the pinned field. |
151 | (unsafe { &mut self.get_unchecked_mut().f })(cx) |
152 | } |
153 | } |
154 | |