1pub mod ordered;
2pub mod set;
3#[cfg(all(feature = "std", feature = "timeout"))]
4pub mod timeout_map;
5#[cfg(all(feature = "std", feature = "timeout"))]
6pub mod timeout_set;
7
8use crate::common::InnerMap;
9use core::future::Future;
10use core::pin::Pin;
11use core::task::{Context, Poll, Waker};
12use futures::stream::{FusedStream, FuturesUnordered};
13use futures::{Stream, StreamExt};
14
15pub struct FutureMap<K, S> {
16 list: FuturesUnordered<InnerMap<K, S>>,
17 empty: bool,
18 terminate_on_empty: bool,
19 waker: Option<Waker>,
20}
21
22impl<K, T> Default for FutureMap<K, T> {
23 fn default() -> Self {
24 Self::new()
25 }
26}
27
28impl<K, T> FutureMap<K, T> {
29 pub fn new() -> Self {
31 Self {
32 list: FuturesUnordered::new(),
33 empty: true,
34 terminate_on_empty: false,
35 waker: None,
36 }
37 }
38
39 pub fn set_terminate_on_empty(&mut self, terminate: bool) {
41 self.terminate_on_empty = terminate;
42 }
43}
44
45impl<K, T> FutureMap<K, T>
46where
47 K: Clone + PartialEq,
48 T: Future,
49{
50 pub fn insert(&mut self, key: K, fut: T) -> bool {
54 if self.contains_key(&key) {
55 return false;
56 }
57
58 let st = InnerMap::new(key, fut);
59 self.list.push(st);
60
61 if let Some(waker) = self.waker.take() {
62 waker.wake();
63 }
64
65 self.empty = false;
66 true
67 }
68
69 pub fn set_wake_on_success(&mut self, key: &K, wake_on_success: bool) -> bool {
73 Pin::new(&mut self.list)
74 .iter_pin_mut()
75 .find(|st| st.as_ref().key_pin().eq(key))
76 .is_some_and(|st| st.set_wake_on_success_pin(wake_on_success))
77 }
78
79 pub fn iter(&self) -> impl Iterator<Item = (&K, &T)> {
81 Pin::new(&self.list)
82 .iter_pin_ref()
83 .filter_map(|st| st.key_value_pin_ref())
84 .map(|(key, future)| (key, future.get_ref()))
85 }
86
87 pub fn iter_pin(&mut self) -> impl Iterator<Item = (&K, Pin<&mut T>)> {
89 Pin::new(&mut self.list)
90 .iter_pin_mut()
91 .filter_map(|st| st.key_value_pin())
92 }
93
94 pub fn keys(&self) -> impl Iterator<Item = &K> {
96 Pin::new(&self.list)
97 .iter_pin_ref()
98 .filter_map(|st| st.key_value_pin_ref().map(|(key, _)| key))
99 }
100
101 pub fn values(&self) -> impl Iterator<Item = &T> {
103 Pin::new(&self.list)
104 .iter_pin_ref()
105 .filter_map(|st| st.inner_pin_ref())
106 .map(Pin::get_ref)
107 }
108
109 pub fn contains_key(&self, key: &K) -> bool {
111 Pin::new(&self.list)
112 .iter_pin_ref()
113 .filter(|st| st.as_ref().inner_pin_ref().is_some())
114 .any(|st| st.key_pin().eq(key))
115 }
116
117 pub fn clear(&mut self) {
119 self.list.clear();
120 }
121
122 pub fn get(&self, key: &K) -> Option<&T> {
124 Pin::new(&self.list)
125 .iter_pin_ref()
126 .find(|st| st.as_ref().key_pin().eq(key))
127 .and_then(|st| st.inner_pin_ref())
128 .map(Pin::get_ref)
129 }
130
131 pub fn get_pinned(&mut self, key: &K) -> Option<Pin<&mut T>> {
133 Pin::new(&mut self.list)
134 .iter_pin_mut()
135 .find(|st| st.as_ref().key_pin().eq(key))
136 .and_then(|st| st.inner_pin())
137 }
138
139 pub fn len(&self) -> usize {
141 Pin::new(&self.list)
142 .iter_pin_ref()
143 .filter(|st| st.as_ref().inner_pin_ref().is_some())
144 .count()
145 }
146
147 pub fn is_empty(&self) -> bool {
149 self.len() == 0
150 }
151}
152
153impl<K, T> FutureMap<K, T>
154where
155 K: Clone + PartialEq,
156 T: Future + Unpin,
157{
158 pub fn iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut T)> {
160 self.list.iter_mut().filter_map(|st| st.key_value_mut())
161 }
162
163 pub fn values_mut(&mut self) -> impl Iterator<Item = &mut T> {
165 self.list.iter_mut().filter_map(|st| st.inner_mut())
166 }
167
168 pub fn get_mut(&mut self, key: &K) -> Option<&mut T> {
170 self.list
171 .iter_mut()
172 .find(|st| st.key().eq(key))
173 .and_then(|st| st.inner_mut())
174 }
175
176 pub fn get_mut_or_default(&mut self, key: &K) -> &mut T
178 where
179 T: Default,
180 {
181 self.insert(key.clone(), T::default());
182 self.get_mut(key).expect("valid entry")
183 }
184
185 pub fn remove(&mut self, key: &K) -> Option<T> {
187 self.list
188 .iter_mut()
189 .find(|st| st.key().eq(key))
190 .and_then(|st| st.take_inner())
191 }
192}
193
194impl<K, T> FromIterator<(K, T)> for FutureMap<K, T>
195where
196 K: Clone + PartialEq,
197 T: Future,
198{
199 fn from_iter<I: IntoIterator<Item = (K, T)>>(iter: I) -> Self {
200 let mut maps = Self::new();
201 for (key, val) in iter {
202 maps.insert(key, val);
203 }
204 maps
205 }
206}
207
208impl<K, T> Stream for FutureMap<K, T>
209where
210 K: Clone,
211 T: Future,
212{
213 type Item = (K, T::Output);
214
215 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
216 loop {
217 match self.list.poll_next_unpin(cx) {
218 Poll::Ready(Some((key, Some(item)))) => return Poll::Ready(Some((key, item))),
219 Poll::Ready(Some((_key, None))) => continue,
221 Poll::Ready(None) => {
222 if self.empty {
229 if self.terminate_on_empty {
230 return Poll::Ready(None);
231 }
232 self.waker = Some(cx.waker().clone());
233 return Poll::Pending;
234 }
235
236 self.empty = true;
237 return Poll::Ready(None);
238 }
239 Poll::Pending => {
240 self.waker = Some(cx.waker().clone());
242 return Poll::Pending;
243 }
244 }
245 }
246 }
247
248 fn size_hint(&self) -> (usize, Option<usize>) {
249 self.list.size_hint()
250 }
251}
252
253impl<K, T> FusedStream for FutureMap<K, T>
254where
255 K: Clone,
256 T: Future,
257{
258 fn is_terminated(&self) -> bool {
259 self.terminate_on_empty && self.list.is_terminated()
260 }
261}
262
263#[cfg(test)]
264mod test {
265 use crate::futures::FutureMap;
266 use core::task::Poll;
267 use futures::future::pending;
268 use futures::StreamExt;
269
270 #[test]
271 fn existing_key() {
272 let mut map = FutureMap::new();
273 assert!(map.insert(1, pending::<()>()));
274 assert!(!map.insert(1, pending::<()>()));
275 }
276
277 #[test]
278 fn supports_unboxed_async_future() {
279 let mut map = FutureMap::new();
280 assert!(map.insert(1, async { 42 }));
281
282 futures::executor::block_on(async move {
283 assert_eq!(map.next().await, Some((1, 42)));
284 });
285 }
286
287 #[test]
288 fn poll_multiple_keyed_streams() {
289 let mut map = FutureMap::new();
290 map.insert(1, futures::future::ready(10));
291 map.insert(2, futures::future::ready(20));
292 map.insert(3, futures::future::ready(30));
293
294 futures::executor::block_on(async move {
295 assert_eq!(map.next().await, Some((1, 10)));
296 assert_eq!(map.next().await, Some((2, 20)));
297 assert_eq!(map.next().await, Some((3, 30)));
298 assert_eq!(map.next().await, None);
299 let pending =
300 futures::future::poll_fn(|cx| Poll::Ready(map.poll_next_unpin(cx).is_pending()))
301 .await;
302 assert!(pending);
303 })
304 }
305}