1use super::flow::{self, FlowTransform};
11use super::*;
12use crate::Attributes;
13use crate::context::SourceWithContext;
14use crate::instrument::{InstrumentedStream, StreamInstrumentationRegistry};
15
16#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
17pub struct NotUsed;
18
19type CombinedSourceFactory<Out> =
20 dyn Fn(&Materializer) -> StreamResult<BoxStream<Out>> + Send + Sync;
21
22pub struct Keep;
23
24impl Keep {
25 pub fn left<Left, Right>(left: Left, _right: Right) -> Left {
26 left
27 }
28
29 pub fn right<Left, Right>(_left: Left, right: Right) -> Right {
30 right
31 }
32
33 pub fn both<Left, Right>(left: Left, right: Right) -> (Left, Right) {
34 (left, right)
35 }
36
37 pub fn none<Left, Right>(_left: Left, _right: Right) -> NotUsed {
38 NotUsed
39 }
40}
41
42#[derive(Debug, Clone, PartialEq, Eq)]
43pub enum SourceCombineStrategy {
44 Merge {
45 eager_complete: bool,
46 },
47 Concat,
48 Prioritized {
49 priorities: Vec<usize>,
50 eager_complete: bool,
51 },
52}
53
54#[derive(Clone)]
55pub struct MaybeHandle<T> {
56 value: Arc<Mutex<Option<StreamResult<T>>>>,
57}
58
59impl<T> MaybeHandle<T> {
60 #[must_use]
61 pub fn is_completed(&self) -> bool {
62 self.value.lock().expect("maybe handle poisoned").is_some()
63 }
64
65 pub fn complete(&self, item: T) -> StreamResult<()> {
66 self.settle(Ok(item))
67 }
68
69 pub fn fail(&self, error: StreamError) -> StreamResult<()> {
70 self.settle(Err(error))
71 }
72
73 fn settle(&self, result: StreamResult<T>) -> StreamResult<()> {
74 let mut value = self.value.lock().expect("maybe handle poisoned");
75 if value.is_some() {
76 return Err(StreamError::Failed("maybe source already completed".into()));
77 }
78 *value = Some(result);
79 Ok(())
80 }
81}
82
83#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
84pub struct Demand(u64);
85
86impl Demand {
87 pub const ZERO: Self = Self(0);
88 pub const ONE: Self = Self(1);
89 pub const MAX: Self = Self(u64::MAX);
90
91 #[must_use]
92 pub const fn new(available: u64) -> Self {
93 Self(available)
94 }
95
96 #[must_use]
97 pub const fn available(self) -> u64 {
98 self.0
99 }
100
101 #[must_use]
102 pub const fn is_unbounded(self) -> bool {
103 self.0 == u64::MAX
104 }
105
106 #[must_use]
107 pub const fn is_empty(self) -> bool {
108 self.0 == 0
109 }
110
111 #[must_use]
112 pub const fn saturating_add(self, rhs: Self) -> Self {
113 Self(self.0.saturating_add(rhs.0))
114 }
115
116 pub fn consume_one(&mut self) -> bool {
117 match self.0 {
118 0 => false,
119 u64::MAX => true,
120 _ => {
121 self.0 -= 1;
122 true
123 }
124 }
125 }
126}
127
128pub trait PushOutlet<T>: Send {
129 fn push(&mut self, item: T) -> StreamResult<Demand>;
130
131 fn complete(&mut self) -> StreamResult<()> {
132 Ok(())
133 }
134
135 fn fail(&mut self, cause: StreamError) -> StreamResult<()> {
136 Err(cause)
137 }
138}
139
140#[derive(Clone)]
141pub struct Source<Out, Mat = NotUsed> {
142 pub(crate) factory: Arc<dyn SourceFactory<Out, Mat>>,
143 pub(crate) terminal_factory: Option<Arc<TerminalSourceFactory<Out, Mat>>>,
144 pub(super) hints: SourceHints,
145 pub(super) attributes: Attributes,
146 pub(crate) split_hook: Option<Arc<dyn SplitSegmentHookDyn>>,
149}
150
151pub(crate) type TerminalSourceFactory<Out, Mat> =
152 dyn Fn(&Materializer) -> StreamResult<(Arc<dyn TerminalSourceHookDyn<Out>>, Mat)> + Send + Sync;
153
154impl<Out: Send + 'static> Source<Out, NotUsed> {
155 pub(super) fn from_factory<F>(factory: F) -> Self
156 where
157 F: Fn() -> BoxStream<Out> + Send + Sync + 'static,
158 {
159 Self::from_factory_with_hints(factory, SourceHints::default())
160 }
161
162 fn from_factory_with_hints<F>(factory: F, hints: SourceHints) -> Self
163 where
164 F: Fn() -> BoxStream<Out> + Send + Sync + 'static,
165 {
166 Self::from_materialized_factory_with_hints(
167 move |_materializer| Ok((factory(), NotUsed)),
168 hints,
169 )
170 }
171
172 #[must_use]
173 pub fn empty() -> Self {
174 Self::from_factory_with_hints(
175 || Box::new(std::iter::empty()),
176 SourceHints::with_inline_micro(0),
177 )
178 }
179
180 #[must_use]
181 pub fn never() -> Self {
182 Self::from_materialized_factory_with_hints(
183 move |materializer| {
184 let state = Arc::clone(&materializer.inner.state);
185 Ok((
186 Box::new(std::iter::from_fn(move || {
187 loop {
188 if state.shutdown.load(Ordering::SeqCst) {
189 return Some(Err(StreamError::AbruptTermination));
190 }
191 if super::runtime::current_stream_cancelled()
192 .as_ref()
193 .is_some_and(|cancelled| cancelled.load(Ordering::SeqCst))
194 {
195 return Some(Err(StreamError::Cancelled));
196 }
197 std::thread::park_timeout(Duration::from_millis(1));
198 }
199 })),
200 NotUsed,
201 ))
202 },
203 SourceHints::default(),
204 )
205 }
206
207 #[must_use]
208 pub fn failed(error: StreamError) -> Self {
209 Self::from_factory_with_hints(
210 move || Box::new(std::iter::once(Err(error.clone()))),
211 SourceHints::with_inline_micro(0),
213 )
214 }
215
216 #[must_use]
217 pub fn future<F, Fut>(future: F) -> Self
218 where
219 F: Fn() -> Fut + Send + Sync + 'static,
220 Fut: Future<Output = StreamResult<Out>> + Send + 'static,
221 {
222 let future = Arc::new(future);
223 Self::from_factory(move || {
224 let future = Arc::clone(&future);
225 let mut emitted = false;
226 Box::new(std::iter::from_fn(move || {
227 if emitted {
228 return None;
229 }
230 emitted = true;
231 Some(
232 catch_unwind_failed("source future factory", || future())
233 .and_then(flow::run_future_inline_or_spawn),
234 )
235 }))
236 })
237 }
238
239 #[must_use]
240 pub fn future_source<F, Fut>(future: F) -> Self
241 where
242 F: Fn() -> Fut + Send + Sync + 'static,
243 Fut: Future<Output = StreamResult<Source<Out>>> + Send + 'static,
244 {
245 let future = Arc::new(future);
246 Self::from_materialized_factory(move |materializer| {
247 let materializer = materializer.with_name_prefix(materializer.name_prefix().to_owned());
248 let future = Arc::clone(&future);
249 let mut current = None::<BoxStream<Out>>;
250 let mut initialized = false;
251 let mut terminated = false;
252 Ok((
253 Box::new(std::iter::from_fn(move || {
254 if terminated {
255 return None;
256 }
257
258 loop {
259 if let Some(stream) = current.as_mut() {
260 match stream.next() {
261 Some(item) => return Some(item),
262 None => {
263 terminated = true;
264 return None;
265 }
266 }
267 }
268
269 if initialized {
270 terminated = true;
271 return None;
272 }
273 initialized = true;
274 let source = match catch_unwind_failed("future_source factory", || future())
275 .and_then(flow::run_future_inline_or_spawn)
276 {
277 Ok(source) => source,
278 Err(error) => {
279 terminated = true;
280 return Some(Err(error));
281 }
282 };
283 current = Some(match Arc::clone(&source.factory).create(&materializer) {
284 Ok((stream, _)) => stream,
285 Err(error) => {
286 terminated = true;
287 return Some(Err(error));
288 }
289 });
290 }
291 })) as BoxStream<Out>,
292 NotUsed,
293 ))
294 })
295 }
296
297 #[must_use]
298 pub fn cycle<F, I>(factory: F) -> Self
299 where
300 F: Fn() -> I + Send + Sync + 'static,
301 I: IntoIterator<Item = Out>,
302 I::IntoIter: Send + 'static,
303 {
304 let factory = Arc::new(factory);
305 Self::from_factory(move || {
306 let factory = Arc::clone(&factory);
307 let mut current = None::<I::IntoIter>;
308 let mut terminated = false;
309 Box::new(std::iter::from_fn(move || {
310 if terminated {
311 return None;
312 }
313
314 if let Some(iter) = current.as_mut()
315 && let Some(item) = iter.next()
316 {
317 return Some(Ok(item));
318 }
319
320 let mut next = match catch_unwind_failed("cycle factory", || factory()) {
321 Ok(iterable) => iterable.into_iter(),
322 Err(error) => {
323 terminated = true;
324 return Some(Err(error));
325 }
326 };
327 match next.next() {
328 Some(item) => {
329 current = Some(next);
330 Some(Ok(item))
331 }
332 None => {
333 terminated = true;
334 Some(Err(StreamError::Failed("empty iterator".into())))
335 }
336 }
337 }))
338 })
339 }
340
341 #[must_use]
342 pub fn unfold<State, F>(initial: State, f: F) -> Self
343 where
344 State: Clone + Send + Sync + 'static,
345 F: Fn(State) -> Option<(State, Out)> + Send + Sync + 'static,
346 {
347 let f = Arc::new(f);
348 Self::from_factory(move || {
349 let f = Arc::clone(&f);
350 let mut state = Some(initial.clone());
351 let mut terminated = false;
352 Box::new(std::iter::from_fn(move || {
353 if terminated {
354 return None;
355 }
356 let current = state.take().expect("unfold state present");
357 match catch_unwind_failed("unfold function", || f(current)) {
358 Ok(Some((next_state, item))) => {
359 state = Some(next_state);
360 Some(Ok(item))
361 }
362 Ok(None) => {
363 terminated = true;
364 None
365 }
366 Err(error) => {
367 terminated = true;
368 Some(Err(error))
369 }
370 }
371 }))
372 })
373 }
374
375 #[must_use]
376 pub fn unfold_async<State, F, Fut>(initial: State, f: F) -> Self
377 where
378 State: Clone + Send + Sync + 'static,
379 F: Fn(State) -> Fut + Send + Sync + 'static,
380 Fut: Future<Output = StreamResult<Option<(State, Out)>>> + Send + 'static,
381 {
382 let f = Arc::new(f);
383 Self::from_factory(move || {
384 let f = Arc::clone(&f);
385 let mut state = Some(initial.clone());
386 let mut terminated = false;
387 Box::new(std::iter::from_fn(move || {
388 if terminated {
389 return None;
390 }
391 let current = state.take().expect("unfold_async state present");
392 match catch_unwind_failed("unfold_async factory", || f(current))
393 .and_then(flow::run_future_inline_or_spawn)
394 {
395 Ok(Some((next_state, item))) => {
396 state = Some(next_state);
397 Some(Ok(item))
398 }
399 Ok(None) => {
400 terminated = true;
401 None
402 }
403 Err(error) => {
404 terminated = true;
405 Some(Err(error))
406 }
407 }
408 }))
409 })
410 }
411
412 #[must_use]
413 pub fn unfold_resource<Resource, Create, Read, Close>(
414 create: Create,
415 read: Read,
416 close: Close,
417 ) -> Self
418 where
419 Resource: Send + 'static,
420 Create: Fn() -> StreamResult<Resource> + Send + Sync + 'static,
421 Read: Fn(&mut Resource) -> StreamResult<Option<Out>> + Send + Sync + 'static,
422 Close: Fn(Resource) -> StreamResult<()> + Send + Sync + 'static,
423 {
424 let create = Arc::new(create);
425 let read = Arc::new(read);
426 let close = Arc::new(close);
427 Self::from_factory(move || {
428 Box::new(UnfoldResourceStream {
429 create: Arc::clone(&create),
430 read: Arc::clone(&read),
431 close: Arc::clone(&close),
432 resource: None,
433 created: false,
434 terminated: false,
435 _marker: PhantomData,
436 })
437 })
438 }
439
440 #[must_use]
441 pub fn unfold_resource_async<Resource, Create, CreateFut, Read, ReadFut, Close, CloseFut>(
442 create: Create,
443 read: Read,
444 close: Close,
445 ) -> Self
446 where
447 Resource: Send + 'static,
448 Create: Fn() -> CreateFut + Send + Sync + 'static,
449 CreateFut: Future<Output = StreamResult<Resource>> + Send + 'static,
450 Read: Fn(&mut Resource) -> ReadFut + Send + Sync + 'static,
451 ReadFut: Future<Output = StreamResult<Option<Out>>> + Send + 'static,
452 Close: Fn(Resource) -> CloseFut + Send + Sync + 'static,
453 CloseFut: Future<Output = StreamResult<()>> + Send + 'static,
454 {
455 let create = Arc::new(create);
456 let read = Arc::new(read);
457 let close = Arc::new(close);
458 Self::from_factory(move || {
459 Box::new(UnfoldResourceAsyncStream {
460 create: Arc::clone(&create),
461 read: Arc::clone(&read),
462 close: Arc::clone(&close),
463 resource: None,
464 created: false,
465 terminated: false,
466 _marker: PhantomData,
467 })
468 })
469 }
470
471 #[must_use]
472 pub fn lazy_single<F>(create: F) -> Self
473 where
474 F: Fn() -> Out + Send + Sync + 'static,
475 {
476 let create = Arc::new(create);
477 Self::from_factory(move || {
478 let create = Arc::clone(&create);
479 let mut emitted = false;
480 Box::new(std::iter::from_fn(move || {
481 if emitted {
482 return None;
483 }
484 emitted = true;
485 Some(catch_unwind_failed("lazy_single factory", || create()))
486 }))
487 })
488 }
489
490 #[must_use]
491 pub fn lazy_future<F, Fut>(create: F) -> Self
492 where
493 F: Fn() -> Fut + Send + Sync + 'static,
494 Fut: Future<Output = StreamResult<Out>> + Send + 'static,
495 {
496 let create = Arc::new(create);
497 Self::from_factory(move || {
498 let create = Arc::clone(&create);
499 let mut emitted = false;
500 Box::new(std::iter::from_fn(move || {
501 if emitted {
502 return None;
503 }
504 emitted = true;
505 Some(
506 catch_unwind_failed("lazy_future factory", || create())
507 .and_then(flow::run_future_inline_or_spawn),
508 )
509 }))
510 })
511 }
512
513 #[must_use]
514 pub fn lazy_source<InnerMat, F>(create: F) -> Source<Out, StreamCompletion<InnerMat>>
515 where
516 InnerMat: Send + 'static,
517 F: Fn() -> Source<Out, InnerMat> + Send + Sync + 'static,
518 {
519 let create = Arc::new(create);
520 Source::from_materialized_factory(move |materializer| {
521 let (sender, receiver) = oneshot::channel();
522 Ok((
523 Box::new(LazySourceStream {
524 create: Arc::clone(&create),
525 materializer: materializer
526 .with_name_prefix(materializer.name_prefix().to_owned()),
527 current: None,
528 mat_sender: Some(sender),
529 initialized: false,
530 terminated: false,
531 }) as BoxStream<Out>,
532 StreamCompletion::from_receiver(receiver, None),
533 ))
534 })
535 }
536
537 #[must_use]
538 pub fn lazy_future_source<InnerMat, F, Fut>(
539 create: F,
540 ) -> Source<Out, StreamCompletion<InnerMat>>
541 where
542 InnerMat: Send + 'static,
543 F: Fn() -> Fut + Send + Sync + 'static,
544 Fut: Future<Output = StreamResult<Source<Out, InnerMat>>> + Send + 'static,
545 {
546 let create = Arc::new(create);
547 Source::from_materialized_factory(move |materializer| {
548 let (sender, receiver) = oneshot::channel();
549 Ok((
550 Box::new(LazyFutureSourceStream {
551 create: Arc::clone(&create),
552 materializer: materializer
553 .with_name_prefix(materializer.name_prefix().to_owned()),
554 current: None,
555 mat_sender: Some(sender),
556 initialized: false,
557 terminated: false,
558 _marker: PhantomData,
559 }) as BoxStream<Out>,
560 StreamCompletion::from_receiver(receiver, None),
561 ))
562 })
563 }
564
565 #[must_use]
566 pub fn from_fn_iter<F, I>(factory: F) -> Self
567 where
568 F: Fn() -> I + Send + Sync + 'static,
569 I: IntoIterator<Item = Out>,
570 I::IntoIter: Send + 'static,
571 {
572 Self::from_factory(move || Box::new(factory().into_iter().map(Ok)))
573 }
574}
575
576impl<Out: Send + 'static, Mat: Send + 'static> Source<Out, Mat> {
577 fn from_materialized_factory_with_hints<F>(factory: F, hints: SourceHints) -> Self
578 where
579 F: Fn(&Materializer) -> StreamResult<(BoxStream<Out>, Mat)> + Send + Sync + 'static,
580 {
581 Self {
582 factory: Arc::new(FnSourceFactory(factory)),
583 terminal_factory: None,
584 hints,
585 attributes: Attributes::default(),
586 split_hook: None,
587 }
588 }
589
590 pub(crate) fn from_materialized_factory<F>(factory: F) -> Self
591 where
592 F: Fn(&Materializer) -> StreamResult<(BoxStream<Out>, Mat)> + Send + Sync + 'static,
593 {
594 Self::from_materialized_factory_with_hints(factory, SourceHints::default())
595 }
596
597 pub(crate) fn from_terminal_direct_materialized_factory<F, D>(
598 factory: F,
599 terminal_factory: D,
600 ) -> Self
601 where
602 F: Fn(&Materializer) -> StreamResult<(BoxStream<Out>, Mat)> + Send + Sync + 'static,
603 D: Fn(&Materializer) -> StreamResult<(Arc<dyn TerminalSourceHookDyn<Out>>, Mat)>
604 + Send
605 + Sync
606 + 'static,
607 {
608 Self {
609 factory: Arc::new(FnSourceFactory(factory)),
610 terminal_factory: Some(Arc::new(terminal_factory)),
611 hints: SourceHints::with_terminal_consumer_batch(),
612 attributes: Attributes::default(),
613 split_hook: None,
614 }
615 }
616
617 #[must_use]
618 pub fn as_source_with_context<Ctx, F>(
619 self,
620 extract_context: F,
621 ) -> SourceWithContext<Out, Ctx, Mat>
622 where
623 Ctx: Send + 'static,
624 F: Fn(&Out) -> Ctx + Send + Sync + 'static,
625 {
626 SourceWithContext::from_source(self.map(move |item| {
627 let context = extract_context(&item);
628 (item, context)
629 }))
630 }
631
632 #[must_use]
633 pub fn via<Next, FlowMat>(self, flow: Flow<Out, Next, FlowMat>) -> Source<Next, Mat>
634 where
635 Next: Send + 'static,
636 FlowMat: Send + 'static,
637 {
638 self.via_mat(flow, Keep::left)
639 }
640
641 #[must_use]
642 pub fn via_mat<Next, FlowMat, Combined, F>(
643 self,
644 flow: Flow<Out, Next, FlowMat>,
645 combine: F,
646 ) -> Source<Next, Combined>
647 where
648 Next: Send + 'static,
649 FlowMat: Send + 'static,
650 Combined: Send + 'static,
651 F: Fn(Mat, FlowMat) -> Combined + Send + Sync + 'static,
652 {
653 let source = self.factory;
654 let transform = flow.transform;
655 let materialize_flow = flow.materialize;
656 let hints = self.hints.after_flow(flow.hints);
657 let combine = Arc::new(combine);
658 Source::from_materialized_factory_with_hints(
659 move |materializer| {
660 let (stream, source_mat) = Arc::clone(&source).create(materializer)?;
661 let flow_mat = materialize_flow()?;
662 let stream = match &transform {
663 FlowTransform::Pure(transform) => transform(stream),
664 FlowTransform::Runtime(transform) => transform(stream, materializer)?,
665 };
666 Ok((stream, combine(source_mat, flow_mat)))
667 },
668 hints,
669 )
670 }
671
672 #[must_use]
673 pub fn via_mat_with<Next, FlowMat, Combined, F>(
674 self,
675 flow: Flow<Out, Next, FlowMat>,
676 combine: F,
677 ) -> Source<Next, Combined>
678 where
679 Next: Send + 'static,
680 FlowMat: Send + 'static,
681 Combined: Send + 'static,
682 F: Fn(Mat, FlowMat) -> Combined + Send + Sync + 'static,
683 {
684 self.via_mat(flow, combine)
685 }
686
687 #[must_use]
688 pub fn map<Next, F>(self, f: F) -> Source<Next, Mat>
689 where
690 Next: Send + 'static,
691 F: Fn(Out) -> Next + Send + Sync + 'static,
692 {
693 let hints = self.hints.without_inline_micro();
694 Source {
695 factory: Arc::new(MapSourceFactory {
696 source: self.factory,
697 stage: f,
698 _marker: PhantomData,
699 }),
700 terminal_factory: None,
701 hints,
702 attributes: self.attributes,
703 split_hook: None,
704 }
705 }
706
707 #[must_use]
708 pub fn attributes(&self) -> &Attributes {
709 &self.attributes
710 }
711
712 #[must_use]
713 pub fn with_attributes(mut self, attributes: Attributes) -> Self {
714 self.attributes = attributes;
715 self
716 }
717
718 #[must_use]
719 pub fn add_attributes(mut self, attributes: Attributes) -> Self {
720 self.attributes = self.attributes.and(attributes);
721 self
722 }
723
724 #[must_use]
725 pub fn named(self, name: impl Into<String>) -> Self {
726 self.add_attributes(Attributes::named(name))
727 }
728
729 #[must_use]
739 pub fn instrumented(
740 self,
741 name: impl Into<String>,
742 registry: &StreamInstrumentationRegistry,
743 ) -> Self {
744 let Source {
745 factory,
746 terminal_factory: _,
747 hints,
748 attributes,
749 split_hook: _,
750 } = self;
751 let name: Arc<str> = Arc::from(name.into());
752 let registry = registry.clone();
753 let mut source = Source::from_materialized_factory_with_hints(
754 move |materializer| {
755 let run = registry.register(name.as_ref().to_owned());
756 match Arc::clone(&factory).create(materializer) {
757 Ok((stream, mat)) => Ok((
758 Box::new(InstrumentedStream::new(stream, run)) as BoxStream<Out>,
759 mat,
760 )),
761 Err(error) => {
762 run.mark_failed();
763 Err(error)
764 }
765 }
766 },
767 hints.without_inline_micro(),
768 );
769 source.attributes = attributes;
770 source
771 }
772
773 #[must_use]
780 pub fn async_boundary(self) -> Self {
781 self.via(Flow::identity().async_boundary())
782 }
783
784 #[must_use]
786 pub fn r#async(self) -> Self {
787 self.async_boundary()
788 }
789
790 #[must_use]
796 pub fn async_boundary_with_config(
797 self,
798 config: crate::graph::AsyncBoundaryExecutionConfig,
799 ) -> Self {
800 self.via(Flow::identity().async_boundary_with_config(config))
801 }
802
803 #[must_use]
805 pub fn async_boundary_with_buffer(self, buffer_size: usize) -> Self {
806 self.via(Flow::identity().async_boundary_with_buffer(buffer_size))
807 }
808
809 #[must_use]
810 pub fn try_map<Next, F>(self, f: F) -> Source<Next, Mat>
811 where
812 Next: Send + 'static,
813 F: Fn(Out) -> StreamResult<Next> + Send + Sync + 'static,
814 {
815 self.via(Flow::identity().try_map(f))
816 }
817
818 #[must_use]
820 #[deprecated(
821 since = "0.9.0",
822 note = "renamed to `try_map` (idiomatic); the `_result` name still works"
823 )]
824 pub fn map_result<Next, F>(self, f: F) -> Source<Next, Mat>
825 where
826 Next: Send + 'static,
827 F: Fn(Out) -> StreamResult<Next> + Send + Sync + 'static,
828 {
829 self.try_map(f)
830 }
831
832 #[must_use]
833 pub fn map_result_with_supervision<Next, F>(
834 self,
835 f: F,
836 decider: SupervisionDecider,
837 ) -> Source<Next, Mat>
838 where
839 Next: Send + 'static,
840 F: Fn(Out) -> StreamResult<Next> + Send + Sync + 'static,
841 {
842 self.via(Flow::identity().map_result_with_supervision(f, decider))
843 }
844
845 #[must_use]
846 pub fn filter<F>(self, predicate: F) -> Source<Out, Mat>
847 where
848 F: Fn(&Out) -> bool + Send + Sync + 'static,
849 {
850 self.via(Flow::identity().filter(predicate))
851 }
852
853 #[must_use]
854 pub fn try_filter<F>(self, predicate: F) -> Source<Out, Mat>
855 where
856 F: Fn(&Out) -> StreamResult<bool> + Send + Sync + 'static,
857 {
858 self.via(Flow::identity().try_filter(predicate))
859 }
860
861 #[must_use]
863 #[deprecated(
864 since = "0.9.0",
865 note = "renamed to `try_filter` (idiomatic); the `_result` name still works"
866 )]
867 pub fn filter_result<F>(self, predicate: F) -> Source<Out, Mat>
868 where
869 F: Fn(&Out) -> StreamResult<bool> + Send + Sync + 'static,
870 {
871 self.try_filter(predicate)
872 }
873
874 #[must_use]
875 pub fn filter_result_with_supervision<F>(
876 self,
877 predicate: F,
878 decider: SupervisionDecider,
879 ) -> Source<Out, Mat>
880 where
881 F: Fn(&Out) -> StreamResult<bool> + Send + Sync + 'static,
882 {
883 self.via(Flow::identity().filter_result_with_supervision(predicate, decider))
884 }
885
886 #[must_use]
887 pub fn filter_not<F>(self, predicate: F) -> Source<Out, Mat>
888 where
889 F: Fn(&Out) -> bool + Send + Sync + 'static,
890 {
891 self.via(Flow::identity().filter_not(predicate))
892 }
893
894 #[must_use]
895 pub fn filter_map<Next, F>(self, f: F) -> Source<Next, Mat>
896 where
897 Next: Send + 'static,
898 F: Fn(Out) -> Option<Next> + Send + Sync + 'static,
899 {
900 self.via(Flow::identity().filter_map(f))
901 }
902
903 #[must_use]
904 pub fn try_filter_map<Next, F>(self, f: F) -> Source<Next, Mat>
905 where
906 Next: Send + 'static,
907 F: Fn(Out) -> StreamResult<Option<Next>> + Send + Sync + 'static,
908 {
909 self.via(Flow::identity().try_filter_map(f))
910 }
911
912 #[must_use]
914 #[deprecated(
915 since = "0.9.0",
916 note = "renamed to `try_filter_map` (idiomatic); the `_result` name still works"
917 )]
918 pub fn filter_map_result<Next, F>(self, f: F) -> Source<Next, Mat>
919 where
920 Next: Send + 'static,
921 F: Fn(Out) -> StreamResult<Option<Next>> + Send + Sync + 'static,
922 {
923 self.try_filter_map(f)
924 }
925
926 #[must_use]
927 pub fn filter_map_result_with_supervision<Next, F>(
928 self,
929 f: F,
930 decider: SupervisionDecider,
931 ) -> Source<Next, Mat>
932 where
933 Next: Send + 'static,
934 F: Fn(Out) -> StreamResult<Option<Next>> + Send + Sync + 'static,
935 {
936 self.via(Flow::identity().filter_map_result_with_supervision(f, decider))
937 }
938
939 #[must_use]
940 pub fn map_concat<Next, F, I>(self, f: F) -> Source<Next, Mat>
941 where
942 Next: Send + 'static,
943 F: Fn(Out) -> I + Send + Sync + 'static,
944 I: IntoIterator<Item = Next>,
945 I::IntoIter: Send + 'static,
946 {
947 self.via(Flow::identity().map_concat(f))
948 }
949
950 #[must_use]
951 pub fn try_map_concat<Next, F, I>(self, f: F) -> Source<Next, Mat>
952 where
953 Next: Send + 'static,
954 F: Fn(Out) -> StreamResult<I> + Send + Sync + 'static,
955 I: IntoIterator<Item = Next>,
956 I::IntoIter: Send + 'static,
957 {
958 self.via(Flow::identity().try_map_concat(f))
959 }
960
961 #[must_use]
963 #[deprecated(
964 since = "0.9.0",
965 note = "renamed to `try_map_concat` (idiomatic); the `_result` name still works"
966 )]
967 pub fn map_concat_result<Next, F, I>(self, f: F) -> Source<Next, Mat>
968 where
969 Next: Send + 'static,
970 F: Fn(Out) -> StreamResult<I> + Send + Sync + 'static,
971 I: IntoIterator<Item = Next>,
972 I::IntoIter: Send + 'static,
973 {
974 self.try_map_concat(f)
975 }
976
977 #[must_use]
978 pub fn map_concat_result_with_supervision<Next, F, I>(
979 self,
980 f: F,
981 decider: SupervisionDecider,
982 ) -> Source<Next, Mat>
983 where
984 Next: Send + 'static,
985 F: Fn(Out) -> StreamResult<I> + Send + Sync + 'static,
986 I: IntoIterator<Item = Next>,
987 I::IntoIter: Send + 'static,
988 {
989 self.via(Flow::identity().map_concat_result_with_supervision(f, decider))
990 }
991
992 #[must_use]
993 pub fn stateful_map<State, Next, F>(self, seed: State, f: F) -> Source<Next, Mat>
994 where
995 State: Clone + Send + Sync + 'static,
996 Next: Send + 'static,
997 F: Fn(&mut State, Out) -> Next + Send + Sync + 'static,
998 {
999 self.via(Flow::identity().stateful_map(seed, f))
1000 }
1001
1002 #[must_use]
1003 pub fn try_stateful_map<State, Next, F>(self, seed: State, f: F) -> Source<Next, Mat>
1004 where
1005 State: Clone + Send + Sync + 'static,
1006 Next: Send + 'static,
1007 F: Fn(&mut State, Out) -> StreamResult<Next> + Send + Sync + 'static,
1008 {
1009 self.via(Flow::identity().try_stateful_map(seed, f))
1010 }
1011
1012 #[must_use]
1014 #[deprecated(
1015 since = "0.9.0",
1016 note = "renamed to `try_stateful_map` (idiomatic); the `_result` name still works"
1017 )]
1018 pub fn stateful_map_result<State, Next, F>(self, seed: State, f: F) -> Source<Next, Mat>
1019 where
1020 State: Clone + Send + Sync + 'static,
1021 Next: Send + 'static,
1022 F: Fn(&mut State, Out) -> StreamResult<Next> + Send + Sync + 'static,
1023 {
1024 self.try_stateful_map(seed, f)
1025 }
1026
1027 #[must_use]
1028 pub fn stateful_map_result_with_supervision<State, Next, F>(
1029 self,
1030 seed: State,
1031 f: F,
1032 decider: SupervisionDecider,
1033 ) -> Source<Next, Mat>
1034 where
1035 State: Clone + Send + Sync + 'static,
1036 Next: Send + 'static,
1037 F: Fn(&mut State, Out) -> StreamResult<Next> + Send + Sync + 'static,
1038 {
1039 self.via(Flow::identity().stateful_map_result_with_supervision(seed, f, decider))
1040 }
1041
1042 #[must_use]
1043 pub fn stateful_map_concat<State, Next, F, I>(self, seed: State, f: F) -> Source<Next, Mat>
1044 where
1045 State: Clone + Send + Sync + 'static,
1046 Next: Send + 'static,
1047 F: Fn(&mut State, Out) -> I + Send + Sync + 'static,
1048 I: IntoIterator<Item = Next>,
1049 I::IntoIter: Send + 'static,
1050 {
1051 self.via(Flow::identity().stateful_map_concat(seed, f))
1052 }
1053
1054 #[must_use]
1055 pub fn try_stateful_map_concat<State, Next, F, I>(self, seed: State, f: F) -> Source<Next, Mat>
1056 where
1057 State: Clone + Send + Sync + 'static,
1058 Next: Send + 'static,
1059 F: Fn(&mut State, Out) -> StreamResult<I> + Send + Sync + 'static,
1060 I: IntoIterator<Item = Next>,
1061 I::IntoIter: Send + 'static,
1062 {
1063 self.via(Flow::identity().try_stateful_map_concat(seed, f))
1064 }
1065
1066 #[must_use]
1068 #[deprecated(
1069 since = "0.9.0",
1070 note = "renamed to `try_stateful_map_concat` (idiomatic); the `_result` name still works"
1071 )]
1072 pub fn stateful_map_concat_result<State, Next, F, I>(
1073 self,
1074 seed: State,
1075 f: F,
1076 ) -> Source<Next, Mat>
1077 where
1078 State: Clone + Send + Sync + 'static,
1079 Next: Send + 'static,
1080 F: Fn(&mut State, Out) -> StreamResult<I> + Send + Sync + 'static,
1081 I: IntoIterator<Item = Next>,
1082 I::IntoIter: Send + 'static,
1083 {
1084 self.try_stateful_map_concat(seed, f)
1085 }
1086
1087 #[must_use]
1088 pub fn stateful_map_concat_result_with_supervision<State, Next, F, I>(
1089 self,
1090 seed: State,
1091 f: F,
1092 decider: SupervisionDecider,
1093 ) -> Source<Next, Mat>
1094 where
1095 State: Clone + Send + Sync + 'static,
1096 Next: Send + 'static,
1097 F: Fn(&mut State, Out) -> StreamResult<I> + Send + Sync + 'static,
1098 I: IntoIterator<Item = Next>,
1099 I::IntoIter: Send + 'static,
1100 {
1101 self.via(Flow::identity().stateful_map_concat_result_with_supervision(seed, f, decider))
1102 }
1103
1104 #[must_use]
1105 pub fn map_async<Next, F, Fut>(self, parallelism: usize, f: F) -> Source<Next, Mat>
1106 where
1107 Next: Send + 'static,
1108 F: Fn(Out) -> Fut + Send + Sync + 'static,
1109 Fut: Future<Output = StreamResult<Next>> + Send + 'static,
1110 {
1111 self.via(Flow::identity().map_async(parallelism, f))
1112 }
1113
1114 #[must_use]
1115 pub fn map_async_with_supervision<Next, F, Fut>(
1116 self,
1117 parallelism: usize,
1118 f: F,
1119 decider: SupervisionDecider,
1120 ) -> Source<Next, Mat>
1121 where
1122 Next: Send + 'static,
1123 F: Fn(Out) -> Fut + Send + Sync + 'static,
1124 Fut: Future<Output = StreamResult<Next>> + Send + 'static,
1125 {
1126 self.via(Flow::identity().map_async_with_supervision(parallelism, f, decider))
1127 }
1128
1129 #[must_use]
1130 pub fn map_async_unordered<Next, F, Fut>(self, parallelism: usize, f: F) -> Source<Next, Mat>
1131 where
1132 Next: Send + 'static,
1133 F: Fn(Out) -> Fut + Send + Sync + 'static,
1134 Fut: Future<Output = StreamResult<Next>> + Send + 'static,
1135 {
1136 self.via(Flow::identity().map_async_unordered(parallelism, f))
1137 }
1138
1139 #[must_use]
1140 pub fn map_async_unordered_with_supervision<Next, F, Fut>(
1141 self,
1142 parallelism: usize,
1143 f: F,
1144 decider: SupervisionDecider,
1145 ) -> Source<Next, Mat>
1146 where
1147 Next: Send + 'static,
1148 F: Fn(Out) -> Fut + Send + Sync + 'static,
1149 Fut: Future<Output = StreamResult<Next>> + Send + 'static,
1150 {
1151 self.via(Flow::identity().map_async_unordered_with_supervision(parallelism, f, decider))
1152 }
1153
1154 #[must_use]
1155 pub fn map_async_partitioned<Key, Next, Partition, F, Fut>(
1156 self,
1157 parallelism: usize,
1158 per_partition: usize,
1159 partition: Partition,
1160 f: F,
1161 ) -> Source<Next, Mat>
1162 where
1163 Key: Clone + Eq + Hash + Send + 'static,
1164 Next: Send + 'static,
1165 Partition: Fn(&Out) -> Key + Send + Sync + 'static,
1166 F: Fn(Out) -> Fut + Send + Sync + 'static,
1167 Fut: Future<Output = StreamResult<Next>> + Send + 'static,
1168 {
1169 self.via(Flow::identity().map_async_partitioned(parallelism, per_partition, partition, f))
1170 }
1171
1172 #[must_use]
1173 pub fn prefix_and_tail(self, n: usize) -> Source<(Vec<Out>, Source<Out>), Mat> {
1174 self.via(Flow::identity().prefix_and_tail(n))
1175 }
1176
1177 #[must_use]
1178 pub fn flat_map_prefix<Next, FlowMat, F>(self, n: usize, f: F) -> Source<Next, Mat>
1179 where
1180 Next: Send + 'static,
1181 FlowMat: Send + 'static,
1182 F: Fn(Vec<Out>) -> Flow<Out, Next, FlowMat> + Send + Sync + 'static,
1183 Out: Clone,
1184 {
1185 self.via(Flow::identity().flat_map_prefix(n, f))
1186 }
1187
1188 #[must_use]
1189 pub fn group_by<Key, F>(
1190 self,
1191 max_substreams: usize,
1192 f: F,
1193 allow_closed_substream_recreation: bool,
1194 ) -> Source<Source<Out>, Mat>
1195 where
1196 Key: Clone + Eq + Hash + Send + 'static,
1197 F: Fn(&Out) -> Key + Send + Sync + 'static,
1198 Out: Clone,
1199 {
1200 let batch_mode = if self.hints.inline_micro.is_some() && !allow_closed_substream_recreation
1201 {
1202 flow::GroupByBatchMode::FiniteEagerNoRecreate
1203 } else {
1204 flow::GroupByBatchMode::Immediate
1205 };
1206 self.via(Flow::identity().group_by_with_batching(
1207 max_substreams,
1208 f,
1209 allow_closed_substream_recreation,
1210 batch_mode,
1211 ))
1212 }
1213
1214 #[must_use]
1215 pub fn split_when<F>(self, predicate: F) -> Source<Source<Out>, Mat>
1216 where
1217 F: Fn(&Out) -> bool + Send + Sync + 'static,
1218 Out: Clone,
1219 {
1220 self.via(Flow::identity().split_when(predicate))
1221 }
1222
1223 #[must_use]
1224 pub fn split_after<F>(self, predicate: F) -> Source<Source<Out>, Mat>
1225 where
1226 F: Fn(&Out) -> bool + Send + Sync + 'static,
1227 Out: Clone,
1228 {
1229 self.via(Flow::identity().split_after(predicate))
1230 }
1231
1232 #[must_use]
1233 pub fn flat_map_concat<Next, NextMat, F>(self, f: F) -> Source<Next, Mat>
1234 where
1235 Next: Send + 'static,
1236 NextMat: Send + 'static,
1237 F: Fn(Out) -> Source<Next, NextMat> + Send + Sync + 'static,
1238 {
1239 self.via(Flow::identity().flat_map_concat(f))
1240 }
1241
1242 #[must_use]
1243 pub fn flat_map_merge<Next, NextMat, F>(self, breadth: usize, f: F) -> Source<Next, Mat>
1244 where
1245 Next: Send + 'static,
1246 NextMat: Send + 'static,
1247 F: Fn(Out) -> Source<Next, NextMat> + Send + Sync + 'static,
1248 {
1249 self.via(Flow::identity().flat_map_merge(breadth, f))
1250 }
1251
1252 #[must_use]
1253 pub fn take(self, n: usize) -> Source<Out, Mat> {
1254 self.via(Flow::identity().take(n))
1255 }
1256
1257 #[must_use]
1258 pub fn drop(self, n: usize) -> Source<Out, Mat> {
1259 self.via(Flow::identity().drop(n))
1260 }
1261
1262 #[must_use]
1263 pub fn take_while<F>(self, predicate: F) -> Source<Out, Mat>
1264 where
1265 F: Fn(&Out) -> bool + Send + Sync + 'static,
1266 {
1267 self.via(Flow::identity().take_while(predicate))
1268 }
1269
1270 #[must_use]
1271 pub fn drop_while<F>(self, predicate: F) -> Source<Out, Mat>
1272 where
1273 F: Fn(&Out) -> bool + Send + Sync + 'static,
1274 {
1275 self.via(Flow::identity().drop_while(predicate))
1276 }
1277
1278 #[must_use]
1279 pub fn limit(self, max: u64) -> Source<Out, Mat> {
1280 self.via(Flow::identity().limit(max))
1281 }
1282
1283 #[must_use]
1284 pub fn grouped(self, size: usize) -> Source<Vec<Out>, Mat> {
1285 self.via(Flow::identity().grouped(size))
1286 }
1287
1288 #[must_use]
1289 pub fn scan<State, F>(self, seed: State, f: F) -> Source<State, Mat>
1290 where
1291 State: Clone + Send + Sync + 'static,
1292 F: Fn(State, Out) -> State + Send + Sync + 'static,
1293 {
1294 self.via(Flow::identity().scan(seed, f))
1295 }
1296
1297 #[must_use]
1298 pub fn scan_async<State, F, Fut>(self, seed: State, f: F) -> Source<State, Mat>
1299 where
1300 State: Clone + Send + Sync + 'static,
1301 F: Fn(State, Out) -> Fut + Send + Sync + 'static,
1302 Fut: Future<Output = StreamResult<State>> + Send + 'static,
1303 {
1304 self.via(Flow::identity().scan_async(seed, f))
1305 }
1306
1307 #[must_use]
1308 pub fn try_scan<State, F>(self, seed: State, f: F) -> Source<State, Mat>
1309 where
1310 State: Clone + Send + Sync + 'static,
1311 F: Fn(State, Out) -> StreamResult<State> + Send + Sync + 'static,
1312 {
1313 self.via(Flow::identity().try_scan(seed, f))
1314 }
1315
1316 #[must_use]
1318 #[deprecated(
1319 since = "0.9.0",
1320 note = "renamed to `try_scan` (idiomatic); the `_result` name still works"
1321 )]
1322 pub fn scan_result<State, F>(self, seed: State, f: F) -> Source<State, Mat>
1323 where
1324 State: Clone + Send + Sync + 'static,
1325 F: Fn(State, Out) -> StreamResult<State> + Send + Sync + 'static,
1326 {
1327 self.try_scan(seed, f)
1328 }
1329
1330 #[must_use]
1331 pub fn scan_result_with_supervision<State, F>(
1332 self,
1333 seed: State,
1334 f: F,
1335 decider: SupervisionDecider,
1336 ) -> Source<State, Mat>
1337 where
1338 State: Clone + Send + Sync + 'static,
1339 F: Fn(State, Out) -> StreamResult<State> + Send + Sync + 'static,
1340 {
1341 self.via(Flow::identity().scan_result_with_supervision(seed, f, decider))
1342 }
1343
1344 #[must_use]
1345 pub fn sliding(self, size: usize, step: usize) -> Source<Vec<Out>, Mat>
1346 where
1347 Out: Clone,
1348 {
1349 self.via(Flow::identity().sliding(size, step))
1350 }
1351
1352 #[must_use]
1353 pub fn fold<Acc, F>(self, zero: Acc, f: F) -> Source<Acc, Mat>
1354 where
1355 Acc: Clone + Send + Sync + 'static,
1356 F: Fn(Acc, Out) -> Acc + Send + Sync + 'static,
1357 {
1358 self.via(Flow::identity().fold(zero, f))
1359 }
1360
1361 #[must_use]
1362 pub fn fold_async<Acc, F, Fut>(self, zero: Acc, f: F) -> Source<Acc, Mat>
1363 where
1364 Acc: Clone + Send + Sync + 'static,
1365 F: Fn(Acc, Out) -> Fut + Send + Sync + 'static,
1366 Fut: Future<Output = StreamResult<Acc>> + Send + 'static,
1367 {
1368 self.via(Flow::identity().fold_async(zero, f))
1369 }
1370
1371 #[must_use]
1372 pub fn map_with_resource<Resource, Next, Create, F, Close>(
1373 self,
1374 create: Create,
1375 f: F,
1376 close: Close,
1377 ) -> Source<Next, Mat>
1378 where
1379 Resource: Send + 'static,
1380 Next: Send + 'static,
1381 Create: Fn() -> StreamResult<Resource> + Send + Sync + 'static,
1382 F: Fn(&mut Resource, Out) -> StreamResult<Next> + Send + Sync + 'static,
1383 Close: Fn(Resource) -> StreamResult<Option<Next>> + Send + Sync + 'static,
1384 {
1385 self.via(Flow::identity().map_with_resource(create, f, close))
1386 }
1387
1388 #[must_use]
1389 pub fn try_fold<Acc, F>(self, zero: Acc, f: F) -> Source<Acc, Mat>
1390 where
1391 Acc: Clone + Send + Sync + 'static,
1392 F: Fn(Acc, Out) -> StreamResult<Acc> + Send + Sync + 'static,
1393 {
1394 self.via(Flow::identity().try_fold(zero, f))
1395 }
1396
1397 #[must_use]
1399 #[deprecated(
1400 since = "0.9.0",
1401 note = "renamed to `try_fold` (idiomatic); the `_result` name still works"
1402 )]
1403 pub fn fold_result<Acc, F>(self, zero: Acc, f: F) -> Source<Acc, Mat>
1404 where
1405 Acc: Clone + Send + Sync + 'static,
1406 F: Fn(Acc, Out) -> StreamResult<Acc> + Send + Sync + 'static,
1407 {
1408 self.try_fold(zero, f)
1409 }
1410
1411 #[must_use]
1412 pub fn fold_result_with_supervision<Acc, F>(
1413 self,
1414 zero: Acc,
1415 f: F,
1416 decider: SupervisionDecider,
1417 ) -> Source<Acc, Mat>
1418 where
1419 Acc: Clone + Send + Sync + 'static,
1420 F: Fn(Acc, Out) -> StreamResult<Acc> + Send + Sync + 'static,
1421 {
1422 self.via(Flow::identity().fold_result_with_supervision(zero, f, decider))
1423 }
1424
1425 #[must_use]
1426 pub fn reduce<F>(self, f: F) -> Source<Out, Mat>
1427 where
1428 F: Fn(Out, Out) -> Out + Send + Sync + 'static,
1429 {
1430 self.via(Flow::identity().reduce(f))
1431 }
1432
1433 #[must_use]
1434 pub fn try_reduce<F>(self, f: F) -> Source<Out, Mat>
1435 where
1436 Out: Clone,
1437 F: Fn(Out, Out) -> StreamResult<Out> + Send + Sync + 'static,
1438 {
1439 self.via(Flow::identity().try_reduce(f))
1440 }
1441
1442 #[must_use]
1444 #[deprecated(
1445 since = "0.9.0",
1446 note = "renamed to `try_reduce` (idiomatic); the `_result` name still works"
1447 )]
1448 pub fn reduce_result<F>(self, f: F) -> Source<Out, Mat>
1449 where
1450 Out: Clone,
1451 F: Fn(Out, Out) -> StreamResult<Out> + Send + Sync + 'static,
1452 {
1453 self.try_reduce(f)
1454 }
1455
1456 #[must_use]
1457 pub fn reduce_result_with_supervision<F>(
1458 self,
1459 f: F,
1460 decider: SupervisionDecider,
1461 ) -> Source<Out, Mat>
1462 where
1463 Out: Clone,
1464 F: Fn(Out, Out) -> StreamResult<Out> + Send + Sync + 'static,
1465 {
1466 self.via(Flow::identity().reduce_result_with_supervision(f, decider))
1467 }
1468
1469 #[must_use]
1470 pub fn map_error<F>(self, f: F) -> Source<Out, Mat>
1471 where
1472 F: Fn(StreamError) -> StreamError + Send + Sync + 'static,
1473 {
1474 self.via(Flow::identity().map_error(f))
1475 }
1476
1477 #[must_use]
1478 pub fn recover<F>(self, f: F) -> Source<Out, Mat>
1479 where
1480 F: Fn(StreamError) -> Option<Out> + Send + Sync + 'static,
1481 {
1482 self.via(Flow::identity().recover(f))
1483 }
1484
1485 #[must_use]
1486 pub fn recover_with<F>(self, f: F) -> Source<Out, Mat>
1487 where
1488 F: Fn(StreamError) -> Option<Source<Out>> + Send + Sync + 'static,
1489 {
1490 self.via(Flow::identity().recover_with(f))
1491 }
1492
1493 #[must_use]
1494 pub fn recover_with_retries<F>(self, retries: usize, f: F) -> Source<Out, Mat>
1495 where
1496 F: Fn(StreamError) -> Option<Source<Out>> + Send + Sync + 'static,
1497 {
1498 self.via(Flow::identity().recover_with_retries(retries, f))
1499 }
1500
1501 #[must_use]
1502 pub fn on_error_complete(self) -> Source<Out, Mat> {
1503 self.via(Flow::identity().on_error_complete())
1504 }
1505
1506 #[must_use]
1507 pub fn concat<Mat2>(self, that: Source<Out, Mat2>) -> Source<Out, Mat>
1508 where
1509 Mat2: Send + 'static,
1510 {
1511 let factory = self.factory;
1512 let hints = self.hints;
1513 let that_factory = that.factory;
1514 Source::from_materialized_factory_with_hints(
1515 move |materializer| {
1516 let (primary, mat) = Arc::clone(&factory).create(materializer)?;
1517 let secondary = match Arc::clone(&that_factory).create(materializer) {
1518 Ok((stream, _)) => stream,
1519 Err(error) => Box::new(std::iter::once(Err(error))) as BoxStream<Out>,
1520 };
1521 Ok((concat_source_streams(vec![primary, secondary]), mat))
1522 },
1523 hints,
1524 )
1525 }
1526
1527 #[must_use]
1528 pub fn concat_lazy<Mat2>(self, that: Source<Out, Mat2>) -> Source<Out, Mat>
1529 where
1530 Mat2: Send + 'static,
1531 {
1532 let factory = self.factory;
1533 let hints = self.hints;
1534 let that_factory = that.factory;
1535 Source::from_materialized_factory_with_hints(
1536 move |materializer| {
1537 let (primary, mat) = Arc::clone(&factory).create(materializer)?;
1538 Ok((
1539 concat_source_streams_lazy(
1540 primary,
1541 vec![Arc::clone(&that_factory)],
1542 materializer,
1543 ),
1544 mat,
1545 ))
1546 },
1547 hints,
1548 )
1549 }
1550
1551 #[must_use]
1552 pub fn concat_all_lazy<Mat2, I>(self, those: I) -> Source<Out, Mat>
1553 where
1554 Mat2: Send + 'static,
1555 I: IntoIterator<Item = Source<Out, Mat2>>,
1556 {
1557 let factory = self.factory;
1558 let hints = self.hints;
1559 let other_factories: Vec<_> = those.into_iter().map(|source| source.factory).collect();
1560 Source::from_materialized_factory_with_hints(
1561 move |materializer| {
1562 let (primary, mat) = Arc::clone(&factory).create(materializer)?;
1563 Ok((
1564 concat_source_streams_lazy(primary, other_factories.clone(), materializer),
1565 mat,
1566 ))
1567 },
1568 hints,
1569 )
1570 }
1571
1572 #[must_use]
1573 pub fn prepend<Mat2>(self, that: Source<Out, Mat2>) -> Source<Out, Mat>
1574 where
1575 Mat2: Send + 'static,
1576 {
1577 let factory = self.factory;
1578 let hints = self.hints;
1579 let that_factory = that.factory;
1580 Source::from_materialized_factory_with_hints(
1581 move |materializer| {
1582 let (primary, mat) = Arc::clone(&factory).create(materializer)?;
1583 let secondary = match Arc::clone(&that_factory).create(materializer) {
1584 Ok((stream, _)) => stream,
1585 Err(error) => Box::new(std::iter::once(Err(error))) as BoxStream<Out>,
1586 };
1587 Ok((concat_source_streams(vec![secondary, primary]), mat))
1588 },
1589 hints,
1590 )
1591 }
1592
1593 #[must_use]
1594 pub fn prepend_lazy<Mat2>(self, that: Source<Out, Mat2>) -> Source<Out, Mat>
1595 where
1596 Mat2: Send + 'static,
1597 {
1598 self.prepend(that)
1599 }
1600
1601 #[must_use]
1602 pub fn or_else<Mat2>(self, secondary: Source<Out, Mat2>) -> Source<Out, Mat>
1603 where
1604 Mat2: Send + 'static,
1605 {
1606 let factory = self.factory;
1607 let hints = self.hints;
1608 let secondary_factory = secondary.factory;
1609 Source::from_materialized_factory_with_hints(
1610 move |materializer| {
1611 let (primary, mat) = Arc::clone(&factory).create(materializer)?;
1612 let secondary = match Arc::clone(&secondary_factory).create(materializer) {
1613 Ok((stream, _)) => stream,
1614 Err(error) => Box::new(std::iter::once(Err(error))) as BoxStream<Out>,
1615 };
1616 Ok((or_else_source_stream(primary, secondary), mat))
1617 },
1618 hints,
1619 )
1620 }
1621
1622 #[must_use]
1623 pub fn interleave<Mat2>(self, that: Source<Out, Mat2>, segment_size: usize) -> Source<Out, Mat>
1624 where
1625 Mat2: Send + 'static,
1626 {
1627 self.interleave_all([that], segment_size, false)
1628 }
1629
1630 #[must_use]
1631 pub fn interleave_all<Mat2, I>(
1632 self,
1633 those: I,
1634 segment_size: usize,
1635 eager_close: bool,
1636 ) -> Source<Out, Mat>
1637 where
1638 Mat2: Send + 'static,
1639 I: IntoIterator<Item = Source<Out, Mat2>>,
1640 {
1641 let factory = self.factory;
1642 let hints = self.hints;
1643 let other_factories: Vec<_> = those.into_iter().map(|source| source.factory).collect();
1644 Source::from_materialized_factory_with_hints(
1645 move |materializer| {
1646 let (primary, mat) = Arc::clone(&factory).create(materializer)?;
1647 let mut streams = Vec::with_capacity(other_factories.len() + 1);
1648 streams.push(primary);
1649 for other in &other_factories {
1650 let stream = match Arc::clone(other).create(materializer) {
1651 Ok((stream, _)) => stream,
1652 Err(error) => Box::new(std::iter::once(Err(error))) as BoxStream<Out>,
1653 };
1654 streams.push(stream);
1655 }
1656 Ok((
1657 interleave_source_streams(streams, segment_size, eager_close),
1658 mat,
1659 ))
1660 },
1661 hints,
1662 )
1663 }
1664
1665 #[must_use]
1666 pub fn merge_sorted<Mat2>(self, that: Source<Out, Mat2>) -> Source<Out, Mat>
1667 where
1668 Out: Ord,
1669 Mat2: Send + 'static,
1670 {
1671 self.via(Flow::identity().merge_sorted(that))
1672 }
1673
1674 #[must_use]
1675 pub fn merge_latest<Mat2>(
1676 self,
1677 that: Source<Out, Mat2>,
1678 eager_complete: bool,
1679 ) -> Source<Vec<Out>, Mat>
1680 where
1681 Out: Clone,
1682 Mat2: Send + 'static,
1683 {
1684 let factory = self.factory;
1685 let hints = self.hints;
1686 let that_factory = that.factory;
1687 Source::from_materialized_factory_with_hints(
1688 move |materializer| {
1689 let (left, mat) = Arc::clone(&factory).create(materializer)?;
1690 let right = match Arc::clone(&that_factory).create(materializer) {
1691 Ok((stream, _)) => stream,
1692 Err(error) => {
1693 return Ok((
1694 Box::new(std::iter::once(Err(error))) as BoxStream<Vec<Out>>,
1695 mat,
1696 ));
1697 }
1698 };
1699 Ok((merge_latest_streams(vec![left, right], eager_complete), mat))
1700 },
1701 hints,
1702 )
1703 }
1704
1705 #[must_use]
1706 pub fn merge_all<Mat2, I>(self, those: I, eager_complete: bool) -> Source<Out, Mat>
1707 where
1708 Mat2: Send + 'static,
1709 I: IntoIterator<Item = Source<Out, Mat2>>,
1710 {
1711 let factory = self.factory;
1712 let hints = self.hints;
1713 let other_factories: Vec<_> = those.into_iter().map(|source| source.factory).collect();
1714 Source::from_materialized_factory_with_hints(
1715 move |materializer| {
1716 let (primary, mat) = Arc::clone(&factory).create(materializer)?;
1717 let mut streams = Vec::with_capacity(other_factories.len() + 1);
1718 streams.push(primary);
1719 for other in &other_factories {
1720 let stream = match Arc::clone(other).create(materializer) {
1721 Ok((stream, _)) => stream,
1722 Err(error) => {
1723 return Ok((
1724 Box::new(std::iter::once(Err(error))) as BoxStream<Out>,
1725 mat,
1726 ));
1727 }
1728 };
1729 streams.push(stream);
1730 }
1731 Ok((merge_streams(streams, eager_complete), mat))
1732 },
1733 hints,
1734 )
1735 }
1736
1737 #[must_use]
1738 pub fn zip_with<Mat2, Out2, Next, F>(
1739 self,
1740 that: Source<Out2, Mat2>,
1741 combine: F,
1742 ) -> Source<Next, Mat>
1743 where
1744 Out2: Send + 'static,
1745 Next: Send + 'static,
1746 Mat2: Send + 'static,
1747 F: Fn(Out, Out2) -> Next + Send + Sync + 'static,
1748 {
1749 self.via(Flow::identity().zip_with(that, combine))
1750 }
1751
1752 #[must_use]
1753 pub fn zip_latest<Mat2, Out2>(self, that: Source<Out2, Mat2>) -> Source<(Out, Out2), Mat>
1754 where
1755 Out: Clone,
1756 Out2: Clone + Send + 'static,
1757 Mat2: Send + 'static,
1758 {
1759 self.zip_latest_with(that, true, |left, right| (left, right))
1760 }
1761
1762 #[must_use]
1763 pub fn zip_latest_with<Mat2, Out2, Next, F>(
1764 self,
1765 that: Source<Out2, Mat2>,
1766 eager_complete: bool,
1767 combine: F,
1768 ) -> Source<Next, Mat>
1769 where
1770 Out: Clone,
1771 Out2: Clone + Send + 'static,
1772 Next: Send + 'static,
1773 Mat2: Send + 'static,
1774 F: Fn(Out, Out2) -> Next + Send + Sync + 'static,
1775 {
1776 let factory = self.factory;
1777 let hints = self.hints;
1778 let that_factory = that.factory;
1779 let combine = Arc::new(combine);
1780 Source::from_materialized_factory_with_hints(
1781 move |materializer| {
1782 let (left, mat) = Arc::clone(&factory).create(materializer)?;
1783 let right = match Arc::clone(&that_factory).create(materializer) {
1784 Ok((stream, _)) => stream,
1785 Err(error) => {
1786 return Ok((
1787 Box::new(std::iter::once(Err(error))) as BoxStream<Next>,
1788 mat,
1789 ));
1790 }
1791 };
1792 Ok((
1793 zip_latest_with_stream(left, right, eager_complete, Arc::clone(&combine)),
1794 mat,
1795 ))
1796 },
1797 hints,
1798 )
1799 }
1800
1801 #[must_use]
1802 pub fn zip_with_index(self) -> Source<(Out, u64), Mat> {
1803 let factory = self.factory;
1804 let hints = self.hints;
1805 Source::from_materialized_factory_with_hints(
1806 move |materializer| {
1807 let (mut stream, mat) = Arc::clone(&factory).create(materializer)?;
1808 let mut index = 0_u64;
1809 Ok((
1810 Box::new(std::iter::from_fn(move || {
1811 stream.next().map(|item| {
1812 item.map(|value| {
1813 let pair = (value, index);
1814 index = index.wrapping_add(1);
1815 pair
1816 })
1817 })
1818 })) as BoxStream<(Out, u64)>,
1819 mat,
1820 ))
1821 },
1822 hints,
1823 )
1824 }
1825
1826 #[must_use]
1827 pub fn zip_all<Mat2, Out2>(
1828 self,
1829 that: Source<Out2, Mat2>,
1830 this_elem: Out,
1831 that_elem: Out2,
1832 ) -> Source<(Out, Out2), Mat>
1833 where
1834 Out: Clone + Sync,
1835 Out2: Clone + Send + Sync + 'static,
1836 Mat2: Send + 'static,
1837 {
1838 let factory = self.factory;
1839 let hints = self.hints;
1840 let that_factory = that.factory;
1841 Source::from_materialized_factory_with_hints(
1842 move |materializer| {
1843 let (left, mat) = Arc::clone(&factory).create(materializer)?;
1844 let right = match Arc::clone(&that_factory).create(materializer) {
1845 Ok((stream, _)) => stream,
1846 Err(error) => {
1847 return Ok((
1848 Box::new(std::iter::once(Err(error))) as BoxStream<(Out, Out2)>,
1849 mat,
1850 ));
1851 }
1852 };
1853 Ok((
1854 zip_all_stream(left, right, this_elem.clone(), that_elem.clone()),
1855 mat,
1856 ))
1857 },
1858 hints,
1859 )
1860 }
1861
1862 #[must_use]
1863 pub fn also_to<SinkMat>(self, sink: Sink<Out, SinkMat>) -> Source<Out, Mat>
1864 where
1865 Out: Clone,
1866 SinkMat: Send + 'static,
1867 {
1868 self.via(Flow::identity().also_to(sink))
1869 }
1870
1871 #[must_use]
1872 pub fn also_to_all<SinkMat, I>(self, sinks: I) -> Source<Out, Mat>
1873 where
1874 Out: Clone,
1875 SinkMat: Send + 'static,
1876 I: IntoIterator<Item = Sink<Out, SinkMat>>,
1877 {
1878 self.via(Flow::identity().also_to_all(sinks))
1879 }
1880
1881 #[must_use]
1882 pub fn divert_to<SinkMat, F>(self, sink: Sink<Out, SinkMat>, predicate: F) -> Source<Out, Mat>
1883 where
1884 SinkMat: Send + 'static,
1885 F: Fn(&Out) -> bool + Send + Sync + 'static,
1886 {
1887 self.via(Flow::identity().divert_to(sink, predicate))
1888 }
1889
1890 #[must_use]
1891 pub fn wire_tap<SinkMat>(self, sink: Sink<Out, SinkMat>) -> Source<Out, Mat>
1892 where
1893 Out: Clone,
1894 SinkMat: Send + 'static,
1895 {
1896 self.via(Flow::identity().wire_tap(sink))
1897 }
1898
1899 pub fn run_with<SinkMat: Send + 'static>(
1900 self,
1901 sink: Sink<Out, SinkMat>,
1902 ) -> StreamResult<SinkMat> {
1903 let fast_result = self
1906 .split_hook
1907 .as_ref()
1908 .zip(sink.fold_fp.as_deref())
1909 .and_then(|(hook, fp)| fp.try_register(Arc::clone(hook)));
1910 if let Some(result) = fast_result {
1911 return result?.downcast::<SinkMat>().map(|b| *b).map_err(|_| {
1912 StreamError::Failed("split fast path: unexpected mat type (internal error)".into())
1913 });
1914 }
1915 self.to_mat(sink, Keep::right).run()
1916 }
1917
1918 pub fn run_with_materializer<SinkMat: Send + 'static>(
1919 self,
1920 sink: Sink<Out, SinkMat>,
1921 materializer: &Materializer,
1922 ) -> StreamResult<SinkMat> {
1923 self.to_mat(sink, Keep::right)
1924 .run_with_materializer(materializer)
1925 }
1926
1927 #[must_use]
1928 pub fn to<SinkMat>(self, sink: Sink<Out, SinkMat>) -> RunnableGraph<Mat>
1929 where
1930 SinkMat: Send + 'static,
1931 {
1932 self.to_mat(sink, Keep::left)
1933 }
1934
1935 #[must_use]
1936 pub fn to_mat<SinkMat, Combined, F>(
1937 self,
1938 sink: Sink<Out, SinkMat>,
1939 combine: F,
1940 ) -> RunnableGraph<Combined>
1941 where
1942 SinkMat: Send + 'static,
1943 Combined: Send + 'static,
1944 F: Fn(Mat, SinkMat) -> Combined + Send + Sync + 'static,
1945 {
1946 let factory = self.factory;
1947 let terminal_factory = self.terminal_factory;
1948 let hints = self.hints;
1949 let combine = Arc::new(combine);
1950 RunnableGraph::from_runner(move |materializer| {
1951 if let Some(terminal_factory) = &terminal_factory
1952 && let Some(fold_fp) = sink.fold_fp.as_deref()
1953 {
1954 let (hook, source_mat) = terminal_factory(materializer)?;
1955 if hook.supports_direct_terminal()
1956 && let Some(sink_mat) =
1957 fold_fp.try_register_direct_terminal(Arc::clone(&hook), materializer)
1958 {
1959 let sink_mat = sink_mat.and_then(|mat| {
1960 mat.downcast::<SinkMat>().map(|boxed| *boxed).map_err(|_| {
1961 StreamError::Failed(
1962 "terminal fast path: unexpected mat type (internal error)".into(),
1963 )
1964 })
1965 })?;
1966 return Ok(combine(source_mat, sink_mat));
1967 }
1968 if !fold_fp.supports_terminal_drain() {
1969 let (stream, source_mat) = Arc::clone(&factory).create(materializer)?;
1970 let sink_mat = sink.run_from_source(stream, materializer, hints.runtime())?;
1971 return Ok(combine(source_mat, sink_mat));
1972 }
1973 let sink_mat = fold_fp
1974 .try_register_terminal_drain(hook, materializer)
1975 .expect("terminal drain support advertised")
1976 .and_then(|mat| {
1977 mat.downcast::<SinkMat>().map(|boxed| *boxed).map_err(|_| {
1978 StreamError::Failed(
1979 "terminal fast path: unexpected mat type (internal error)".into(),
1980 )
1981 })
1982 })?;
1983 return Ok(combine(source_mat, sink_mat));
1984 }
1985 let (stream, source_mat) = Arc::clone(&factory).create(materializer)?;
1986 let sink_mat = if hints.inline_head_terminal && sink.can_inline() {
1987 let stream =
1988 runtime_checked_stream(stream, Arc::clone(&materializer.inner.state), None);
1989 sink.run_inline(stream, materializer)?
1990 } else {
1991 sink.run_from_source(stream, materializer, hints.runtime())?
1992 };
1993 Ok(combine(source_mat, sink_mat))
1994 })
1995 }
1996
1997 pub fn run_collect(self) -> StreamResult<Vec<Out>> {
1998 self.run_with(Sink::collect())?.wait()
1999 }
2000
2001 pub fn run_fold<Acc, F>(self, zero: Acc, f: F) -> StreamResult<StreamCompletion<Acc>>
2002 where
2003 Acc: Clone + Send + Sync + 'static,
2004 F: Fn(Acc, Out) -> Acc + Send + Sync + 'static,
2005 {
2006 self.run_with(Sink::fold(zero, f))
2007 }
2008
2009 pub fn run_foreach<F>(self, f: F) -> StreamResult<StreamCompletion<NotUsed>>
2010 where
2011 F: Fn(Out) + Send + Sync + 'static,
2012 {
2013 self.run_with(Sink::foreach(f))
2014 }
2015
2016 pub fn run_for_each<F>(self, f: F) -> StreamResult<StreamCompletion<NotUsed>>
2017 where
2018 F: Fn(Out) + Send + Sync + 'static,
2019 {
2020 self.run_with(Sink::foreach(f))
2021 }
2022
2023 pub fn run_reduce<F>(self, f: F) -> StreamResult<StreamCompletion<Out>>
2024 where
2025 F: Fn(Out, Out) -> Out + Send + Sync + 'static,
2026 {
2027 self.run_with(Sink::reduce(f))
2028 }
2029
2030 #[must_use]
2031 pub fn map_materialized_value<NextMat, F>(self, f: F) -> Source<Out, NextMat>
2032 where
2033 NextMat: Send + 'static,
2034 F: Fn(Mat) -> NextMat + Send + Sync + 'static,
2035 {
2036 let factory = self.factory;
2037 let terminal_factory = self.terminal_factory;
2038 let hints = self.hints;
2039 let f = Arc::new(f);
2040 let factory_f = Arc::clone(&f);
2041 let mapped_terminal_factory = terminal_factory.map(|terminal_factory| {
2042 let f = Arc::clone(&f);
2043 Arc::new(move |materializer: &Materializer| {
2044 let (hook, mat) = terminal_factory(materializer)?;
2045 Ok((hook, f(mat)))
2046 }) as Arc<TerminalSourceFactory<Out, NextMat>>
2047 });
2048 Source {
2049 factory: Arc::new(FnSourceFactory(move |materializer: &Materializer| {
2050 let (stream, mat) = Arc::clone(&factory).create(materializer)?;
2051 Ok((stream, factory_f(mat)))
2052 })),
2053 terminal_factory: mapped_terminal_factory,
2054 hints,
2055 attributes: Attributes::default(),
2056 split_hook: None,
2057 }
2058 }
2059}
2060
2061impl<Out: Clone + Send + Sync + 'static> Source<Out, NotUsed> {
2062 #[must_use]
2063 pub fn combine<Mat1, Mat2, MatRest, I>(
2064 first: Source<Out, Mat1>,
2065 second: Source<Out, Mat2>,
2066 rest: I,
2067 strategy: SourceCombineStrategy,
2068 ) -> Source<Out, NotUsed>
2069 where
2070 Mat1: Send + 'static,
2071 Mat2: Send + 'static,
2072 MatRest: Send + 'static,
2073 I: IntoIterator<Item = Source<Out, MatRest>>,
2074 {
2075 let mut factories: Vec<Arc<CombinedSourceFactory<Out>>> = vec![
2076 Arc::new(move |materializer| {
2077 Arc::clone(&first.factory)
2078 .create(materializer)
2079 .map(|(stream, _)| stream)
2080 }),
2081 Arc::new(move |materializer| {
2082 Arc::clone(&second.factory)
2083 .create(materializer)
2084 .map(|(stream, _)| stream)
2085 }),
2086 ];
2087 factories.extend(rest.into_iter().map(|source| {
2088 Arc::new(move |materializer: &Materializer| {
2089 Arc::clone(&source.factory)
2090 .create(materializer)
2091 .map(|(stream, _)| stream)
2092 }) as Arc<CombinedSourceFactory<Out>>
2093 }));
2094 Source::from_materialized_factory(move |materializer| {
2095 let mut streams = Vec::with_capacity(factories.len());
2096 for factory in &factories {
2097 let stream = match factory(materializer) {
2098 Ok(stream) => stream,
2099 Err(error) => {
2100 return Ok((
2101 Box::new(std::iter::once(Err(error))) as BoxStream<Out>,
2102 NotUsed,
2103 ));
2104 }
2105 };
2106 streams.push(stream);
2107 }
2108 let stream = match &strategy {
2109 SourceCombineStrategy::Merge { eager_complete } => {
2110 merge_streams(streams, *eager_complete)
2111 }
2112 SourceCombineStrategy::Concat => concat_source_streams(streams),
2113 SourceCombineStrategy::Prioritized {
2114 priorities,
2115 eager_complete,
2116 } => {
2117 if priorities.len() != streams.len() {
2118 return Err(StreamError::GraphValidation(format!(
2119 "combine priorities length {} did not match source count {}",
2120 priorities.len(),
2121 streams.len()
2122 )));
2123 }
2124 merge_prioritized_streams(streams, priorities.clone(), *eager_complete)
2125 }
2126 };
2127 Ok((stream, NotUsed))
2128 })
2129 }
2130
2131 #[must_use]
2132 pub fn zip_n<Mat2, I>(sources: I) -> Source<Vec<Out>, NotUsed>
2133 where
2134 I: IntoIterator<Item = Source<Out, Mat2>>,
2135 Mat2: Send + 'static,
2136 Out: Clone,
2137 {
2138 Self::zip_with_n(sources, |values| values)
2139 }
2140
2141 #[must_use]
2142 pub fn zip_with_n<Mat2, I, Next, F>(sources: I, zipper: F) -> Source<Next, NotUsed>
2143 where
2144 I: IntoIterator<Item = Source<Out, Mat2>>,
2145 Mat2: Send + 'static,
2146 Next: Send + 'static,
2147 F: Fn(Vec<Out>) -> Next + Send + Sync + 'static,
2148 {
2149 let factories: Vec<_> = sources.into_iter().map(|source| source.factory).collect();
2150 let zipper = Arc::new(zipper);
2151 Source::from_materialized_factory(move |materializer| {
2152 let mut streams = Vec::with_capacity(factories.len());
2153 for factory in &factories {
2154 let stream = match Arc::clone(factory).create(materializer) {
2155 Ok((stream, _)) => stream,
2156 Err(error) => {
2157 return Ok((
2158 Box::new(std::iter::once(Err(error))) as BoxStream<Next>,
2159 NotUsed,
2160 ));
2161 }
2162 };
2163 streams.push(stream);
2164 }
2165 Ok((zip_n_streams(streams, Arc::clone(&zipper)), NotUsed))
2166 })
2167 }
2168
2169 #[must_use]
2170 pub fn merge_prioritized_n<Mat2, I>(
2171 sources_and_priorities: I,
2172 eager_complete: bool,
2173 ) -> Source<Out, NotUsed>
2174 where
2175 I: IntoIterator<Item = (Source<Out, Mat2>, usize)>,
2176 Mat2: Send + 'static,
2177 {
2178 let sources_and_priorities: Vec<_> = sources_and_priorities.into_iter().collect();
2179 if sources_and_priorities.is_empty() {
2180 return Source::empty();
2181 }
2182 let (factories, priorities): (Vec<_>, Vec<_>) = sources_and_priorities
2183 .into_iter()
2184 .map(|(source, priority)| (source.factory, priority))
2185 .unzip();
2186 Source::from_materialized_factory(move |materializer| {
2187 let mut streams = Vec::with_capacity(factories.len());
2188 for factory in &factories {
2189 let stream = match Arc::clone(factory).create(materializer) {
2190 Ok((stream, _)) => stream,
2191 Err(error) => {
2192 return Ok((
2193 Box::new(std::iter::once(Err(error))) as BoxStream<Out>,
2194 NotUsed,
2195 ));
2196 }
2197 };
2198 streams.push(stream);
2199 }
2200 Ok((
2201 merge_prioritized_streams(streams, priorities.clone(), eager_complete),
2202 NotUsed,
2203 ))
2204 })
2205 }
2206
2207 #[must_use]
2208 pub fn maybe() -> (MaybeHandle<Out>, Self) {
2209 let value = Arc::new(Mutex::new(None));
2210 let handle = MaybeHandle {
2211 value: Arc::clone(&value),
2212 };
2213 let source = Self::from_factory(move || {
2214 let result = value
2215 .lock()
2216 .expect("maybe source poisoned")
2217 .clone()
2218 .unwrap_or(Err(StreamError::MaybeIncomplete));
2219 Box::new(std::iter::once(result))
2220 });
2221 (handle, source)
2222 }
2223
2224 #[must_use]
2225 pub fn single(item: Out) -> Self {
2226 Self::from_factory_with_hints(
2227 move || Box::new(std::iter::once(Ok(item.clone()))),
2228 SourceHints::with_inline_micro(1),
2229 )
2230 }
2231
2232 #[must_use]
2233 pub fn repeat(item: Out) -> Self {
2234 Self::from_factory(move || {
2235 let item = item.clone();
2236 Box::new(std::iter::repeat_with(move || Ok(item.clone())))
2237 })
2238 }
2239
2240 #[must_use]
2241 pub fn from_iterable<I>(items: I) -> Self
2242 where
2243 I: IntoIterator<Item = Out>,
2244 {
2245 items.into_iter().collect()
2246 }
2247}
2248
2249impl<Out: Clone + Send + Sync + 'static> FromIterator<Out> for Source<Out, NotUsed> {
2250 fn from_iter<T: IntoIterator<Item = Out>>(iter: T) -> Self {
2251 let items: Arc<[Out]> = iter.into_iter().collect();
2254 let len = items.len();
2255 Self::from_factory_with_hints(
2256 move || {
2257 let items = Arc::clone(&items);
2258 let mut index = 0;
2259 Box::new(std::iter::from_fn(move || {
2260 let item = items.get(index)?.clone();
2261 index += 1;
2262 Some(Ok(item))
2263 }))
2264 },
2265 SourceHints::with_inline_micro(len),
2267 )
2268 }
2269}
2270
2271impl<Out: Clone + Send + Sync + 'static> From<Vec<Out>> for Source<Out, NotUsed> {
2272 fn from(items: Vec<Out>) -> Self {
2273 Source::from_iter(items)
2274 }
2275}
2276
2277impl<Out: Clone + Send + Sync + 'static, const N: usize> From<[Out; N]> for Source<Out, NotUsed> {
2278 fn from(items: [Out; N]) -> Self {
2279 Source::from_iter(items)
2280 }
2281}
2282
2283pub trait IntoSource: IntoIterator + Sized {
2313 #[must_use]
2314 fn into_source(self) -> Source<Self::Item, NotUsed>
2315 where
2316 Self::Item: Clone + Send + Sync + 'static,
2317 {
2318 Source::from_iter(self)
2319 }
2320}
2321
2322impl<I> IntoSource for I where I: IntoIterator {}
2323
2324#[cfg(test)]
2329pub(in crate::stream) fn test_source_with_inline_micro_hint<Out: Send + 'static>(
2330 factory: impl Fn() -> BoxStream<Out> + Send + Sync + 'static,
2331 max_success_items: usize,
2332) -> Source<Out, NotUsed> {
2333 Source::from_factory_with_hints(factory, SourceHints::with_inline_micro(max_success_items))
2334}
2335
2336struct UnfoldResourceStream<Resource, Out, Create, Read, Close>
2337where
2338 Create: Fn() -> StreamResult<Resource>,
2339 Read: Fn(&mut Resource) -> StreamResult<Option<Out>>,
2340 Close: Fn(Resource) -> StreamResult<()>,
2341{
2342 create: Arc<Create>,
2343 read: Arc<Read>,
2344 close: Arc<Close>,
2345 resource: Option<Resource>,
2346 created: bool,
2347 terminated: bool,
2348 _marker: PhantomData<fn() -> Out>,
2349}
2350
2351impl<Resource, Out, Create, Read, Close> UnfoldResourceStream<Resource, Out, Create, Read, Close>
2352where
2353 Create: Fn() -> StreamResult<Resource>,
2354 Read: Fn(&mut Resource) -> StreamResult<Option<Out>>,
2355 Close: Fn(Resource) -> StreamResult<()>,
2356{
2357 fn ensure_created(&mut self) -> StreamResult<()> {
2358 if self.created {
2359 return Ok(());
2360 }
2361 self.created = true;
2362 let resource = catch_unwind_failed("unfold_resource create", || (self.create)())
2363 .and_then(|result| result)?;
2364 self.resource = Some(resource);
2365 Ok(())
2366 }
2367
2368 fn close_resource(&mut self) -> StreamResult<()> {
2369 match self.resource.take() {
2370 Some(resource) => {
2371 catch_unwind_failed("unfold_resource close", || (self.close)(resource))
2372 .and_then(|result| result)
2373 }
2374 None => Ok(()),
2375 }
2376 }
2377}
2378
2379impl<Resource, Out, Create, Read, Close> Iterator
2380 for UnfoldResourceStream<Resource, Out, Create, Read, Close>
2381where
2382 Create: Fn() -> StreamResult<Resource>,
2383 Read: Fn(&mut Resource) -> StreamResult<Option<Out>>,
2384 Close: Fn(Resource) -> StreamResult<()>,
2385{
2386 type Item = StreamResult<Out>;
2387
2388 fn next(&mut self) -> Option<Self::Item> {
2389 if self.terminated {
2390 return None;
2391 }
2392 if let Err(error) = self.ensure_created() {
2393 self.terminated = true;
2394 return Some(Err(error));
2395 }
2396
2397 let result = {
2398 let resource = self
2399 .resource
2400 .as_mut()
2401 .expect("unfold_resource resource is open");
2402 catch_unwind_failed("unfold_resource read", || (self.read)(resource))
2403 .and_then(|result| result)
2404 };
2405
2406 match result {
2407 Ok(Some(item)) => Some(Ok(item)),
2408 Ok(None) => {
2409 self.terminated = true;
2410 match self.close_resource() {
2411 Ok(()) => None,
2412 Err(error) => Some(Err(error)),
2413 }
2414 }
2415 Err(read_error) => {
2416 self.terminated = true;
2417 let _ = self.close_resource();
2418 Some(Err(read_error))
2419 }
2420 }
2421 }
2422}
2423
2424impl<Resource, Out, Create, Read, Close> Drop
2425 for UnfoldResourceStream<Resource, Out, Create, Read, Close>
2426where
2427 Create: Fn() -> StreamResult<Resource>,
2428 Read: Fn(&mut Resource) -> StreamResult<Option<Out>>,
2429 Close: Fn(Resource) -> StreamResult<()>,
2430{
2431 fn drop(&mut self) {
2432 let _ = self.close_resource();
2433 }
2434}
2435
2436type UnfoldResourceAsyncMarker<Out, CreateFut, ReadFut, CloseFut> =
2437 fn() -> (Out, CreateFut, ReadFut, CloseFut);
2438
2439struct UnfoldResourceAsyncStream<Resource, Out, Create, CreateFut, Read, ReadFut, Close, CloseFut>
2440where
2441 Resource: Send + 'static,
2442 Create: Fn() -> CreateFut,
2443 CreateFut: Future<Output = StreamResult<Resource>> + Send + 'static,
2444 Read: Fn(&mut Resource) -> ReadFut,
2445 ReadFut: Future<Output = StreamResult<Option<Out>>> + Send + 'static,
2446 Close: Fn(Resource) -> CloseFut,
2447 CloseFut: Future<Output = StreamResult<()>> + Send + 'static,
2448{
2449 create: Arc<Create>,
2450 read: Arc<Read>,
2451 close: Arc<Close>,
2452 resource: Option<Resource>,
2453 created: bool,
2454 terminated: bool,
2455 _marker: PhantomData<UnfoldResourceAsyncMarker<Out, CreateFut, ReadFut, CloseFut>>,
2456}
2457
2458impl<Resource, Out, Create, CreateFut, Read, ReadFut, Close, CloseFut>
2459 UnfoldResourceAsyncStream<Resource, Out, Create, CreateFut, Read, ReadFut, Close, CloseFut>
2460where
2461 Resource: Send + 'static,
2462 Create: Fn() -> CreateFut,
2463 CreateFut: Future<Output = StreamResult<Resource>> + Send + 'static,
2464 Read: Fn(&mut Resource) -> ReadFut,
2465 ReadFut: Future<Output = StreamResult<Option<Out>>> + Send + 'static,
2466 Close: Fn(Resource) -> CloseFut,
2467 CloseFut: Future<Output = StreamResult<()>> + Send + 'static,
2468{
2469 fn ensure_created(&mut self) -> StreamResult<()> {
2470 if self.created {
2471 return Ok(());
2472 }
2473 self.created = true;
2474 let resource = catch_unwind_failed("unfold_resource_async create", || (self.create)())
2475 .and_then(flow::run_future_inline_or_spawn)?;
2476 self.resource = Some(resource);
2477 Ok(())
2478 }
2479
2480 fn close_resource(&mut self) -> StreamResult<()> {
2481 match self.resource.take() {
2482 Some(resource) => {
2483 catch_unwind_failed("unfold_resource_async close", || (self.close)(resource))
2484 .and_then(flow::run_future_inline_or_spawn)
2485 }
2486 None => Ok(()),
2487 }
2488 }
2489}
2490
2491impl<Resource, Out, Create, CreateFut, Read, ReadFut, Close, CloseFut> Iterator
2492 for UnfoldResourceAsyncStream<Resource, Out, Create, CreateFut, Read, ReadFut, Close, CloseFut>
2493where
2494 Resource: Send + 'static,
2495 Out: Send + 'static,
2496 Create: Fn() -> CreateFut,
2497 CreateFut: Future<Output = StreamResult<Resource>> + Send + 'static,
2498 Read: Fn(&mut Resource) -> ReadFut,
2499 ReadFut: Future<Output = StreamResult<Option<Out>>> + Send + 'static,
2500 Close: Fn(Resource) -> CloseFut,
2501 CloseFut: Future<Output = StreamResult<()>> + Send + 'static,
2502{
2503 type Item = StreamResult<Out>;
2504
2505 fn next(&mut self) -> Option<Self::Item> {
2506 if self.terminated {
2507 return None;
2508 }
2509 if let Err(error) = self.ensure_created() {
2510 self.terminated = true;
2511 return Some(Err(error));
2512 }
2513
2514 let result = {
2515 let resource = self
2516 .resource
2517 .as_mut()
2518 .expect("unfold_resource_async resource is open");
2519 catch_unwind_failed("unfold_resource_async read", || (self.read)(resource))
2520 .and_then(flow::run_future_inline_or_spawn)
2521 };
2522
2523 match result {
2524 Ok(Some(item)) => Some(Ok(item)),
2525 Ok(None) => {
2526 self.terminated = true;
2527 match self.close_resource() {
2528 Ok(()) => None,
2529 Err(error) => Some(Err(error)),
2530 }
2531 }
2532 Err(read_error) => {
2533 self.terminated = true;
2534 let _ = self.close_resource();
2535 Some(Err(read_error))
2536 }
2537 }
2538 }
2539}
2540
2541impl<Resource, Out, Create, CreateFut, Read, ReadFut, Close, CloseFut> Drop
2542 for UnfoldResourceAsyncStream<Resource, Out, Create, CreateFut, Read, ReadFut, Close, CloseFut>
2543where
2544 Resource: Send + 'static,
2545 Create: Fn() -> CreateFut,
2546 CreateFut: Future<Output = StreamResult<Resource>> + Send + 'static,
2547 Read: Fn(&mut Resource) -> ReadFut,
2548 ReadFut: Future<Output = StreamResult<Option<Out>>> + Send + 'static,
2549 Close: Fn(Resource) -> CloseFut,
2550 CloseFut: Future<Output = StreamResult<()>> + Send + 'static,
2551{
2552 fn drop(&mut self) {
2553 let _ = self.close_resource();
2554 }
2555}
2556
2557struct LazySourceStream<Out, InnerMat, F> {
2558 create: Arc<F>,
2559 materializer: Materializer,
2560 current: Option<BoxStream<Out>>,
2561 mat_sender: Option<oneshot::Sender<StreamResult<InnerMat>>>,
2562 initialized: bool,
2563 terminated: bool,
2564}
2565
2566impl<Out, InnerMat, F> LazySourceStream<Out, InnerMat, F>
2567where
2568 Out: Send + 'static,
2569 InnerMat: Send + 'static,
2570 F: Fn() -> Source<Out, InnerMat>,
2571{
2572 fn complete_mat(&mut self, result: StreamResult<InnerMat>) {
2573 if let Some(sender) = self.mat_sender.take() {
2574 let _ = sender.send(result);
2575 }
2576 }
2577
2578 fn initialize(&mut self) -> StreamResult<()> {
2579 if self.initialized {
2580 return Ok(());
2581 }
2582 self.initialized = true;
2583 let source = match catch_unwind_failed("lazy_source factory", || (self.create)()) {
2584 Ok(source) => source,
2585 Err(error) => {
2586 self.complete_mat(Err(error.clone()));
2587 return Err(error);
2588 }
2589 };
2590 match Arc::clone(&source.factory).create(&self.materializer) {
2591 Ok((stream, mat)) => {
2592 self.current = Some(stream);
2593 self.complete_mat(Ok(mat));
2594 Ok(())
2595 }
2596 Err(error) => {
2597 self.complete_mat(Err(error.clone()));
2598 Err(error)
2599 }
2600 }
2601 }
2602}
2603
2604impl<Out, InnerMat, F> Iterator for LazySourceStream<Out, InnerMat, F>
2605where
2606 Out: Send + 'static,
2607 InnerMat: Send + 'static,
2608 F: Fn() -> Source<Out, InnerMat>,
2609{
2610 type Item = StreamResult<Out>;
2611
2612 fn next(&mut self) -> Option<Self::Item> {
2613 if self.terminated {
2614 return None;
2615 }
2616 if let Err(error) = self.initialize() {
2617 self.terminated = true;
2618 return Some(Err(error));
2619 }
2620 match self
2621 .current
2622 .as_mut()
2623 .expect("lazy_source current stream initialized")
2624 .next()
2625 {
2626 Some(Ok(item)) => Some(Ok(item)),
2627 Some(Err(error)) => {
2628 self.terminated = true;
2629 Some(Err(error))
2630 }
2631 None => {
2632 self.terminated = true;
2633 None
2634 }
2635 }
2636 }
2637}
2638
2639impl<Out, InnerMat, F> Drop for LazySourceStream<Out, InnerMat, F> {
2640 fn drop(&mut self) {
2641 if !self.initialized
2642 && let Some(sender) = self.mat_sender.take()
2643 {
2644 let _ = sender.send(Err(StreamError::Failed(
2645 "lazy source was never materialized".into(),
2646 )));
2647 }
2648 }
2649}
2650
2651struct LazyFutureSourceStream<Out, InnerMat, F, Fut> {
2652 create: Arc<F>,
2653 materializer: Materializer,
2654 current: Option<BoxStream<Out>>,
2655 mat_sender: Option<oneshot::Sender<StreamResult<InnerMat>>>,
2656 initialized: bool,
2657 terminated: bool,
2658 _marker: PhantomData<fn() -> Fut>,
2659}
2660
2661impl<Out, InnerMat, F, Fut> LazyFutureSourceStream<Out, InnerMat, F, Fut>
2662where
2663 Out: Send + 'static,
2664 InnerMat: Send + 'static,
2665 F: Fn() -> Fut,
2666 Fut: Future<Output = StreamResult<Source<Out, InnerMat>>> + Send + 'static,
2667{
2668 fn complete_mat(&mut self, result: StreamResult<InnerMat>) {
2669 if let Some(sender) = self.mat_sender.take() {
2670 let _ = sender.send(result);
2671 }
2672 }
2673
2674 fn initialize(&mut self) -> StreamResult<()> {
2675 if self.initialized {
2676 return Ok(());
2677 }
2678 self.initialized = true;
2679 let source = match catch_unwind_failed("lazy_future_source factory", || (self.create)())
2680 .and_then(flow::run_future_inline_or_spawn)
2681 {
2682 Ok(source) => source,
2683 Err(error) => {
2684 self.complete_mat(Err(error.clone()));
2685 return Err(error);
2686 }
2687 };
2688 match Arc::clone(&source.factory).create(&self.materializer) {
2689 Ok((stream, mat)) => {
2690 self.current = Some(stream);
2691 self.complete_mat(Ok(mat));
2692 Ok(())
2693 }
2694 Err(error) => {
2695 self.complete_mat(Err(error.clone()));
2696 Err(error)
2697 }
2698 }
2699 }
2700}
2701
2702impl<Out, InnerMat, F, Fut> Iterator for LazyFutureSourceStream<Out, InnerMat, F, Fut>
2703where
2704 Out: Send + 'static,
2705 InnerMat: Send + 'static,
2706 F: Fn() -> Fut,
2707 Fut: Future<Output = StreamResult<Source<Out, InnerMat>>> + Send + 'static,
2708{
2709 type Item = StreamResult<Out>;
2710
2711 fn next(&mut self) -> Option<Self::Item> {
2712 if self.terminated {
2713 return None;
2714 }
2715 if let Err(error) = self.initialize() {
2716 self.terminated = true;
2717 return Some(Err(error));
2718 }
2719 match self
2720 .current
2721 .as_mut()
2722 .expect("lazy_future_source current stream initialized")
2723 .next()
2724 {
2725 Some(Ok(item)) => Some(Ok(item)),
2726 Some(Err(error)) => {
2727 self.terminated = true;
2728 Some(Err(error))
2729 }
2730 None => {
2731 self.terminated = true;
2732 None
2733 }
2734 }
2735 }
2736}
2737
2738impl<Out, InnerMat, F, Fut> Drop for LazyFutureSourceStream<Out, InnerMat, F, Fut> {
2739 fn drop(&mut self) {
2740 if !self.initialized
2741 && let Some(sender) = self.mat_sender.take()
2742 {
2743 let _ = sender.send(Err(StreamError::Failed(
2744 "lazy future source was never materialized".into(),
2745 )));
2746 }
2747 }
2748}
2749
2750fn concat_source_streams<Out>(streams: Vec<BoxStream<Out>>) -> BoxStream<Out>
2751where
2752 Out: Send + 'static,
2753{
2754 let mut streams: VecDeque<_> = streams.into();
2755 let mut current = streams.pop_front();
2756 Box::new(std::iter::from_fn(move || {
2757 loop {
2758 match current.as_mut() {
2759 Some(stream) => match stream.next() {
2760 Some(item) => return Some(item),
2761 None => current = streams.pop_front(),
2762 },
2763 None => return None,
2764 }
2765 }
2766 }))
2767}
2768
2769fn concat_source_streams_lazy<Out, Mat>(
2770 initial: BoxStream<Out>,
2771 factories: Vec<Arc<dyn SourceFactory<Out, Mat>>>,
2772 materializer: &Materializer,
2773) -> BoxStream<Out>
2774where
2775 Out: Send + 'static,
2776 Mat: Send + 'static,
2777{
2778 let mut current = Some(initial);
2779 let mut remaining: VecDeque<_> = factories.into();
2780 let materializer = materializer.with_name_prefix(materializer.name_prefix().to_owned());
2781 Box::new(std::iter::from_fn(move || {
2782 loop {
2783 match current.as_mut() {
2784 Some(stream) => match stream.next() {
2785 Some(item) => return Some(item),
2786 None => {
2787 current = remaining.pop_front().map(|factory| {
2788 match factory.create(&materializer) {
2789 Ok((stream, _)) => stream,
2790 Err(error) => {
2791 Box::new(std::iter::once(Err(error))) as BoxStream<Out>
2792 }
2793 }
2794 });
2795 }
2796 },
2797 None => return None,
2798 }
2799 }
2800 }))
2801}
2802
2803fn or_else_source_stream<Out>(
2804 mut primary: BoxStream<Out>,
2805 mut secondary: BoxStream<Out>,
2806) -> BoxStream<Out>
2807where
2808 Out: Send + 'static,
2809{
2810 let mut primary_emitted = false;
2811 let mut using_secondary = false;
2812 Box::new(std::iter::from_fn(move || {
2813 loop {
2814 if using_secondary {
2815 return secondary.next();
2816 }
2817
2818 match primary.next() {
2819 Some(Ok(item)) => {
2820 primary_emitted = true;
2821 return Some(Ok(item));
2822 }
2823 Some(Err(error)) => return Some(Err(error)),
2824 None if primary_emitted => return None,
2825 None => using_secondary = true,
2826 }
2827 }
2828 }))
2829}
2830
2831fn interleave_source_streams<Out>(
2832 streams: Vec<BoxStream<Out>>,
2833 segment_size: usize,
2834 eager_close: bool,
2835) -> BoxStream<Out>
2836where
2837 Out: Send + 'static,
2838{
2839 if segment_size == 0 {
2840 return Box::new(std::iter::once(Err(StreamError::GraphValidation(
2841 "interleave segment size must be greater than zero".into(),
2842 ))));
2843 }
2844
2845 let mut streams: Vec<Option<BoxStream<Out>>> = streams.into_iter().map(Some).collect();
2846 let mut pending: Vec<Option<StreamResult<Out>>> = (0..streams.len()).map(|_| None).collect();
2847 let mut current = 0usize;
2848 let mut emitted = 0usize;
2849 Box::new(std::iter::from_fn(move || {
2850 loop {
2851 if streams.iter().all(Option::is_none) {
2852 return None;
2853 }
2854 if streams[current].is_none() {
2855 match next_active_source_stream(&streams, current) {
2856 Some(next) => {
2857 current = next;
2858 emitted = 0;
2859 }
2860 None => return None,
2861 }
2862 }
2863
2864 let Some(stream) = streams[current].as_mut() else {
2865 continue;
2866 };
2867 let next_item = pending[current].take().or_else(|| stream.next());
2868 match next_item {
2869 Some(Ok(item)) => {
2870 emitted += 1;
2871 if emitted == segment_size {
2872 emitted = 0;
2873 if let Some(next) = next_active_source_stream(&streams, current) {
2874 current = next;
2875 }
2876 }
2877 return Some(Ok(item));
2878 }
2879 Some(Err(error)) => return Some(Err(error)),
2880 None => {
2881 streams[current] = None;
2882 emitted = 0;
2883 if eager_close {
2884 return None;
2885 }
2886 match next_active_source_stream(&streams, current) {
2887 Some(next) => current = next,
2888 None => return None,
2889 }
2890 }
2891 }
2892 }
2893 }))
2894}
2895
2896fn next_active_source_stream<Out>(
2897 streams: &[Option<BoxStream<Out>>],
2898 current: usize,
2899) -> Option<usize>
2900where
2901 Out: Send + 'static,
2902{
2903 if streams.is_empty() {
2904 return None;
2905 }
2906 for offset in 1..=streams.len() {
2907 let index = (current + offset) % streams.len();
2908 if streams[index].is_some() {
2909 return Some(index);
2910 }
2911 }
2912 None
2913}