fix: Using pin_project!

This commit is contained in:
k-nasa 2019-10-25 23:58:08 +09:00
parent 3297a0f327
commit 271b6f4a1c

View file

@ -1,10 +1,12 @@
use std::pin::Pin; use std::pin::Pin;
use pin_project_lite::pin_project;
use crate::prelude::*; use crate::prelude::*;
use crate::stream::stream::map::Map; use crate::stream::stream::map::Map;
use crate::stream::{IntoStream, Stream}; use crate::stream::{IntoStream, Stream};
use crate::task::{Context, Poll}; use crate::task::{Context, Poll};
pin_project! {
/// This `struct` is created by the [`flat_map`] method on [`Stream`]. See its /// This `struct` is created by the [`flat_map`] method on [`Stream`]. See its
/// documentation for more. /// documentation for more.
/// ///
@ -12,8 +14,10 @@ use crate::task::{Context, Poll};
/// [`Stream`]: trait.Stream.html /// [`Stream`]: trait.Stream.html
#[allow(missing_debug_implementations)] #[allow(missing_debug_implementations)]
pub struct FlatMap<S: Stream, U: IntoStream, F> { pub struct FlatMap<S: Stream, U: IntoStream, F> {
#[pin]
inner: FlattenCompat<Map<S, F, S::Item, U>, U>, inner: FlattenCompat<Map<S, F, S::Item, U>, U>,
} }
}
impl<S, U, F> FlatMap<S, U, F> impl<S, U, F> FlatMap<S, U, F>
where where
@ -21,7 +25,6 @@ where
U: IntoStream, U: IntoStream,
F: FnMut(S::Item) -> U, F: FnMut(S::Item) -> U,
{ {
pin_utils::unsafe_pinned!(inner: FlattenCompat<Map<S, F, S::Item, U>, U>);
pub fn new(stream: S, f: F) -> FlatMap<S, U, F> { pub fn new(stream: S, f: F) -> FlatMap<S, U, F> {
FlatMap { FlatMap {
@ -33,17 +36,17 @@ where
impl<S, U, F> Stream for FlatMap<S, U, F> impl<S, U, F> Stream for FlatMap<S, U, F>
where where
S: Stream<Item: IntoStream<IntoStream = U, Item = U::Item>> + std::marker::Unpin, S: Stream<Item: IntoStream<IntoStream = U, Item = U::Item>> + std::marker::Unpin,
S::Item: std::marker::Unpin,
U: Stream + std::marker::Unpin, U: Stream + std::marker::Unpin,
F: FnMut(S::Item) -> U + std::marker::Unpin, F: FnMut(S::Item) -> U,
{ {
type Item = U::Item; type Item = U::Item;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
self.as_mut().inner().poll_next(cx) self.project().inner.poll_next(cx)
} }
} }
pin_project!{
/// This `struct` is created by the [`flatten`] method on [`Stream`]. See its /// This `struct` is created by the [`flatten`] method on [`Stream`]. See its
/// documentation for more. /// documentation for more.
/// ///
@ -54,12 +57,12 @@ pub struct Flatten<S: Stream>
where where
S::Item: IntoStream, S::Item: IntoStream,
{ {
#[pin]
inner: FlattenCompat<S, <S::Item as IntoStream>::IntoStream>, inner: FlattenCompat<S, <S::Item as IntoStream>::IntoStream>,
} }
}
impl<S: Stream<Item: IntoStream>> Flatten<S> { impl<S: Stream<Item: IntoStream>> Flatten<S> {
pin_utils::unsafe_pinned!(inner: FlattenCompat<S, <S::Item as IntoStream>::IntoStream>);
pub fn new(stream: S) -> Flatten<S> { pub fn new(stream: S) -> Flatten<S> {
Flatten { inner: FlattenCompat::new(stream) } Flatten { inner: FlattenCompat::new(stream) }
} }
@ -72,12 +75,13 @@ where
{ {
type Item = U::Item; type Item = U::Item;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
self.as_mut().inner().poll_next(cx) self.project().inner.poll_next(cx)
} }
} }
pin_project! {
/// Real logic of both `Flatten` and `FlatMap` which simply delegate to /// Real logic of both `Flatten` and `FlatMap` which simply delegate to
/// this type. /// this type.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -85,11 +89,9 @@ struct FlattenCompat<S, U> {
stream: S, stream: S,
frontiter: Option<U>, frontiter: Option<U>,
} }
}
impl<S, U> FlattenCompat<S, U> { impl<S, U> FlattenCompat<S, U> {
pin_utils::unsafe_unpinned!(stream: S);
pin_utils::unsafe_unpinned!(frontiter: Option<U>);
/// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`. /// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`.
pub fn new(stream: S) -> FlattenCompat<S, U> { pub fn new(stream: S) -> FlattenCompat<S, U> {
FlattenCompat { FlattenCompat {
@ -106,17 +108,18 @@ where
{ {
type Item = U::Item; type Item = U::Item;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
let mut this = self.project();
loop { loop {
if let Some(ref mut inner) = self.as_mut().frontiter() { if let Some(inner) = this.frontiter {
if let item @ Some(_) = futures_core::ready!(Pin::new(inner).poll_next(cx)) { if let item @ Some(_) = futures_core::ready!(Pin::new(inner).poll_next(cx)) {
return Poll::Ready(item); return Poll::Ready(item);
} }
} }
match futures_core::ready!(Pin::new(&mut self.stream).poll_next(cx)) { match futures_core::ready!(Pin::new(&mut this.stream).poll_next(cx)) {
None => return Poll::Ready(None), None => return Poll::Ready(None),
Some(inner) => *self.as_mut().frontiter() = Some(inner.into_stream()), Some(inner) => *this.frontiter = Some(inner.into_stream()),
} }
} }
} }