1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//! Dynamic merge combinator built on top of futures-util's SelectAll.
//!
//! This crate provides a wrapper around `futures_util::stream::SelectAll` that adds
//! dynamic stream management capabilities with a convenient API for adding and managing
//! multiple streams at runtime.
//!
//! ## 1. Direct API with `DynamicMerge`
//!
//! Use `DynamicMerge` directly when you want a single object that owns both the stream
//! and the ability to push new streams:
//!
//! ```rust
//! use futures_concurrency_dynamic::DynamicMerge;
//! use futures_util::stream::{self, StreamExt, SelectAll};
//!
//! # async fn example() {
//! let mut merge: DynamicMerge<'_, i32> = SelectAll::new();
//! merge.push(Box::pin(stream::iter(vec![1, 2, 3])));
//! merge.push(Box::pin(stream::iter(vec![4, 5, 6])));
//!
//! while let Some(item) = merge.next().await {
//! println!("{}", item);
//! }
//! # }
//! ```
//!
//! ## 2. Handle-based API with `dynamic_merge_with_handle`
//!
//! Use the handle-based API when you need separate mutable references to the stream
//! and the push functionality. This is useful when different parts of your code need
//! to own and mutate each component independently:
//!
//! ```rust
//! use futures_concurrency_dynamic::dynamic_merge_with_handle;
//! use futures_util::stream::{self, StreamExt};
//!
//! # async fn example() {
//! let (mut stream, mut handle) = dynamic_merge_with_handle::<i32>();
//!
//! // One task can push streams
//! let producer = tokio::spawn(async move {
//! handle.push(stream::iter(vec![1, 2, 3]));
//! handle.push(stream::iter(vec![4, 5, 6]));
//! });
//!
//! // Another task can consume from the stream
//! let consumer = tokio::spawn(async move {
//! while let Some(item) = stream.next().await {
//! println!("{}", item);
//! }
//! });
//!
//! producer.await.unwrap();
//! consumer.await.unwrap();
//! # }
//! ```
//!
//! ## Implementation Note
//!
//! This crate is built on top of `futures_util::stream::SelectAll`, providing a more
//! ergonomic API while leveraging the proven implementation from the futures ecosystem.
//! All streams must be `Send + 'static`. If you need to work with borrowed streams,
//! consider using `futures_util::stream::SelectAll` directly.
pub use DynamicMerge;
pub use ;