@@ -25,167 +25,30 @@ use crate::{
25
25
Multiaddr , ProtocolName ,
26
26
} ;
27
27
use either:: Either ;
28
- use futures:: {
29
- io:: { IoSlice , IoSliceMut } ,
30
- prelude:: * ,
31
- } ;
28
+ use futures:: prelude:: * ;
32
29
use pin_project:: pin_project;
33
- use std:: { io, pin:: Pin , task:: Context , task:: Poll } ;
34
-
35
- /// Implements `AsyncRead` and `AsyncWrite` and dispatches all method calls to
36
- /// either `First` or `Second`.
37
- #[ pin_project( project = EitherOutputProj ) ]
38
- #[ derive( Debug , Copy , Clone ) ]
39
- pub enum EitherOutput < A , B > {
40
- First ( #[ pin] A ) ,
41
- Second ( #[ pin] B ) ,
42
- }
43
-
44
- impl < A , B > AsyncRead for EitherOutput < A , B >
45
- where
46
- A : AsyncRead ,
47
- B : AsyncRead ,
48
- {
49
- fn poll_read (
50
- self : Pin < & mut Self > ,
51
- cx : & mut Context < ' _ > ,
52
- buf : & mut [ u8 ] ,
53
- ) -> Poll < io:: Result < usize > > {
54
- match self . project ( ) {
55
- EitherOutputProj :: First ( a) => AsyncRead :: poll_read ( a, cx, buf) ,
56
- EitherOutputProj :: Second ( b) => AsyncRead :: poll_read ( b, cx, buf) ,
57
- }
58
- }
30
+ use std:: { pin:: Pin , task:: Context , task:: Poll } ;
59
31
60
- fn poll_read_vectored (
61
- self : Pin < & mut Self > ,
62
- cx : & mut Context < ' _ > ,
63
- bufs : & mut [ IoSliceMut < ' _ > ] ,
64
- ) -> Poll < io:: Result < usize > > {
65
- match self . project ( ) {
66
- EitherOutputProj :: First ( a) => AsyncRead :: poll_read_vectored ( a, cx, bufs) ,
67
- EitherOutputProj :: Second ( b) => AsyncRead :: poll_read_vectored ( b, cx, bufs) ,
68
- }
69
- }
70
- }
71
-
72
- impl < A , B > AsyncWrite for EitherOutput < A , B >
73
- where
74
- A : AsyncWrite ,
75
- B : AsyncWrite ,
76
- {
77
- fn poll_write (
78
- self : Pin < & mut Self > ,
79
- cx : & mut Context < ' _ > ,
80
- buf : & [ u8 ] ,
81
- ) -> Poll < io:: Result < usize > > {
82
- match self . project ( ) {
83
- EitherOutputProj :: First ( a) => AsyncWrite :: poll_write ( a, cx, buf) ,
84
- EitherOutputProj :: Second ( b) => AsyncWrite :: poll_write ( b, cx, buf) ,
85
- }
86
- }
87
-
88
- fn poll_write_vectored (
89
- self : Pin < & mut Self > ,
90
- cx : & mut Context < ' _ > ,
91
- bufs : & [ IoSlice < ' _ > ] ,
92
- ) -> Poll < io:: Result < usize > > {
93
- match self . project ( ) {
94
- EitherOutputProj :: First ( a) => AsyncWrite :: poll_write_vectored ( a, cx, bufs) ,
95
- EitherOutputProj :: Second ( b) => AsyncWrite :: poll_write_vectored ( b, cx, bufs) ,
96
- }
97
- }
98
-
99
- fn poll_flush ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < io:: Result < ( ) > > {
100
- match self . project ( ) {
101
- EitherOutputProj :: First ( a) => AsyncWrite :: poll_flush ( a, cx) ,
102
- EitherOutputProj :: Second ( b) => AsyncWrite :: poll_flush ( b, cx) ,
103
- }
104
- }
105
-
106
- fn poll_close ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < io:: Result < ( ) > > {
107
- match self . project ( ) {
108
- EitherOutputProj :: First ( a) => AsyncWrite :: poll_close ( a, cx) ,
109
- EitherOutputProj :: Second ( b) => AsyncWrite :: poll_close ( b, cx) ,
110
- }
111
- }
112
- }
113
-
114
- impl < A , B , I > Stream for EitherOutput < A , B >
115
- where
116
- A : TryStream < Ok = I > ,
117
- B : TryStream < Ok = I > ,
118
- {
119
- type Item = Result < I , Either < A :: Error , B :: Error > > ;
120
-
121
- fn poll_next ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
122
- match self . project ( ) {
123
- EitherOutputProj :: First ( a) => {
124
- TryStream :: try_poll_next ( a, cx) . map ( |v| v. map ( |r| r. map_err ( Either :: Left ) ) )
125
- }
126
- EitherOutputProj :: Second ( b) => {
127
- TryStream :: try_poll_next ( b, cx) . map ( |v| v. map ( |r| r. map_err ( Either :: Right ) ) )
128
- }
129
- }
130
- }
131
- }
132
-
133
- impl < A , B , I > Sink < I > for EitherOutput < A , B >
134
- where
135
- A : Sink < I > ,
136
- B : Sink < I > ,
137
- {
138
- type Error = Either < A :: Error , B :: Error > ;
139
-
140
- fn poll_ready ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) , Self :: Error > > {
141
- match self . project ( ) {
142
- EitherOutputProj :: First ( a) => Sink :: poll_ready ( a, cx) . map_err ( Either :: Left ) ,
143
- EitherOutputProj :: Second ( b) => Sink :: poll_ready ( b, cx) . map_err ( Either :: Right ) ,
144
- }
145
- }
146
-
147
- fn start_send ( self : Pin < & mut Self > , item : I ) -> Result < ( ) , Self :: Error > {
148
- match self . project ( ) {
149
- EitherOutputProj :: First ( a) => Sink :: start_send ( a, item) . map_err ( Either :: Left ) ,
150
- EitherOutputProj :: Second ( b) => Sink :: start_send ( b, item) . map_err ( Either :: Right ) ,
151
- }
152
- }
153
-
154
- fn poll_flush ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) , Self :: Error > > {
155
- match self . project ( ) {
156
- EitherOutputProj :: First ( a) => Sink :: poll_flush ( a, cx) . map_err ( Either :: Left ) ,
157
- EitherOutputProj :: Second ( b) => Sink :: poll_flush ( b, cx) . map_err ( Either :: Right ) ,
158
- }
159
- }
160
-
161
- fn poll_close ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) , Self :: Error > > {
162
- match self . project ( ) {
163
- EitherOutputProj :: First ( a) => Sink :: poll_close ( a, cx) . map_err ( Either :: Left ) ,
164
- EitherOutputProj :: Second ( b) => Sink :: poll_close ( b, cx) . map_err ( Either :: Right ) ,
165
- }
166
- }
167
- }
168
-
169
- impl < A , B > StreamMuxer for EitherOutput < A , B >
32
+ impl < A , B > StreamMuxer for future:: Either < A , B >
170
33
where
171
34
A : StreamMuxer ,
172
35
B : StreamMuxer ,
173
36
{
174
- type Substream = EitherOutput < A :: Substream , B :: Substream > ;
37
+ type Substream = future :: Either < A :: Substream , B :: Substream > ;
175
38
type Error = Either < A :: Error , B :: Error > ;
176
39
177
40
fn poll_inbound (
178
41
self : Pin < & mut Self > ,
179
42
cx : & mut Context < ' _ > ,
180
43
) -> Poll < Result < Self :: Substream , Self :: Error > > {
181
- match self . project ( ) {
182
- EitherOutputProj :: First ( inner) => inner
44
+ match as_pin_mut ( self ) {
45
+ future :: Either :: Left ( inner) => inner
183
46
. poll_inbound ( cx)
184
- . map_ok ( EitherOutput :: First )
47
+ . map_ok ( future :: Either :: Left )
185
48
. map_err ( Either :: Left ) ,
186
- EitherOutputProj :: Second ( inner) => inner
49
+ future :: Either :: Right ( inner) => inner
187
50
. poll_inbound ( cx)
188
- . map_ok ( EitherOutput :: Second )
51
+ . map_ok ( future :: Either :: Right )
189
52
. map_err ( Either :: Right ) ,
190
53
}
191
54
}
@@ -194,32 +57,54 @@ where
194
57
self : Pin < & mut Self > ,
195
58
cx : & mut Context < ' _ > ,
196
59
) -> Poll < Result < Self :: Substream , Self :: Error > > {
197
- match self . project ( ) {
198
- EitherOutputProj :: First ( inner) => inner
60
+ match as_pin_mut ( self ) {
61
+ future :: Either :: Left ( inner) => inner
199
62
. poll_outbound ( cx)
200
- . map_ok ( EitherOutput :: First )
63
+ . map_ok ( future :: Either :: Left )
201
64
. map_err ( Either :: Left ) ,
202
- EitherOutputProj :: Second ( inner) => inner
65
+ future :: Either :: Right ( inner) => inner
203
66
. poll_outbound ( cx)
204
- . map_ok ( EitherOutput :: Second )
67
+ . map_ok ( future :: Either :: Right )
205
68
. map_err ( Either :: Right ) ,
206
69
}
207
70
}
208
71
209
72
fn poll_close ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) , Self :: Error > > {
210
- match self . project ( ) {
211
- EitherOutputProj :: First ( inner) => inner. poll_close ( cx) . map_err ( Either :: Left ) ,
212
- EitherOutputProj :: Second ( inner) => inner. poll_close ( cx) . map_err ( Either :: Right ) ,
73
+ match as_pin_mut ( self ) {
74
+ future :: Either :: Left ( inner) => inner. poll_close ( cx) . map_err ( Either :: Left ) ,
75
+ future :: Either :: Right ( inner) => inner. poll_close ( cx) . map_err ( Either :: Right ) ,
213
76
}
214
77
}
215
78
216
79
fn poll (
217
80
self : Pin < & mut Self > ,
218
81
cx : & mut Context < ' _ > ,
219
82
) -> Poll < Result < StreamMuxerEvent , Self :: Error > > {
220
- match self . project ( ) {
221
- EitherOutputProj :: First ( inner) => inner. poll ( cx) . map_err ( Either :: Left ) ,
222
- EitherOutputProj :: Second ( inner) => inner. poll ( cx) . map_err ( Either :: Right ) ,
83
+ match as_pin_mut ( self ) {
84
+ future:: Either :: Left ( inner) => inner. poll ( cx) . map_err ( Either :: Left ) ,
85
+ future:: Either :: Right ( inner) => inner. poll ( cx) . map_err ( Either :: Right ) ,
86
+ }
87
+ }
88
+ }
89
+
90
+ /// Convert `Pin<&mut Either<A, B>>` to `Either<Pin<&mut A>, Pin<&mut B>>`,
91
+ /// pinned projections of the inner variants.
92
+ ///
93
+ /// Local function until <https://github.com/rust-lang/futures-rs/pull/2691> is merged.
94
+ fn as_pin_mut < A , B > (
95
+ either : Pin < & mut future:: Either < A , B > > ,
96
+ ) -> future:: Either < Pin < & mut A > , Pin < & mut B > > {
97
+ // SAFETY: `get_unchecked_mut` is fine because we don't move anything.
98
+ // We can use `new_unchecked` because the `inner` parts are guaranteed
99
+ // to be pinned, as they come from `self` which is pinned, and we never
100
+ // offer an unpinned `&mut L` or `&mut R` through `Pin<&mut Self>`. We
101
+ // also don't have an implementation of `Drop`, nor manual `Unpin`.
102
+ unsafe {
103
+ match * Pin :: get_unchecked_mut ( either) {
104
+ future:: Either :: Left ( ref mut inner) => future:: Either :: Left ( Pin :: new_unchecked ( inner) ) ,
105
+ future:: Either :: Right ( ref mut inner) => {
106
+ future:: Either :: Right ( Pin :: new_unchecked ( inner) )
107
+ }
223
108
}
224
109
}
225
110
}
@@ -238,15 +123,15 @@ where
238
123
AFuture : TryFuture < Ok = AInner > ,
239
124
BFuture : TryFuture < Ok = BInner > ,
240
125
{
241
- type Output = Result < EitherOutput < AInner , BInner > , Either < AFuture :: Error , BFuture :: Error > > ;
126
+ type Output = Result < future :: Either < AInner , BInner > , Either < AFuture :: Error , BFuture :: Error > > ;
242
127
243
128
fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
244
129
match self . project ( ) {
245
130
EitherFutureProj :: First ( a) => TryFuture :: try_poll ( a, cx)
246
- . map_ok ( EitherOutput :: First )
131
+ . map_ok ( future :: Either :: Left )
247
132
. map_err ( Either :: Left ) ,
248
133
EitherFutureProj :: Second ( a) => TryFuture :: try_poll ( a, cx)
249
- . map_ok ( EitherOutput :: Second )
134
+ . map_ok ( future :: Either :: Right )
250
135
. map_err ( Either :: Right ) ,
251
136
}
252
137
}
@@ -272,7 +157,7 @@ where
272
157
B : Transport ,
273
158
A : Transport ,
274
159
{
275
- type Output = EitherOutput < A :: Output , B :: Output > ;
160
+ type Output = future :: Either < A :: Output , B :: Output > ;
276
161
type Error = Either < A :: Error , B :: Error > ;
277
162
type ListenerUpgrade = EitherFuture < A :: ListenerUpgrade , B :: ListenerUpgrade > ;
278
163
type Dial = EitherFuture < A :: Dial , B :: Dial > ;
0 commit comments