1- use std:: marker:: PhantomData ;
21use std:: pin:: Pin ;
3- use std:: future:: Future ;
4-
5- use pin_project_lite:: pin_project;
62
73use crate :: stream:: Stream ;
84use crate :: task:: { Context , Poll } ;
95
10- pin_project ! {
11- /// A stream that yields elements by calling a closure.
12- ///
13- /// This stream is created by the [`from_fn`] function. See its
14- /// documentation for more.
15- ///
16- /// [`from_fn`]: fn.from_fn.html
17- #[ derive( Debug ) ]
18- pub struct FromFn <F , Fut , T > {
19- f: F ,
20- #[ pin]
21- future: Option <Fut >,
22- __t: PhantomData <T >,
23- }
6+ /// A stream that yields elements by calling a closure.
7+ ///
8+ /// This stream is created by the [`from_fn`] function. See its
9+ /// documentation for more.
10+ ///
11+ /// [`from_fn`]: fn.from_fn.html
12+ #[ derive( Clone , Debug ) ]
13+ pub struct FromFn < F > {
14+ f : F ,
2415}
2516
17+ impl < F > Unpin for FromFn < F > { }
18+
2619/// Creates a new stream where to produce each new element a provided closure is called.
2720///
2821/// This allows creating a custom stream with any behaviour without using the more verbose
@@ -34,22 +27,15 @@ pin_project! {
3427/// # async_std::task::block_on(async {
3528/// #
3629/// use async_std::prelude::*;
37- /// use async_std::sync::Mutex;
38- /// use std::sync::Arc;
3930/// use async_std::stream;
4031///
41- /// let count = Arc::new(Mutex::new( 0u8)) ;
32+ /// let mut count = 0u8;
4233/// let s = stream::from_fn(|| {
43- /// let count = Arc::clone(&count);
44- ///
45- /// async move {
46- /// *count.lock().await += 1;
47- ///
48- /// if *count.lock().await > 3 {
49- /// None
50- /// } else {
51- /// Some(*count.lock().await)
52- /// }
34+ /// count += 1;
35+ /// if count > 3 {
36+ /// None
37+ /// } else {
38+ /// Some(count)
5339/// }
5440/// });
5541///
@@ -61,38 +47,21 @@ pin_project! {
6147/// #
6248/// # })
6349/// ```
64- pub fn from_fn < T , F , Fut > ( f : F ) -> FromFn < F , Fut , T >
50+ pub fn from_fn < T , F > ( f : F ) -> FromFn < F >
6551where
66- F : FnMut ( ) -> Fut ,
67- Fut : Future < Output = Option < T > > ,
52+ F : FnMut ( ) -> Option < T > ,
6853{
69- FromFn {
70- f,
71- future : None ,
72- __t : PhantomData ,
73- }
54+ FromFn { f }
7455}
7556
76- impl < F , Fut , T > Stream for FromFn < F , Fut , T >
57+ impl < T , F > Stream for FromFn < F >
7758where
78- F : FnMut ( ) -> Fut ,
79- Fut : Future < Output = Option < T > > ,
59+ F : FnMut ( ) -> Option < T > ,
8060{
8161 type Item = T ;
8262
83- fn poll_next ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
84- let mut this = self . project ( ) ;
85- loop {
86- if this. future . is_some ( ) {
87- let next =
88- futures_core:: ready!( this. future. as_mut( ) . as_pin_mut( ) . unwrap( ) . poll( cx) ) ;
89- this. future . set ( None ) ;
90-
91- return Poll :: Ready ( next) ;
92- } else {
93- let fut = ( this. f ) ( ) ;
94- this. future . set ( Some ( fut) ) ;
95- }
96- }
63+ fn poll_next ( mut self : Pin < & mut Self > , _: & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
64+ let item = ( & mut self . f ) ( ) ;
65+ Poll :: Ready ( item)
9766 }
9867}
0 commit comments