mirror of
https://gitee.com/openharmony/third_party_rust_either
synced 2024-11-23 06:59:40 +00:00
Add Pin
projections and implement Future
(MSRV 1.36)
This commit is contained in:
parent
fad7d3ae64
commit
b136420e40
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
rust:
|
||||
- 1.31.0 # MSRV
|
||||
- 1.36.0 # MSRV
|
||||
- stable
|
||||
- beta
|
||||
- nightly
|
||||
@ -30,12 +30,6 @@ jobs:
|
||||
with:
|
||||
toolchain: ${{ matrix.rust }}
|
||||
|
||||
- name: (1.31.0) Downgrade serde_json
|
||||
if: ${{ matrix.rust == '1.31.0' }}
|
||||
run: |
|
||||
cargo generate-lockfile
|
||||
cargo update -p serde_json --precise 1.0.39
|
||||
|
||||
- name: Build (no_std)
|
||||
run: cargo build --no-default-features
|
||||
|
||||
|
@ -3,7 +3,7 @@ name = "either"
|
||||
version = "1.7.0"
|
||||
authors = ["bluss"]
|
||||
edition = "2018"
|
||||
rust-version = "1.31"
|
||||
rust-version = "1.36"
|
||||
|
||||
license = "MIT/Apache-2.0"
|
||||
repository = "https://github.com/bluss/either"
|
||||
|
@ -31,6 +31,15 @@ How to use with cargo::
|
||||
Recent Changes
|
||||
--------------
|
||||
|
||||
- UNRELEASED
|
||||
|
||||
- **MSRV**: ``either`` now requires Rust 1.36 or later.
|
||||
|
||||
- Add new methods ``.as_pin_ref()`` and ``.as_pin_mut()`` to project a
|
||||
pinned ``Either`` as inner ``Pin`` variants, by @cuviper (#77)
|
||||
|
||||
- Implement the ``Future`` trait, by @cuviper (#77)
|
||||
|
||||
- 1.7.0
|
||||
|
||||
- **MSRV**: ``either`` now requires Rust 1.31 or later.
|
||||
|
47
src/lib.rs
47
src/lib.rs
@ -26,9 +26,11 @@ pub mod serde_untagged_optional;
|
||||
|
||||
use core::convert::{AsMut, AsRef};
|
||||
use core::fmt;
|
||||
use core::future::Future;
|
||||
use core::iter;
|
||||
use core::ops::Deref;
|
||||
use core::ops::DerefMut;
|
||||
use core::pin::Pin;
|
||||
|
||||
#[cfg(any(test, feature = "use_std"))]
|
||||
use std::error::Error;
|
||||
@ -255,6 +257,35 @@ impl<L, R> Either<L, R> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert `Pin<&Either<L, R>>` to `Either<Pin<&L>, Pin<&R>>`,
|
||||
/// pinned projections of the inner variants.
|
||||
pub fn as_pin_ref(self: Pin<&Self>) -> Either<Pin<&L>, Pin<&R>> {
|
||||
// SAFETY: We can use `new_unchecked` because the `inner` parts are
|
||||
// guaranteed to be pinned, as they come from `self` which is pinned.
|
||||
unsafe {
|
||||
match *Pin::get_ref(self) {
|
||||
Left(ref inner) => Left(Pin::new_unchecked(inner)),
|
||||
Right(ref inner) => Right(Pin::new_unchecked(inner)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert `Pin<&mut Either<L, R>>` to `Either<Pin<&mut L>, Pin<&mut R>>`,
|
||||
/// pinned projections of the inner variants.
|
||||
pub fn as_pin_mut(self: Pin<&mut Self>) -> Either<Pin<&mut L>, Pin<&mut R>> {
|
||||
// SAFETY: `get_unchecked_mut` is fine because we don't move anything.
|
||||
// We can use `new_unchecked` because the `inner` parts are guaranteed
|
||||
// to be pinned, as they come from `self` which is pinned, and we never
|
||||
// offer an unpinned `&mut L` or `&mut R` through `Pin<&mut Self>`. We
|
||||
// also don't have an implementation of `Drop`, nor manual `Unpin`.
|
||||
unsafe {
|
||||
match *Pin::get_unchecked_mut(self) {
|
||||
Left(ref mut inner) => Left(Pin::new_unchecked(inner)),
|
||||
Right(ref mut inner) => Right(Pin::new_unchecked(inner)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert `Either<L, R>` to `Either<R, L>`.
|
||||
///
|
||||
/// ```
|
||||
@ -1038,6 +1069,22 @@ where
|
||||
{
|
||||
}
|
||||
|
||||
/// `Either<L, R>` is a future if both `L` and `R` are futures.
|
||||
impl<L, R> Future for Either<L, R>
|
||||
where
|
||||
L: Future,
|
||||
R: Future<Output = L::Output>,
|
||||
{
|
||||
type Output = L::Output;
|
||||
|
||||
fn poll(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut core::task::Context<'_>,
|
||||
) -> core::task::Poll<Self::Output> {
|
||||
for_both!(self.as_pin_mut(), inner => inner.poll(cx))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "use_std"))]
|
||||
/// `Either<L, R>` implements `Read` if both `L` and `R` do.
|
||||
///
|
||||
|
Loading…
Reference in New Issue
Block a user