refactor(client): Use async/await more (#2437)

* refactor: Use async/await in client.rs

* refactor: Simplify client.rs a bit more

* refactor: Allow !Unpin in Lazy

* Remove some impl Future

* Remove some combinator use
This commit is contained in:
Markus Westerlind
2021-02-18 19:35:43 +01:00
committed by GitHub
parent 42587059e6
commit f01de8e503
4 changed files with 174 additions and 178 deletions

View File

@@ -1,4 +1,4 @@
use std::mem;
use pin_project::pin_project;
use super::{task, Future, Pin, Poll};
@@ -18,20 +18,23 @@ where
// FIXME: allow() required due to `impl Trait` leaking types to this lint
#[allow(missing_debug_implementations)]
#[pin_project]
pub(crate) struct Lazy<F, R> {
#[pin]
inner: Inner<F, R>,
}
#[pin_project(project = InnerProj, project_replace = InnerProjReplace)]
enum Inner<F, R> {
Init(F),
Fut(R),
Fut(#[pin] R),
Empty,
}
impl<F, R> Started for Lazy<F, R>
where
F: FnOnce() -> R,
R: Future + Unpin,
R: Future,
{
fn started(&self) -> bool {
match self.inner {
@@ -44,26 +47,26 @@ where
impl<F, R> Future for Lazy<F, R>
where
F: FnOnce() -> R,
R: Future + Unpin,
R: Future,
{
type Output = R::Output;
fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
if let Inner::Fut(ref mut f) = self.inner {
return Pin::new(f).poll(cx);
fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
let mut this = self.project();
if let InnerProj::Fut(f) = this.inner.as_mut().project() {
return f.poll(cx);
}
match mem::replace(&mut self.inner, Inner::Empty) {
Inner::Init(func) => {
let mut fut = func();
let ret = Pin::new(&mut fut).poll(cx);
self.inner = Inner::Fut(fut);
ret
match this.inner.as_mut().project_replace(Inner::Empty) {
InnerProjReplace::Init(func) => {
this.inner.set(Inner::Fut(func()));
if let InnerProj::Fut(f) = this.inner.project() {
return f.poll(cx);
}
unreachable!()
}
_ => unreachable!("lazy state wrong"),
}
}
}
// The closure `F` is never pinned
impl<F, R: Unpin> Unpin for Lazy<F, R> {}