@@ -26,9 +26,11 @@ pub mod serde_untagged_optional;
26
26
27
27
use core:: convert:: { AsMut , AsRef } ;
28
28
use core:: fmt;
29
+ use core:: future:: Future ;
29
30
use core:: iter;
30
31
use core:: ops:: Deref ;
31
32
use core:: ops:: DerefMut ;
33
+ use core:: pin:: Pin ;
32
34
33
35
#[ cfg( any( test, feature = "use_std" ) ) ]
34
36
use std:: error:: Error ;
@@ -255,6 +257,35 @@ impl<L, R> Either<L, R> {
255
257
}
256
258
}
257
259
260
+ /// Convert `Pin<&Either<L, R>>` to `Either<Pin<&L>, Pin<&R>>`,
261
+ /// pinned projections of the inner variants.
262
+ pub fn as_pin_ref ( self : Pin < & Self > ) -> Either < Pin < & L > , Pin < & R > > {
263
+ // SAFETY: We can use `new_unchecked` because the `inner` parts are
264
+ // guaranteed to be pinned, as they come from `self` which is pinned.
265
+ unsafe {
266
+ match * Pin :: get_ref ( self ) {
267
+ Left ( ref inner) => Left ( Pin :: new_unchecked ( inner) ) ,
268
+ Right ( ref inner) => Right ( Pin :: new_unchecked ( inner) ) ,
269
+ }
270
+ }
271
+ }
272
+
273
+ /// Convert `Pin<&mut Either<L, R>>` to `Either<Pin<&mut L>, Pin<&mut R>>`,
274
+ /// pinned projections of the inner variants.
275
+ pub fn as_pin_mut ( self : Pin < & mut Self > ) -> Either < Pin < & mut L > , Pin < & mut R > > {
276
+ // SAFETY: `get_unchecked_mut` is fine because we don't move anything.
277
+ // We can use `new_unchecked` because the `inner` parts are guaranteed
278
+ // to be pinned, as they come from `self` which is pinned, and we never
279
+ // offer an unpinned `&mut L` or `&mut R` through `Pin<&mut Self>`. We
280
+ // also don't have an implementation of `Drop`, nor manual `Unpin`.
281
+ unsafe {
282
+ match * Pin :: get_unchecked_mut ( self ) {
283
+ Left ( ref mut inner) => Left ( Pin :: new_unchecked ( inner) ) ,
284
+ Right ( ref mut inner) => Right ( Pin :: new_unchecked ( inner) ) ,
285
+ }
286
+ }
287
+ }
288
+
258
289
/// Convert `Either<L, R>` to `Either<R, L>`.
259
290
///
260
291
/// ```
@@ -1038,6 +1069,22 @@ where
1038
1069
{
1039
1070
}
1040
1071
1072
+ /// `Either<L, R>` is a future if both `L` and `R` are futures.
1073
+ impl < L , R > Future for Either < L , R >
1074
+ where
1075
+ L : Future ,
1076
+ R : Future < Output = L :: Output > ,
1077
+ {
1078
+ type Output = L :: Output ;
1079
+
1080
+ fn poll (
1081
+ self : Pin < & mut Self > ,
1082
+ cx : & mut core:: task:: Context < ' _ > ,
1083
+ ) -> core:: task:: Poll < Self :: Output > {
1084
+ for_both ! ( self . as_pin_mut( ) , inner => inner. poll( cx) )
1085
+ }
1086
+ }
1087
+
1041
1088
#[ cfg( any( test, feature = "use_std" ) ) ]
1042
1089
/// `Either<L, R>` implements `Read` if both `L` and `R` do.
1043
1090
///
0 commit comments