1 | //! Definition of the `PollFn` combinator |
2 | |
3 | use super::assert_stream; |
4 | use core::fmt; |
5 | use core::pin::Pin; |
6 | use futures_core::stream::Stream; |
7 | use futures_core::task::{Context, Poll}; |
8 | |
9 | /// Stream for the [`poll_fn`] function. |
10 | #[must_use = "streams do nothing unless polled" ] |
11 | pub struct PollFn<F> { |
12 | f: F, |
13 | } |
14 | |
15 | impl<F> Unpin for PollFn<F> {} |
16 | |
17 | impl<F> fmt::Debug for PollFn<F> { |
18 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
19 | f.debug_struct("PollFn" ).finish() |
20 | } |
21 | } |
22 | |
23 | /// Creates a new stream wrapping a function returning `Poll<Option<T>>`. |
24 | /// |
25 | /// Polling the returned stream calls the wrapped function. |
26 | /// |
27 | /// # Examples |
28 | /// |
29 | /// ``` |
30 | /// use futures::stream::poll_fn; |
31 | /// use futures::task::Poll; |
32 | /// |
33 | /// let mut counter = 1usize; |
34 | /// |
35 | /// let read_stream = poll_fn(move |_| -> Poll<Option<String>> { |
36 | /// if counter == 0 { return Poll::Ready(None); } |
37 | /// counter -= 1; |
38 | /// Poll::Ready(Some("Hello, World!" .to_owned())) |
39 | /// }); |
40 | /// ``` |
41 | pub fn poll_fn<T, F>(f: F) -> PollFn<F> |
42 | where |
43 | F: FnMut(&mut Context<'_>) -> Poll<Option<T>>, |
44 | { |
45 | assert_stream::<T, _>(PollFn { f }) |
46 | } |
47 | |
48 | impl<T, F> Stream for PollFn<F> |
49 | where |
50 | F: FnMut(&mut Context<'_>) -> Poll<Option<T>>, |
51 | { |
52 | type Item = T; |
53 | |
54 | fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<T>> { |
55 | (&mut self.f)(cx) |
56 | } |
57 | } |
58 | |