#![allow(clippy::disallowed_types)]
use std::{
future::Future,
pin::Pin,
task::{Context, Poll, Waker},
};
use futures::{stream as inner, Stream, StreamExt};
use pin_project::pin_project;
use crate::WakerExt as _;
#[pin_project]
pub struct FuturesOrdered<F: Future> {
#[pin]
inner: inner::FuturesOrdered<F>,
waker: Option<Waker>,
}
impl<F: Future> Default for FuturesOrdered<F> {
fn default() -> FuturesOrdered<F> {
FuturesOrdered {
inner: Default::default(),
waker: None,
}
}
}
impl<F: Future> FuturesOrdered<F> {
pub fn new() -> FuturesOrdered<F> {
Default::default()
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn push_back(&mut self, future: F) {
self.inner.push_back(future);
self.waker.wake();
}
}
impl<F: Future> FromIterator<F> for FuturesOrdered<F> {
fn from_iter<I: IntoIterator<Item = F>>(iter: I) -> FuturesOrdered<F> {
FuturesOrdered {
inner: inner::FuturesOrdered::from_iter(iter),
waker: None,
}
}
}
impl<F: Future> Stream for FuturesOrdered<F> {
type Item = F::Output;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<F::Output>> {
let this = self.project();
this.waker.store_waker(cx);
this.inner.poll_next(cx)
}
}
#[pin_project]
pub struct FuturesUnordered<F: Future> {
#[pin]
inner: inner::FuturesUnordered<F>,
waker: Option<Waker>,
}
impl<F: Future> Default for FuturesUnordered<F> {
fn default() -> FuturesUnordered<F> {
FuturesUnordered {
inner: Default::default(),
waker: None,
}
}
}
impl<F: Future> FuturesUnordered<F> {
pub fn new() -> FuturesUnordered<F> {
Default::default()
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn push(&mut self, future: F) {
self.inner.push(future);
self.waker.wake();
}
}
impl<F: Future> FromIterator<F> for FuturesUnordered<F> {
fn from_iter<I: IntoIterator<Item = F>>(iter: I) -> FuturesUnordered<F> {
FuturesUnordered {
inner: inner::FuturesUnordered::from_iter(iter),
waker: None,
}
}
}
impl<F: Future> Stream for FuturesUnordered<F> {
type Item = F::Output;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<F::Output>> {
let this = self.project();
this.waker.store_waker(cx);
this.inner.poll_next(cx)
}
}
#[must_use = "streams do nothing unless polled"]
pub struct SelectAll<St: Stream + Unpin> {
inner: inner::SelectAll<St>,
waker: Option<Waker>,
}
impl<St: Stream + Unpin> Default for SelectAll<St> {
fn default() -> SelectAll<St> {
SelectAll {
inner: Default::default(),
waker: None,
}
}
}
impl<St: Stream + Unpin> SelectAll<St> {
pub fn new() -> SelectAll<St> {
Default::default()
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn push(&mut self, stream: St) {
self.inner.push(stream);
self.waker.wake();
}
}
impl<St: Stream + Unpin> FromIterator<St> for SelectAll<St> {
fn from_iter<T: IntoIterator<Item = St>>(iter: T) -> SelectAll<St> {
SelectAll {
inner: inner::SelectAll::from_iter(iter),
waker: None,
}
}
}
impl<St: Stream + Unpin> Stream for SelectAll<St> {
type Item = St::Item;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<St::Item>> {
self.waker.store_waker(cx);
self.inner.poll_next_unpin(cx)
}
}