Skip to content

Instantly share code, notes, and snippets.

@felipesere
Created December 26, 2019 23:18
Show Gist options
  • Save felipesere/7c2ef4f41e078487e219ea3f5c7de978 to your computer and use it in GitHub Desktop.
Save felipesere/7c2ef4f41e078487e219ea3f5c7de978 to your computer and use it in GitHub Desktop.
attempt at turning Vec of Futures (?) into a stream that will yield all items
use std::pin::Pin;
use pin_project_lite::pin_project;
use crate::stream::Stream;
use crate::task::{Context, Poll};
use crate::future::Future;
pin_project! {
/// A stream that was created from a bunch of futures.
pub struct FromManyFutures<T> {
futures: Vec<Pin<Box<dyn Future<Output=T>>>> ,
}
}
impl <T> FromManyFutures<T> {
fn add(&mut self, fut: Pin<Box<dyn Future<Output=T>>>) {
self.futures.push(fut);
}
}
impl <T> Stream for FromManyFutures<T> {
type Item = T;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
let mut this = self.project();
// Nothing left to do here
if self.futures.len() == 0 {
return Poll::Ready(None);
}
// go over each of the futures and see if any will yield a value
let found_item = None;
for (i, fut) in this.futures.iter_mut().enumerate() {
match fut.poll(cx) {
Poll::Ready(v) => {
found_item = Some((i, v));
break;
},
Poll::Pending => {}
}
}
// if yielded a value, remove it from the list
if let Some((i, value)) = found_item {
this.futures.remove(i);
return Poll::Ready(Some(value));
}
Poll::Pending
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment