1pub mod set;
2#[cfg(all(feature = "std", feature = "timeout"))]
3pub mod timeout_map;
4#[cfg(all(feature = "std", feature = "timeout"))]
5pub mod timeout_set;
6
7use crate::common::InnerMap;
8use alloc::boxed::Box;
9use core::pin::Pin;
10use core::task::{Context, Poll, Waker};
11use futures::stream::{FusedStream, SelectAll};
12use futures::{Stream, StreamExt};
13
14pub struct StreamMap<K, S> {
16 list: SelectAll<Pin<Box<InnerMap<K, S>>>>,
17 empty: bool,
18 terminate_on_empty: bool,
19 waker: Option<Waker>,
20}
21
22impl<K, T> Default for StreamMap<K, T>
23where
24 K: Clone,
25 T: Stream,
26{
27 fn default() -> Self {
28 Self::new()
29 }
30}
31
32impl<K, T> StreamMap<K, T>
33where
34 K: Clone,
35 T: Stream,
36{
37 pub fn new() -> Self {
39 Self {
40 list: SelectAll::new(),
41 empty: true,
42 terminate_on_empty: false,
43 waker: None,
44 }
45 }
46
47 pub fn set_terminate_on_empty(&mut self, terminate: bool) {
49 self.terminate_on_empty = terminate;
50 }
51}
52
53impl<K, T> StreamMap<K, T>
54where
55 K: Clone + PartialEq,
56 T: Stream,
57{
58 pub fn insert(&mut self, key: K, stream: T) -> bool {
62 if self.contains_key(&key) {
63 return false;
64 }
65
66 let st = Box::pin(InnerMap::new(key, stream));
67 self.list.push(st);
68
69 if let Some(waker) = self.waker.take() {
70 waker.wake();
71 }
72
73 self.empty = false;
74 true
75 }
76
77 pub fn set_wake_on_success(&mut self, key: &K, wake_on_success: bool) -> bool {
81 self.list
82 .iter_mut()
83 .find(|st| st.as_ref().key_pin().eq(key))
84 .is_some_and(|st| st.as_mut().set_wake_on_success_pin(wake_on_success))
85 }
86
87 pub fn iter(&self) -> impl Iterator<Item = (&K, &T)> {
89 self.list
90 .iter()
91 .filter_map(|st| st.as_ref().key_value_pin_ref())
92 .map(|(key, stream)| (key, stream.get_ref()))
93 }
94
95 pub fn iter_pin(&mut self) -> impl Iterator<Item = (&K, Pin<&mut T>)> {
97 self.list
98 .iter_mut()
99 .filter_map(|st| st.as_mut().key_value_pin())
100 }
101
102 pub fn keys(&self) -> impl Iterator<Item = &K> {
104 self.list
105 .iter()
106 .filter_map(|st| st.as_ref().key_value_pin_ref().map(|(key, _)| key))
107 }
108
109 pub fn values(&self) -> impl Iterator<Item = &T> {
111 self.list
112 .iter()
113 .filter_map(|st| st.as_ref().inner_pin_ref())
114 .map(Pin::get_ref)
115 }
116
117 pub fn contains_key(&self, key: &K) -> bool {
119 self.list
120 .iter()
121 .filter(|st| st.as_ref().inner_pin_ref().is_some())
122 .any(|st| st.as_ref().key_pin().eq(key))
123 }
124
125 pub fn clear(&mut self) {
127 self.list.clear();
128 }
129
130 pub fn get(&self, key: &K) -> Option<&T> {
132 self.list
133 .iter()
134 .find(|st| st.as_ref().key_pin().eq(key))
135 .and_then(|st| st.as_ref().inner_pin_ref())
136 .map(Pin::get_ref)
137 }
138
139 pub fn get_pinned(&mut self, key: &K) -> Option<Pin<&mut T>> {
141 self.list
142 .iter_mut()
143 .find(|st| st.as_ref().key_pin().eq(key))
144 .and_then(|st| st.as_mut().inner_pin())
145 }
146
147 pub fn len(&self) -> usize {
149 self.list
150 .iter()
151 .filter(|st| st.as_ref().inner_pin_ref().is_some())
152 .count()
153 }
154
155 pub fn is_empty(&self) -> bool {
157 self.len() == 0
158 }
159}
160
161impl<K, T> StreamMap<K, T>
162where
163 K: Clone + PartialEq,
164 T: Stream + Unpin,
165{
166 pub fn iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut T)> {
168 self.iter_pin()
169 .map(|(key, stream)| (key, Pin::get_mut(stream)))
170 }
171
172 pub fn values_mut(&mut self) -> impl Iterator<Item = &mut T> {
174 self.iter_pin().map(|(_, stream)| Pin::get_mut(stream))
175 }
176
177 pub fn get_mut(&mut self, key: &K) -> Option<&mut T> {
179 self.get_pinned(key).map(Pin::get_mut)
180 }
181
182 pub fn get_mut_or_default(&mut self, key: &K) -> &mut T
184 where
185 T: Default,
186 {
187 self.insert(key.clone(), T::default());
188 self.get_mut(key).expect("valid entry")
189 }
190
191 pub fn remove(&mut self, key: &K) -> Option<T> {
193 self.list
194 .iter_mut()
195 .find(|st| st.as_ref().key_pin().eq(key))
196 .and_then(|st| st.as_mut().take_inner_pin())
197 }
198}
199
200impl<K, T> FromIterator<(K, T)> for StreamMap<K, T>
201where
202 K: Clone + PartialEq,
203 T: Stream,
204{
205 fn from_iter<I: IntoIterator<Item = (K, T)>>(iter: I) -> Self {
206 let mut maps = Self::new();
207 for (key, val) in iter {
208 maps.insert(key, val);
209 }
210 maps
211 }
212}
213
214impl<K, T> Stream for StreamMap<K, T>
215where
216 K: Clone,
217 T: Stream,
218{
219 type Item = (K, T::Item);
220
221 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
222 if self.list.is_empty() {
223 if self.terminate_on_empty {
224 return Poll::Ready(None);
225 }
226 self.waker = Some(cx.waker().clone());
227 return Poll::Pending;
228 }
229
230 loop {
231 match self.list.poll_next_unpin(cx) {
232 Poll::Ready(Some((key, Some(item)))) => return Poll::Ready(Some((key, item))),
233 Poll::Ready(Some((_key, None))) => continue,
235 Poll::Ready(None) => {
236 if self.empty {
243 self.waker = Some(cx.waker().clone());
244 return Poll::Pending;
245 }
246
247 self.empty = true;
248 return Poll::Ready(None);
249 }
250 Poll::Pending => {
251 self.waker = Some(cx.waker().clone());
253 return Poll::Pending;
254 }
255 }
256 }
257 }
258
259 fn size_hint(&self) -> (usize, Option<usize>) {
260 self.list.size_hint()
261 }
262}
263
264impl<K, T> FusedStream for StreamMap<K, T>
265where
266 K: Clone,
267 T: Stream,
268{
269 fn is_terminated(&self) -> bool {
270 self.terminate_on_empty && self.list.is_terminated()
271 }
272}
273
274#[cfg(test)]
275mod test {
276 use crate::stream::StreamMap;
277 use core::pin::Pin;
278 use core::task::{Context, Poll};
279 use futures::stream::empty;
280 use futures::{Stream, StreamExt};
281
282 struct Once<T> {
283 value: T,
284 }
285
286 impl<T> Once<T> {
287 pub fn new(value: T) -> Self {
288 Self { value }
289 }
290
291 pub fn get(&self) -> &T {
292 &self.value
293 }
294
295 pub fn set(&mut self, val: T) {
296 self.value = val;
297 }
298 }
299
300 impl<T> Stream for Once<T>
301 where
302 T: Unpin,
303 {
304 type Item = T;
305 fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Option<Self::Item>> {
306 Poll::Pending
307 }
308 }
309
310 #[test]
311 fn existing_key() {
312 let mut map = StreamMap::new();
313 assert!(map.insert(1, empty::<()>()));
314 assert!(!map.insert(1, empty::<()>()));
315 }
316
317 #[test]
318 fn supports_unboxed_async_stream() {
319 let mut map = StreamMap::new();
320 let stream = futures::stream::unfold(0, |value| async move {
321 (value < 3).then_some((value, value + 1))
322 });
323 assert!(map.insert("numbers", stream));
324
325 futures::executor::block_on(async move {
326 assert_eq!(map.next().await, Some(("numbers", 0)));
327 assert_eq!(map.next().await, Some(("numbers", 1)));
328 assert_eq!(map.next().await, Some(("numbers", 2)));
329 assert_eq!(map.next().await, None);
330 });
331 }
332
333 #[test]
334 fn poll_multiple_keyed_streams() {
335 let mut map = StreamMap::new();
336 map.insert(1, futures::stream::once(async { 10 }).boxed());
337 map.insert(2, futures::stream::once(async { 20 }).boxed());
338
339 map.insert(3, futures::stream::iter(alloc::vec![30, 40, 50]).boxed());
340
341 futures::executor::block_on(async move {
342 assert_eq!(map.next().await, Some((1, 10)));
343 assert_eq!(map.next().await, Some((2, 20)));
344 assert_eq!(map.next().await, Some((3, 30)));
345 assert_eq!(map.next().await, Some((3, 40)));
346 assert_eq!(map.next().await, Some((3, 50)));
347 assert_eq!(map.next().await, None);
348 let pending =
349 futures::future::poll_fn(|cx| Poll::Ready(map.poll_next_unpin(cx).is_pending()))
350 .await;
351 assert!(pending);
352 })
353 }
354
355 #[test]
356 fn get_from_map() {
357 let mut map = StreamMap::new();
358 map.insert(1, Once::new(10));
359 map.insert(2, Once::new(20));
360
361 {
362 let value0 = map.get(&1).expect("valid entry").get();
363 let value1 = map.get(&2).expect("valid entry").get();
364
365 assert_eq!(value0, &10);
366 assert_eq!(value1, &20);
367 }
368
369 {
370 map.get_mut(&1).expect("valid entry").set(100);
371 let value0 = map.get(&1).expect("valid entry").get();
372 assert_eq!(*value0, 100);
373 }
374 }
375}