tuwunel_core/utils/stream/
broadband.rs1use std::convert::identity;
4
5use futures::stream::{Stream, StreamExt};
6
7use super::{ReadyExt, automatic_width};
8
9pub trait BroadbandExt<Item>
14where
15 Self: Stream<Item = Item> + Send + Sized,
16{
17 fn broadn_all<F, Fut, N>(self, n: N, f: F) -> impl Future<Output = bool> + Send
23 where
24 N: Into<Option<usize>>,
25 F: Fn(Item) -> Fut + Send,
26 Fut: Future<Output = bool> + Send;
27
28 fn broadn_any<F, Fut, N>(self, n: N, f: F) -> impl Future<Output = bool> + Send
34 where
35 N: Into<Option<usize>>,
36 F: Fn(Item) -> Fut + Send,
37 Fut: Future<Output = bool> + Send;
38
39 fn broadn_filter_map<F, Fut, U, N>(self, n: N, f: F) -> impl Stream<Item = U> + Send
45 where
46 N: Into<Option<usize>>,
47 F: Fn(Item) -> Fut + Send,
48 Fut: Future<Output = Option<U>> + Send,
49 U: Send;
50
51 fn broadn_find_map<'a, F, Fut, U, N>(
57 self,
58 n: N,
59 f: F,
60 ) -> impl Future<Output = Option<U>> + Send
61 where
62 N: Into<Option<usize>>,
63 F: Fn(Item) -> Fut + Send + 'a,
64 Fut: Future<Output = Option<U>> + Send,
65 U: Send + 'a,
66 Self: Unpin + 'a;
67
68 fn broadn_flat_map<F, Fut, U, N>(self, n: N, f: F) -> impl Stream<Item = U> + Send
74 where
75 N: Into<Option<usize>>,
76 F: Fn(Item) -> Fut + Send,
77 Fut: Stream<Item = U> + Send + Unpin,
78 U: Send;
79
80 fn broadn_then<F, Fut, U, N>(self, n: N, f: F) -> impl Stream<Item = U> + Send
86 where
87 N: Into<Option<usize>>,
88 F: Fn(Item) -> Fut + Send,
89 Fut: Future<Output = U> + Send,
90 U: Send;
91
92 #[inline]
97 fn broad_all<F, Fut>(self, f: F) -> impl Future<Output = bool> + Send
98 where
99 F: Fn(Item) -> Fut + Send,
100 Fut: Future<Output = bool> + Send,
101 {
102 self.broadn_all(None, f)
103 }
104
105 #[inline]
110 fn broad_any<F, Fut>(self, f: F) -> impl Future<Output = bool> + Send
111 where
112 F: Fn(Item) -> Fut + Send,
113 Fut: Future<Output = bool> + Send,
114 {
115 self.broadn_any(None, f)
116 }
117
118 #[inline]
123 fn broad_filter_map<F, Fut, U>(self, f: F) -> impl Stream<Item = U> + Send
124 where
125 F: Fn(Item) -> Fut + Send,
126 Fut: Future<Output = Option<U>> + Send,
127 U: Send,
128 {
129 self.broadn_filter_map(None, f)
130 }
131
132 #[inline]
137 fn broad_find_map<'a, F, Fut, U>(self, f: F) -> impl Future<Output = Option<U>> + Send
138 where
139 F: Fn(Item) -> Fut + Send + 'a,
140 Fut: Future<Output = Option<U>> + Send,
141 U: Send + 'a,
142 Self: Unpin + 'a,
143 {
144 self.broadn_find_map(None, f)
145 }
146
147 #[inline]
152 fn broad_flat_map<F, Fut, U>(self, f: F) -> impl Stream<Item = U> + Send
153 where
154 F: Fn(Item) -> Fut + Send,
155 Fut: Stream<Item = U> + Send + Unpin,
156 U: Send,
157 {
158 self.broadn_flat_map(None, f)
159 }
160
161 #[inline]
166 fn broad_then<F, Fut, U>(self, f: F) -> impl Stream<Item = U> + Send
167 where
168 F: Fn(Item) -> Fut + Send,
169 Fut: Future<Output = U> + Send,
170 U: Send,
171 {
172 self.broadn_then(None, f)
173 }
174}
175
176impl<Item, S> BroadbandExt<Item> for S
177where
178 S: Stream<Item = Item> + Send + Sized,
179{
180 #[inline]
181 fn broadn_all<F, Fut, N>(self, n: N, f: F) -> impl Future<Output = bool> + Send
182 where
183 N: Into<Option<usize>>,
184 F: Fn(Item) -> Fut + Send,
185 Fut: Future<Output = bool> + Send,
186 {
187 self.map(f)
188 .buffer_unordered(n.into().unwrap_or_else(automatic_width))
189 .ready_all(identity)
190 }
191
192 #[inline]
193 fn broadn_any<F, Fut, N>(self, n: N, f: F) -> impl Future<Output = bool> + Send
194 where
195 N: Into<Option<usize>>,
196 F: Fn(Item) -> Fut + Send,
197 Fut: Future<Output = bool> + Send,
198 {
199 self.map(f)
200 .buffer_unordered(n.into().unwrap_or_else(automatic_width))
201 .ready_any(identity)
202 }
203
204 #[inline]
205 fn broadn_filter_map<F, Fut, U, N>(self, n: N, f: F) -> impl Stream<Item = U> + Send
206 where
207 N: Into<Option<usize>>,
208 F: Fn(Item) -> Fut + Send,
209 Fut: Future<Output = Option<U>> + Send,
210 U: Send,
211 {
212 self.map(f)
213 .buffer_unordered(n.into().unwrap_or_else(automatic_width))
214 .ready_filter_map(identity)
215 }
216
217 #[inline]
218 fn broadn_find_map<'a, F, Fut, U, N>(
219 self,
220 n: N,
221 f: F,
222 ) -> impl Future<Output = Option<U>> + Send
223 where
224 N: Into<Option<usize>>,
225 F: Fn(Item) -> Fut + Send + 'a,
226 Fut: Future<Output = Option<U>> + Send,
227 U: Send + 'a,
228 Self: Unpin + 'a,
229 {
230 self.map(f)
231 .buffer_unordered(n.into().unwrap_or_else(automatic_width))
232 .ready_find_map(identity)
233 }
234
235 #[inline]
236 fn broadn_flat_map<F, Fut, U, N>(self, n: N, f: F) -> impl Stream<Item = U> + Send
237 where
238 N: Into<Option<usize>>,
239 F: Fn(Item) -> Fut + Send,
240 Fut: Stream<Item = U> + Send + Unpin,
241 U: Send,
242 {
243 self.flat_map_unordered(n.into().unwrap_or_else(automatic_width), f)
244 }
245
246 #[inline]
247 fn broadn_then<F, Fut, U, N>(self, n: N, f: F) -> impl Stream<Item = U> + Send
248 where
249 N: Into<Option<usize>>,
250 F: Fn(Item) -> Fut + Send,
251 Fut: Future<Output = U> + Send,
252 U: Send,
253 {
254 self.map(f)
255 .buffer_unordered(n.into().unwrap_or_else(automatic_width))
256 }
257}