Skip to content

Commit d1bd5f0

Browse files
Copy as_pin_ref and as_pin_mut from either
1 parent 2075efd commit d1bd5f0

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

futures-util/src/future/either.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,35 @@ impl<A, B> Either<A, B> {
4141
}
4242
}
4343
}
44+
45+
/// Convert `Pin<&Either<L, R>>` to `Either<Pin<&L>, Pin<&R>>`,
46+
/// pinned projections of the inner variants.
47+
pub fn as_pin_ref(self: Pin<&Self>) -> Either<Pin<&A>, Pin<&B>> {
48+
// SAFETY: We can use `new_unchecked` because the `inner` parts are
49+
// guaranteed to be pinned, as they come from `self` which is pinned.
50+
unsafe {
51+
match *Pin::get_ref(self) {
52+
Either::Left(ref inner) => Either::Left(Pin::new_unchecked(inner)),
53+
Either::Right(ref inner) => Either::Right(Pin::new_unchecked(inner)),
54+
}
55+
}
56+
}
57+
58+
/// Convert `Pin<&mut Either<L, R>>` to `Either<Pin<&mut L>, Pin<&mut R>>`,
59+
/// pinned projections of the inner variants.
60+
pub fn as_pin_mut(self: Pin<&mut Self>) -> Either<Pin<&mut A>, Pin<&mut B>> {
61+
// SAFETY: `get_unchecked_mut` is fine because we don't move anything.
62+
// We can use `new_unchecked` because the `inner` parts are guaranteed
63+
// to be pinned, as they come from `self` which is pinned, and we never
64+
// offer an unpinned `&mut L` or `&mut R` through `Pin<&mut Self>`. We
65+
// also don't have an implementation of `Drop`, nor manual `Unpin`.
66+
unsafe {
67+
match *Pin::get_unchecked_mut(self) {
68+
Either::Left(ref mut inner) => Either::Left(Pin::new_unchecked(inner)),
69+
Either::Right(ref mut inner) => Either::Right(Pin::new_unchecked(inner)),
70+
}
71+
}
72+
}
4473
}
4574

4675
impl<A, B, T> Either<(T, A), (T, B)> {

0 commit comments

Comments
 (0)