1
1
use std:: pin:: Pin ;
2
+ use pin_project_lite:: pin_project;
2
3
3
4
use crate :: prelude:: * ;
4
5
use crate :: stream:: stream:: map:: Map ;
5
6
use crate :: stream:: { IntoStream , Stream } ;
6
7
use crate :: task:: { Context , Poll } ;
7
8
8
- /// This `struct` is created by the [`flat_map`] method on [`Stream`]. See its
9
- /// documentation for more.
10
- ///
11
- /// [`flat_map`]: trait.Stream.html#method.flat_map
12
- /// [`Stream`]: trait.Stream.html
13
- #[ allow( missing_debug_implementations) ]
14
- pub struct FlatMap < S : Stream , U : IntoStream , F > {
15
- inner : FlattenCompat < Map < S , F , S :: Item , U > , U > ,
9
+ pin_project ! {
10
+ /// This `struct` is created by the [`flat_map`] method on [`Stream`]. See its
11
+ /// documentation for more.
12
+ ///
13
+ /// [`flat_map`]: trait.Stream.html#method.flat_map
14
+ /// [`Stream`]: trait.Stream.html
15
+ #[ allow( missing_debug_implementations) ]
16
+ pub struct FlatMap <S : Stream , U : IntoStream , F > {
17
+ #[ pin]
18
+ inner: FlattenCompat <Map <S , F , S :: Item , U >, U >,
19
+ }
16
20
}
17
21
18
22
impl < S , U , F > FlatMap < S , U , F >
21
25
U : IntoStream ,
22
26
F : FnMut ( S :: Item ) -> U ,
23
27
{
24
- pin_utils:: unsafe_pinned!( inner: FlattenCompat <Map <S , F , S :: Item , U >, U >) ;
25
28
26
29
pub fn new ( stream : S , f : F ) -> FlatMap < S , U , F > {
27
30
FlatMap {
@@ -33,33 +36,33 @@ where
33
36
impl < S , U , F > Stream for FlatMap < S , U , F >
34
37
where
35
38
S : Stream < Item : IntoStream < IntoStream = U , Item = U :: Item > > + std:: marker:: Unpin ,
36
- S :: Item : std:: marker:: Unpin ,
37
39
U : Stream + std:: marker:: Unpin ,
38
- F : FnMut ( S :: Item ) -> U + std :: marker :: Unpin ,
40
+ F : FnMut ( S :: Item ) -> U ,
39
41
{
40
42
type Item = U :: Item ;
41
43
42
- fn poll_next ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
43
- self . as_mut ( ) . inner ( ) . poll_next ( cx)
44
+ fn poll_next ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
45
+ self . project ( ) . inner . poll_next ( cx)
44
46
}
45
47
}
46
48
47
- /// This `struct` is created by the [`flatten`] method on [`Stream`]. See its
48
- /// documentation for more.
49
- ///
50
- /// [`flatten`]: trait.Stream.html#method.flatten
51
- /// [`Stream`]: trait.Stream.html
52
- #[ allow( missing_debug_implementations) ]
53
- pub struct Flatten < S : Stream >
54
- where
55
- S :: Item : IntoStream ,
56
- {
57
- inner : FlattenCompat < S , <S :: Item as IntoStream >:: IntoStream > ,
49
+ pin_project ! {
50
+ /// This `struct` is created by the [`flatten`] method on [`Stream`]. See its
51
+ /// documentation for more.
52
+ ///
53
+ /// [`flatten`]: trait.Stream.html#method.flatten
54
+ /// [`Stream`]: trait.Stream.html
55
+ #[ allow( missing_debug_implementations) ]
56
+ pub struct Flatten <S : Stream >
57
+ where
58
+ S :: Item : IntoStream ,
59
+ {
60
+ #[ pin]
61
+ inner: FlattenCompat <S , <S :: Item as IntoStream >:: IntoStream >,
62
+ }
58
63
}
59
64
60
65
impl < S : Stream < Item : IntoStream > > Flatten < S > {
61
- pin_utils:: unsafe_pinned!( inner: FlattenCompat <S , <S :: Item as IntoStream >:: IntoStream >) ;
62
-
63
66
pub fn new ( stream : S ) -> Flatten < S > {
64
67
Flatten { inner : FlattenCompat :: new ( stream) }
65
68
}
@@ -72,24 +75,23 @@ where
72
75
{
73
76
type Item = U :: Item ;
74
77
75
- fn poll_next ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
76
- self . as_mut ( ) . inner ( ) . poll_next ( cx)
78
+ fn poll_next ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
79
+ self . project ( ) . inner . poll_next ( cx)
77
80
}
78
81
}
79
82
80
83
81
- /// Real logic of both `Flatten` and `FlatMap` which simply delegate to
82
- /// this type.
83
- #[ derive( Clone , Debug ) ]
84
- struct FlattenCompat < S , U > {
85
- stream : S ,
86
- frontiter : Option < U > ,
84
+ pin_project ! {
85
+ /// Real logic of both `Flatten` and `FlatMap` which simply delegate to
86
+ /// this type.
87
+ #[ derive( Clone , Debug ) ]
88
+ struct FlattenCompat <S , U > {
89
+ stream: S ,
90
+ frontiter: Option <U >,
91
+ }
87
92
}
88
93
89
94
impl < S , U > FlattenCompat < S , U > {
90
- pin_utils:: unsafe_unpinned!( stream: S ) ;
91
- pin_utils:: unsafe_unpinned!( frontiter: Option <U >) ;
92
-
93
95
/// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`.
94
96
pub fn new ( stream : S ) -> FlattenCompat < S , U > {
95
97
FlattenCompat {
@@ -106,17 +108,18 @@ where
106
108
{
107
109
type Item = U :: Item ;
108
110
109
- fn poll_next ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
111
+ fn poll_next ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
112
+ let mut this = self . project ( ) ;
110
113
loop {
111
- if let Some ( ref mut inner) = self . as_mut ( ) . frontiter ( ) {
114
+ if let Some ( inner) = this . frontiter {
112
115
if let item @ Some ( _) = futures_core:: ready!( Pin :: new( inner) . poll_next( cx) ) {
113
116
return Poll :: Ready ( item) ;
114
117
}
115
118
}
116
119
117
- match futures_core:: ready!( Pin :: new( & mut self . stream) . poll_next( cx) ) {
120
+ match futures_core:: ready!( Pin :: new( & mut this . stream) . poll_next( cx) ) {
118
121
None => return Poll :: Ready ( None ) ,
119
- Some ( inner) => * self . as_mut ( ) . frontiter ( ) = Some ( inner. into_stream ( ) ) ,
122
+ Some ( inner) => * this . frontiter = Some ( inner. into_stream ( ) ) ,
120
123
}
121
124
}
122
125
}
0 commit comments