use std::future::Future; use async_macros::utils::poll_fn; use std::task::{Context, Poll, Waker}; use std::pin::Pin; use async_macros::MaybeDone; use async_std::stream::Stream; use std::collections::VecDeque; use std::sync::Mutex; use async_std::sync::Arc; use std::mem; #[async_trait] pub trait IntoResults { async fn into_results<'a>(self) -> T where Self: 'a, T: 'a; } #[async_trait] impl + Send> IntoResults> for Vec { async fn into_results<'a>(self) -> Vec where Self: 'a, O: 'a { let mut futures: Vec> = self.into_iter().map(MaybeDone::new).collect(); return poll_fn(|cx: &mut Context<'_>| -> Poll> { let mut ready = true; for future in &mut futures { let fut = unsafe { Pin::new_unchecked(future) }; ready &= Future::poll(fut, cx).is_ready(); } if ready { let mut results = Vec::new(); for future in &mut futures { let fut = unsafe { Pin::new_unchecked(future) }; results.push(fut.take().unwrap()); } Poll::Ready(results) } else { Poll::Pending } }).await; } } #[derive(Clone, Debug)] pub struct AsyncQueue(Arc>>); impl Default for AsyncQueue { fn default() -> Self { AsyncQueue(Arc::new(Mutex::new(AsyncQueueState { closed: false, waker: None, queue: Default::default(), }))) } } impl AsyncQueue { pub fn push(&mut self, value: T) { let mut res = self.0.lock().unwrap(); res.queue.push_back(value); if let Some(waker) = &res.waker { waker.wake_by_ref(); } } pub fn close(&mut self) { let mut res = self.0.lock().unwrap(); res.closed = true; if let Some(waker) = &res.waker { waker.wake_by_ref(); } } pub fn new() -> AsyncQueue { AsyncQueue(Arc::new(Mutex::new(AsyncQueueState { closed: false, waker: None, queue: VecDeque::new(), }))) } } #[derive(Clone, Debug)] struct AsyncQueueState { closed: bool, waker: Option, queue: VecDeque, } impl Default for AsyncQueueState { fn default() -> Self { AsyncQueueState { closed: false, waker: None, queue: Default::default(), } } } impl Stream for AsyncQueue { type Item = T; fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll> { if let Ok(mut res) = self.0.lock() { res.waker = Some(cx.waker().clone()); if let Some(data) = res.queue.pop_front() { return Poll::Ready(Some(data)); } if res.closed { return Poll::Ready(None); } } Poll::Pending } } #[derive(Clone, Debug)] pub struct Deferred { state: Arc>>, } impl Deferred { pub fn new() -> Self { Deferred { state: Arc::new(Mutex::new(DeferredState { waker: None, result: None, })) } } pub fn complete(&mut self, result: T) { let mut state = self.state.lock().unwrap(); state.result = Some(result); if let Some(waker) = &state.waker { waker.wake_by_ref() } } } #[derive(Clone, Debug)] struct DeferredState { waker: Option, result: Option, } impl Future for Deferred { type Output = T; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut state = self.state.lock().unwrap(); state.waker = Some(cx.waker().clone()); if let Some(_) = &state.result { let result = mem::replace(&mut state.result, None); Poll::Ready(result.unwrap()) } else { Poll::Pending } } }