1 use {
2     crate::AsContextMut,
3     anyhow::Result,
4     futures::{stream::FuturesUnordered, FutureExt},
5     std::{boxed::Box, future::Future, pin::Pin},
6 };
7 
8 pub use futures_and_streams::{ErrorContext, FutureReader, StreamReader};
9 
10 mod futures_and_streams;
11 
12 /// Represents the result of a concurrent operation.
13 ///
14 /// This is similar to a [`std::future::Future`] except that it represents an
15 /// operation which requires exclusive access to a store in order to make
16 /// progress -- without monopolizing that store for the lifetime of the
17 /// operation.
18 pub struct Promise<T>(Pin<Box<dyn Future<Output = T> + Send + Sync + 'static>>);
19 
20 impl<T: 'static> Promise<T> {
21     /// Map the result of this `Promise` from one value to another.
22     pub fn map<U>(self, fun: impl FnOnce(T) -> U + Send + Sync + 'static) -> Promise<U> {
23         Promise(Box::pin(self.0.map(fun)))
24     }
25 
26     /// Convert this `Promise` to a future which may be `await`ed for its
27     /// result.
28     ///
29     /// The returned future will require exclusive use of the store until it
30     /// completes.  If you need to await more than one `Promise` concurrently,
31     /// use [`PromisesUnordered`].
32     pub async fn get<U: Send>(self, store: impl AsContextMut<Data = U>) -> Result<T> {
33         _ = store;
34         todo!()
35     }
36 
37     /// Convert this `Promise` to a future which may be `await`ed for its
38     /// result.
39     ///
40     /// Unlike [`Self::get`], this does _not_ take a store parameter, meaning
41     /// the returned future will not make progress until and unless the event
42     /// loop for the store it came from is polled.  Thus, this method should
43     /// only be used from within host functions and not from top-level embedder
44     /// code.
45     pub fn into_future(self) -> Pin<Box<dyn Future<Output = T> + Send + Sync + 'static>> {
46         self.0
47     }
48 }
49 
50 /// Represents a collection of zero or more concurrent operations.
51 ///
52 /// Similar to [`futures::stream::FuturesUnordered`], this type supports
53 /// `await`ing more than one [`Promise`]s concurrently.
54 pub struct PromisesUnordered<T>(
55     FuturesUnordered<Pin<Box<dyn Future<Output = T> + Send + Sync + 'static>>>,
56 );
57 
58 impl<T: 'static> PromisesUnordered<T> {
59     /// Create a new `PromisesUnordered` with no entries.
60     pub fn new() -> Self {
61         Self(FuturesUnordered::new())
62     }
63 
64     /// Add the specified [`Promise`] to this collection.
65     pub fn push(&mut self, promise: Promise<T>) {
66         self.0.push(promise.0)
67     }
68 
69     /// Get the next result from this collection, if any.
70     pub async fn next<U: Send>(&mut self, store: impl AsContextMut<Data = U>) -> Result<Option<T>> {
71         _ = store;
72         todo!()
73     }
74 }
75