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 scalar_chunks_allowed = self.hints.inline_micro.is_some();
654 let source = self.factory;
655 let transform = flow.transform;
656 let scalar_i64_fallback = flow.scalar_i64_fallback;
657 let materialize_flow = flow.materialize;
658 let hints = self.hints.after_flow(flow.hints);
659 let combine = Arc::new(combine);
660 Source::from_materialized_factory_with_hints(
661 move |materializer| {
662 let (stream, source_mat) = Arc::clone(&source).create(materializer)?;
663 let flow_mat = materialize_flow()?;
664 let stream = match &transform {
665 FlowTransform::Pure(transform) => {
666 if scalar_chunks_allowed {
667 transform(stream)
668 } else if let Some(fallback) = &scalar_i64_fallback {
669 fallback(stream)
670 } else {
671 transform(stream)
672 }
673 }
674 FlowTransform::Runtime(transform) => transform(stream, materializer)?,
675 };
676 Ok((stream, combine(source_mat, flow_mat)))
677 },
678 hints,
679 )
680 }
681
682 #[must_use]
683 pub fn via_mat_with<Next, FlowMat, Combined, F>(
684 self,
685 flow: Flow<Out, Next, FlowMat>,
686 combine: F,
687 ) -> Source<Next, Combined>
688 where
689 Next: Send + 'static,
690 FlowMat: Send + 'static,
691 Combined: Send + 'static,
692 F: Fn(Mat, FlowMat) -> Combined + Send + Sync + 'static,
693 {
694 self.via_mat(flow, combine)
695 }
696
697 #[must_use]
698 pub fn map<Next, F>(self, f: F) -> Source<Next, Mat>
699 where
700 Next: Send + 'static,
701 F: Fn(Out) -> Next + Send + Sync + 'static,
702 {
703 let hints = self.hints.without_inline_micro();
704 Source {
705 factory: Arc::new(MapSourceFactory {
706 source: self.factory,
707 stage: f,
708 _marker: PhantomData,
709 }),
710 terminal_factory: None,
711 hints,
712 attributes: self.attributes,
713 split_hook: None,
714 }
715 }
716
717 #[must_use]
718 pub fn attributes(&self) -> &Attributes {
719 &self.attributes
720 }
721
722 #[must_use]
723 pub fn with_attributes(mut self, attributes: Attributes) -> Self {
724 self.attributes = attributes;
725 self
726 }
727
728 #[must_use]
729 pub fn add_attributes(mut self, attributes: Attributes) -> Self {
730 self.attributes = self.attributes.and(attributes);
731 self
732 }
733
734 #[must_use]
735 pub fn named(self, name: impl Into<String>) -> Self {
736 self.add_attributes(Attributes::named(name))
737 }
738
739 #[must_use]
749 pub fn instrumented(
750 self,
751 name: impl Into<String>,
752 registry: &StreamInstrumentationRegistry,
753 ) -> Self {
754 let Source {
755 factory,
756 terminal_factory: _,
757 hints,
758 attributes,
759 split_hook: _,
760 } = self;
761 let name: Arc<str> = Arc::from(name.into());
762 let registry = registry.clone();
763 let mut source = Source::from_materialized_factory_with_hints(
764 move |materializer| {
765 let run = registry.register(name.as_ref().to_owned());
766 match Arc::clone(&factory).create(materializer) {
767 Ok((stream, mat)) => Ok((
768 Box::new(InstrumentedStream::new(stream, run)) as BoxStream<Out>,
769 mat,
770 )),
771 Err(error) => {
772 run.mark_failed();
773 Err(error)
774 }
775 }
776 },
777 hints.without_inline_micro(),
778 );
779 source.attributes = attributes;
780 source
781 }
782
783 #[must_use]
790 pub fn async_boundary(self) -> Self {
791 self.via(Flow::identity().async_boundary())
792 }
793
794 #[must_use]
796 pub fn r#async(self) -> Self {
797 self.async_boundary()
798 }
799
800 #[must_use]
806 pub fn async_boundary_with_config(
807 self,
808 config: crate::graph::AsyncBoundaryExecutionConfig,
809 ) -> Self {
810 self.via(Flow::identity().async_boundary_with_config(config))
811 }
812
813 #[must_use]
815 pub fn async_boundary_with_buffer(self, buffer_size: usize) -> Self {
816 self.via(Flow::identity().async_boundary_with_buffer(buffer_size))
817 }
818
819 #[must_use]
820 pub fn try_map<Next, F>(self, f: F) -> Source<Next, Mat>
821 where
822 Next: Send + 'static,
823 F: Fn(Out) -> StreamResult<Next> + Send + Sync + 'static,
824 {
825 self.via(Flow::identity().try_map(f))
826 }
827
828 #[must_use]
830 #[deprecated(
831 since = "0.9.0",
832 note = "renamed to `try_map` (idiomatic); the `_result` name still works"
833 )]
834 pub fn map_result<Next, F>(self, f: F) -> Source<Next, Mat>
835 where
836 Next: Send + 'static,
837 F: Fn(Out) -> StreamResult<Next> + Send + Sync + 'static,
838 {
839 self.try_map(f)
840 }
841
842 #[must_use]
843 pub fn map_result_with_supervision<Next, F>(
844 self,
845 f: F,
846 decider: SupervisionDecider,
847 ) -> Source<Next, Mat>
848 where
849 Next: Send + 'static,
850 F: Fn(Out) -> StreamResult<Next> + Send + Sync + 'static,
851 {
852 self.via(Flow::identity().map_result_with_supervision(f, decider))
853 }
854
855 #[must_use]
856 pub fn filter<F>(self, predicate: F) -> Source<Out, Mat>
857 where
858 F: Fn(&Out) -> bool + Send + Sync + 'static,
859 {
860 self.via(Flow::identity().filter(predicate))
861 }
862
863 #[must_use]
864 pub fn try_filter<F>(self, predicate: F) -> Source<Out, Mat>
865 where
866 F: Fn(&Out) -> StreamResult<bool> + Send + Sync + 'static,
867 {
868 self.via(Flow::identity().try_filter(predicate))
869 }
870
871 #[must_use]
873 #[deprecated(
874 since = "0.9.0",
875 note = "renamed to `try_filter` (idiomatic); the `_result` name still works"
876 )]
877 pub fn filter_result<F>(self, predicate: F) -> Source<Out, Mat>
878 where
879 F: Fn(&Out) -> StreamResult<bool> + Send + Sync + 'static,
880 {
881 self.try_filter(predicate)
882 }
883
884 #[must_use]
885 pub fn filter_result_with_supervision<F>(
886 self,
887 predicate: F,
888 decider: SupervisionDecider,
889 ) -> Source<Out, Mat>
890 where
891 F: Fn(&Out) -> StreamResult<bool> + Send + Sync + 'static,
892 {
893 self.via(Flow::identity().filter_result_with_supervision(predicate, decider))
894 }
895
896 #[must_use]
897 pub fn filter_not<F>(self, predicate: F) -> Source<Out, Mat>
898 where
899 F: Fn(&Out) -> bool + Send + Sync + 'static,
900 {
901 self.via(Flow::identity().filter_not(predicate))
902 }
903
904 #[must_use]
905 pub fn filter_map<Next, F>(self, f: F) -> Source<Next, Mat>
906 where
907 Next: Send + 'static,
908 F: Fn(Out) -> Option<Next> + Send + Sync + 'static,
909 {
910 self.via(Flow::identity().filter_map(f))
911 }
912
913 #[must_use]
914 pub fn try_filter_map<Next, F>(self, f: F) -> Source<Next, Mat>
915 where
916 Next: Send + 'static,
917 F: Fn(Out) -> StreamResult<Option<Next>> + Send + Sync + 'static,
918 {
919 self.via(Flow::identity().try_filter_map(f))
920 }
921
922 #[must_use]
924 #[deprecated(
925 since = "0.9.0",
926 note = "renamed to `try_filter_map` (idiomatic); the `_result` name still works"
927 )]
928 pub fn filter_map_result<Next, F>(self, f: F) -> Source<Next, Mat>
929 where
930 Next: Send + 'static,
931 F: Fn(Out) -> StreamResult<Option<Next>> + Send + Sync + 'static,
932 {
933 self.try_filter_map(f)
934 }
935
936 #[must_use]
937 pub fn filter_map_result_with_supervision<Next, F>(
938 self,
939 f: F,
940 decider: SupervisionDecider,
941 ) -> Source<Next, Mat>
942 where
943 Next: Send + 'static,
944 F: Fn(Out) -> StreamResult<Option<Next>> + Send + Sync + 'static,
945 {
946 self.via(Flow::identity().filter_map_result_with_supervision(f, decider))
947 }
948
949 #[must_use]
950 pub fn map_concat<Next, F, I>(self, f: F) -> Source<Next, Mat>
951 where
952 Next: Send + 'static,
953 F: Fn(Out) -> I + Send + Sync + 'static,
954 I: IntoIterator<Item = Next>,
955 I::IntoIter: Send + 'static,
956 {
957 self.via(Flow::identity().map_concat(f))
958 }
959
960 #[must_use]
961 pub fn try_map_concat<Next, F, I>(self, f: F) -> Source<Next, Mat>
962 where
963 Next: Send + 'static,
964 F: Fn(Out) -> StreamResult<I> + Send + Sync + 'static,
965 I: IntoIterator<Item = Next>,
966 I::IntoIter: Send + 'static,
967 {
968 self.via(Flow::identity().try_map_concat(f))
969 }
970
971 #[must_use]
973 #[deprecated(
974 since = "0.9.0",
975 note = "renamed to `try_map_concat` (idiomatic); the `_result` name still works"
976 )]
977 pub fn map_concat_result<Next, F, I>(self, f: F) -> Source<Next, Mat>
978 where
979 Next: Send + 'static,
980 F: Fn(Out) -> StreamResult<I> + Send + Sync + 'static,
981 I: IntoIterator<Item = Next>,
982 I::IntoIter: Send + 'static,
983 {
984 self.try_map_concat(f)
985 }
986
987 #[must_use]
988 pub fn map_concat_result_with_supervision<Next, F, I>(
989 self,
990 f: F,
991 decider: SupervisionDecider,
992 ) -> Source<Next, Mat>
993 where
994 Next: Send + 'static,
995 F: Fn(Out) -> StreamResult<I> + Send + Sync + 'static,
996 I: IntoIterator<Item = Next>,
997 I::IntoIter: Send + 'static,
998 {
999 self.via(Flow::identity().map_concat_result_with_supervision(f, decider))
1000 }
1001
1002 #[must_use]
1003 pub fn 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) -> Next + Send + Sync + 'static,
1008 {
1009 self.via(Flow::identity().stateful_map(seed, f))
1010 }
1011
1012 #[must_use]
1013 pub fn try_stateful_map<State, Next, F>(self, seed: State, f: F) -> Source<Next, Mat>
1014 where
1015 State: Clone + Send + Sync + 'static,
1016 Next: Send + 'static,
1017 F: Fn(&mut State, Out) -> StreamResult<Next> + Send + Sync + 'static,
1018 {
1019 self.via(Flow::identity().try_stateful_map(seed, f))
1020 }
1021
1022 #[must_use]
1024 #[deprecated(
1025 since = "0.9.0",
1026 note = "renamed to `try_stateful_map` (idiomatic); the `_result` name still works"
1027 )]
1028 pub fn stateful_map_result<State, Next, F>(self, seed: State, f: F) -> Source<Next, Mat>
1029 where
1030 State: Clone + Send + Sync + 'static,
1031 Next: Send + 'static,
1032 F: Fn(&mut State, Out) -> StreamResult<Next> + Send + Sync + 'static,
1033 {
1034 self.try_stateful_map(seed, f)
1035 }
1036
1037 #[must_use]
1038 pub fn stateful_map_result_with_supervision<State, Next, F>(
1039 self,
1040 seed: State,
1041 f: F,
1042 decider: SupervisionDecider,
1043 ) -> Source<Next, Mat>
1044 where
1045 State: Clone + Send + Sync + 'static,
1046 Next: Send + 'static,
1047 F: Fn(&mut State, Out) -> StreamResult<Next> + Send + Sync + 'static,
1048 {
1049 self.via(Flow::identity().stateful_map_result_with_supervision(seed, f, decider))
1050 }
1051
1052 #[must_use]
1053 pub fn stateful_map_concat<State, Next, F, I>(self, seed: State, f: F) -> Source<Next, Mat>
1054 where
1055 State: Clone + Send + Sync + 'static,
1056 Next: Send + 'static,
1057 F: Fn(&mut State, Out) -> I + Send + Sync + 'static,
1058 I: IntoIterator<Item = Next>,
1059 I::IntoIter: Send + 'static,
1060 {
1061 self.via(Flow::identity().stateful_map_concat(seed, f))
1062 }
1063
1064 #[must_use]
1065 pub fn try_stateful_map_concat<State, Next, F, I>(self, seed: State, f: F) -> Source<Next, Mat>
1066 where
1067 State: Clone + Send + Sync + 'static,
1068 Next: Send + 'static,
1069 F: Fn(&mut State, Out) -> StreamResult<I> + Send + Sync + 'static,
1070 I: IntoIterator<Item = Next>,
1071 I::IntoIter: Send + 'static,
1072 {
1073 self.via(Flow::identity().try_stateful_map_concat(seed, f))
1074 }
1075
1076 #[must_use]
1078 #[deprecated(
1079 since = "0.9.0",
1080 note = "renamed to `try_stateful_map_concat` (idiomatic); the `_result` name still works"
1081 )]
1082 pub fn stateful_map_concat_result<State, Next, F, I>(
1083 self,
1084 seed: State,
1085 f: F,
1086 ) -> Source<Next, Mat>
1087 where
1088 State: Clone + Send + Sync + 'static,
1089 Next: Send + 'static,
1090 F: Fn(&mut State, Out) -> StreamResult<I> + Send + Sync + 'static,
1091 I: IntoIterator<Item = Next>,
1092 I::IntoIter: Send + 'static,
1093 {
1094 self.try_stateful_map_concat(seed, f)
1095 }
1096
1097 #[must_use]
1098 pub fn stateful_map_concat_result_with_supervision<State, Next, F, I>(
1099 self,
1100 seed: State,
1101 f: F,
1102 decider: SupervisionDecider,
1103 ) -> Source<Next, Mat>
1104 where
1105 State: Clone + Send + Sync + 'static,
1106 Next: Send + 'static,
1107 F: Fn(&mut State, Out) -> StreamResult<I> + Send + Sync + 'static,
1108 I: IntoIterator<Item = Next>,
1109 I::IntoIter: Send + 'static,
1110 {
1111 self.via(Flow::identity().stateful_map_concat_result_with_supervision(seed, f, decider))
1112 }
1113
1114 #[must_use]
1115 pub fn map_async<Next, F, Fut>(self, parallelism: usize, f: F) -> Source<Next, Mat>
1116 where
1117 Next: Send + 'static,
1118 F: Fn(Out) -> Fut + Send + Sync + 'static,
1119 Fut: Future<Output = StreamResult<Next>> + Send + 'static,
1120 {
1121 self.via(Flow::identity().map_async(parallelism, f))
1122 }
1123
1124 #[must_use]
1125 pub fn map_async_with_supervision<Next, F, Fut>(
1126 self,
1127 parallelism: usize,
1128 f: F,
1129 decider: SupervisionDecider,
1130 ) -> 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_with_supervision(parallelism, f, decider))
1137 }
1138
1139 #[must_use]
1140 pub fn map_async_unordered<Next, F, Fut>(self, parallelism: usize, f: F) -> Source<Next, Mat>
1141 where
1142 Next: Send + 'static,
1143 F: Fn(Out) -> Fut + Send + Sync + 'static,
1144 Fut: Future<Output = StreamResult<Next>> + Send + 'static,
1145 {
1146 self.via(Flow::identity().map_async_unordered(parallelism, f))
1147 }
1148
1149 #[must_use]
1150 pub fn map_async_unordered_with_supervision<Next, F, Fut>(
1151 self,
1152 parallelism: usize,
1153 f: F,
1154 decider: SupervisionDecider,
1155 ) -> Source<Next, Mat>
1156 where
1157 Next: Send + 'static,
1158 F: Fn(Out) -> Fut + Send + Sync + 'static,
1159 Fut: Future<Output = StreamResult<Next>> + Send + 'static,
1160 {
1161 self.via(Flow::identity().map_async_unordered_with_supervision(parallelism, f, decider))
1162 }
1163
1164 #[must_use]
1165 pub fn map_async_partitioned<Key, Next, Partition, F, Fut>(
1166 self,
1167 parallelism: usize,
1168 per_partition: usize,
1169 partition: Partition,
1170 f: F,
1171 ) -> Source<Next, Mat>
1172 where
1173 Key: Clone + Eq + Hash + Send + 'static,
1174 Next: Send + 'static,
1175 Partition: Fn(&Out) -> Key + Send + Sync + 'static,
1176 F: Fn(Out) -> Fut + Send + Sync + 'static,
1177 Fut: Future<Output = StreamResult<Next>> + Send + 'static,
1178 {
1179 self.via(Flow::identity().map_async_partitioned(parallelism, per_partition, partition, f))
1180 }
1181
1182 #[must_use]
1183 pub fn prefix_and_tail(self, n: usize) -> Source<(Vec<Out>, Source<Out>), Mat> {
1184 self.via(Flow::identity().prefix_and_tail(n))
1185 }
1186
1187 #[must_use]
1188 pub fn flat_map_prefix<Next, FlowMat, F>(self, n: usize, f: F) -> Source<Next, Mat>
1189 where
1190 Next: Send + 'static,
1191 FlowMat: Send + 'static,
1192 F: Fn(Vec<Out>) -> Flow<Out, Next, FlowMat> + Send + Sync + 'static,
1193 Out: Clone,
1194 {
1195 self.via(Flow::identity().flat_map_prefix(n, f))
1196 }
1197
1198 #[must_use]
1199 pub fn group_by<Key, F>(
1200 self,
1201 max_substreams: usize,
1202 f: F,
1203 allow_closed_substream_recreation: bool,
1204 ) -> Source<Source<Out>, Mat>
1205 where
1206 Key: Clone + Eq + Hash + Send + 'static,
1207 F: Fn(&Out) -> Key + Send + Sync + 'static,
1208 Out: Clone,
1209 {
1210 let batch_mode = if self.hints.inline_micro.is_some() && !allow_closed_substream_recreation
1211 {
1212 flow::GroupByBatchMode::FiniteEagerNoRecreate
1213 } else {
1214 flow::GroupByBatchMode::Immediate
1215 };
1216 self.via(Flow::identity().group_by_with_batching(
1217 max_substreams,
1218 f,
1219 allow_closed_substream_recreation,
1220 batch_mode,
1221 ))
1222 }
1223
1224 #[must_use]
1225 pub fn split_when<F>(self, predicate: F) -> Source<Source<Out>, Mat>
1226 where
1227 F: Fn(&Out) -> bool + Send + Sync + 'static,
1228 Out: Clone,
1229 {
1230 self.via(Flow::identity().split_when(predicate))
1231 }
1232
1233 #[must_use]
1234 pub fn split_after<F>(self, predicate: F) -> Source<Source<Out>, Mat>
1235 where
1236 F: Fn(&Out) -> bool + Send + Sync + 'static,
1237 Out: Clone,
1238 {
1239 self.via(Flow::identity().split_after(predicate))
1240 }
1241
1242 #[must_use]
1243 pub fn flat_map_concat<Next, NextMat, F>(self, 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_concat(f))
1250 }
1251
1252 #[must_use]
1253 pub fn flat_map_merge<Next, NextMat, F>(self, breadth: usize, f: F) -> Source<Next, Mat>
1254 where
1255 Next: Send + 'static,
1256 NextMat: Send + 'static,
1257 F: Fn(Out) -> Source<Next, NextMat> + Send + Sync + 'static,
1258 {
1259 self.via(Flow::identity().flat_map_merge(breadth, f))
1260 }
1261
1262 #[must_use]
1263 pub fn take(self, n: usize) -> Source<Out, Mat> {
1264 self.via(Flow::identity().take(n))
1265 }
1266
1267 #[must_use]
1268 pub fn drop(self, n: usize) -> Source<Out, Mat> {
1269 self.via(Flow::identity().drop(n))
1270 }
1271
1272 #[must_use]
1273 pub fn take_while<F>(self, predicate: F) -> Source<Out, Mat>
1274 where
1275 F: Fn(&Out) -> bool + Send + Sync + 'static,
1276 {
1277 self.via(Flow::identity().take_while(predicate))
1278 }
1279
1280 #[must_use]
1281 pub fn drop_while<F>(self, predicate: F) -> Source<Out, Mat>
1282 where
1283 F: Fn(&Out) -> bool + Send + Sync + 'static,
1284 {
1285 self.via(Flow::identity().drop_while(predicate))
1286 }
1287
1288 #[must_use]
1289 pub fn limit(self, max: u64) -> Source<Out, Mat> {
1290 self.via(Flow::identity().limit(max))
1291 }
1292
1293 #[must_use]
1294 pub fn grouped(self, size: usize) -> Source<Vec<Out>, Mat> {
1295 self.via(Flow::identity().grouped(size))
1296 }
1297
1298 #[must_use]
1299 pub fn scan<State, F>(self, seed: State, f: F) -> Source<State, Mat>
1300 where
1301 State: Clone + Send + Sync + 'static,
1302 F: Fn(State, Out) -> State + Send + Sync + 'static,
1303 {
1304 self.via(Flow::identity().scan(seed, f))
1305 }
1306
1307 #[must_use]
1308 pub fn scan_async<State, F, Fut>(self, seed: State, f: F) -> Source<State, Mat>
1309 where
1310 State: Clone + Send + Sync + 'static,
1311 F: Fn(State, Out) -> Fut + Send + Sync + 'static,
1312 Fut: Future<Output = StreamResult<State>> + Send + 'static,
1313 {
1314 self.via(Flow::identity().scan_async(seed, f))
1315 }
1316
1317 #[must_use]
1318 pub fn try_scan<State, F>(self, seed: State, f: F) -> Source<State, Mat>
1319 where
1320 State: Clone + Send + Sync + 'static,
1321 F: Fn(State, Out) -> StreamResult<State> + Send + Sync + 'static,
1322 {
1323 self.via(Flow::identity().try_scan(seed, f))
1324 }
1325
1326 #[must_use]
1328 #[deprecated(
1329 since = "0.9.0",
1330 note = "renamed to `try_scan` (idiomatic); the `_result` name still works"
1331 )]
1332 pub fn scan_result<State, F>(self, seed: State, f: F) -> Source<State, Mat>
1333 where
1334 State: Clone + Send + Sync + 'static,
1335 F: Fn(State, Out) -> StreamResult<State> + Send + Sync + 'static,
1336 {
1337 self.try_scan(seed, f)
1338 }
1339
1340 #[must_use]
1341 pub fn scan_result_with_supervision<State, F>(
1342 self,
1343 seed: State,
1344 f: F,
1345 decider: SupervisionDecider,
1346 ) -> Source<State, Mat>
1347 where
1348 State: Clone + Send + Sync + 'static,
1349 F: Fn(State, Out) -> StreamResult<State> + Send + Sync + 'static,
1350 {
1351 self.via(Flow::identity().scan_result_with_supervision(seed, f, decider))
1352 }
1353
1354 #[must_use]
1355 pub fn sliding(self, size: usize, step: usize) -> Source<Vec<Out>, Mat>
1356 where
1357 Out: Clone,
1358 {
1359 self.via(Flow::identity().sliding(size, step))
1360 }
1361
1362 #[must_use]
1363 pub fn fold<Acc, F>(self, zero: Acc, f: F) -> Source<Acc, Mat>
1364 where
1365 Acc: Clone + Send + Sync + 'static,
1366 F: Fn(Acc, Out) -> Acc + Send + Sync + 'static,
1367 {
1368 self.via(Flow::identity().fold(zero, f))
1369 }
1370
1371 #[must_use]
1372 pub fn fold_async<Acc, F, Fut>(self, zero: Acc, f: F) -> Source<Acc, Mat>
1373 where
1374 Acc: Clone + Send + Sync + 'static,
1375 F: Fn(Acc, Out) -> Fut + Send + Sync + 'static,
1376 Fut: Future<Output = StreamResult<Acc>> + Send + 'static,
1377 {
1378 self.via(Flow::identity().fold_async(zero, f))
1379 }
1380
1381 #[must_use]
1382 pub fn map_with_resource<Resource, Next, Create, F, Close>(
1383 self,
1384 create: Create,
1385 f: F,
1386 close: Close,
1387 ) -> Source<Next, Mat>
1388 where
1389 Resource: Send + 'static,
1390 Next: Send + 'static,
1391 Create: Fn() -> StreamResult<Resource> + Send + Sync + 'static,
1392 F: Fn(&mut Resource, Out) -> StreamResult<Next> + Send + Sync + 'static,
1393 Close: Fn(Resource) -> StreamResult<Option<Next>> + Send + Sync + 'static,
1394 {
1395 self.via(Flow::identity().map_with_resource(create, f, close))
1396 }
1397
1398 #[must_use]
1399 pub fn try_fold<Acc, F>(self, zero: Acc, f: F) -> Source<Acc, Mat>
1400 where
1401 Acc: Clone + Send + Sync + 'static,
1402 F: Fn(Acc, Out) -> StreamResult<Acc> + Send + Sync + 'static,
1403 {
1404 self.via(Flow::identity().try_fold(zero, f))
1405 }
1406
1407 #[must_use]
1409 #[deprecated(
1410 since = "0.9.0",
1411 note = "renamed to `try_fold` (idiomatic); the `_result` name still works"
1412 )]
1413 pub fn fold_result<Acc, F>(self, zero: Acc, f: F) -> Source<Acc, Mat>
1414 where
1415 Acc: Clone + Send + Sync + 'static,
1416 F: Fn(Acc, Out) -> StreamResult<Acc> + Send + Sync + 'static,
1417 {
1418 self.try_fold(zero, f)
1419 }
1420
1421 #[must_use]
1422 pub fn fold_result_with_supervision<Acc, F>(
1423 self,
1424 zero: Acc,
1425 f: F,
1426 decider: SupervisionDecider,
1427 ) -> Source<Acc, Mat>
1428 where
1429 Acc: Clone + Send + Sync + 'static,
1430 F: Fn(Acc, Out) -> StreamResult<Acc> + Send + Sync + 'static,
1431 {
1432 self.via(Flow::identity().fold_result_with_supervision(zero, f, decider))
1433 }
1434
1435 #[must_use]
1436 pub fn reduce<F>(self, f: F) -> Source<Out, Mat>
1437 where
1438 F: Fn(Out, Out) -> Out + Send + Sync + 'static,
1439 {
1440 self.via(Flow::identity().reduce(f))
1441 }
1442
1443 #[must_use]
1444 pub fn try_reduce<F>(self, f: F) -> Source<Out, Mat>
1445 where
1446 Out: Clone,
1447 F: Fn(Out, Out) -> StreamResult<Out> + Send + Sync + 'static,
1448 {
1449 self.via(Flow::identity().try_reduce(f))
1450 }
1451
1452 #[must_use]
1454 #[deprecated(
1455 since = "0.9.0",
1456 note = "renamed to `try_reduce` (idiomatic); the `_result` name still works"
1457 )]
1458 pub fn reduce_result<F>(self, f: F) -> Source<Out, Mat>
1459 where
1460 Out: Clone,
1461 F: Fn(Out, Out) -> StreamResult<Out> + Send + Sync + 'static,
1462 {
1463 self.try_reduce(f)
1464 }
1465
1466 #[must_use]
1467 pub fn reduce_result_with_supervision<F>(
1468 self,
1469 f: F,
1470 decider: SupervisionDecider,
1471 ) -> Source<Out, Mat>
1472 where
1473 Out: Clone,
1474 F: Fn(Out, Out) -> StreamResult<Out> + Send + Sync + 'static,
1475 {
1476 self.via(Flow::identity().reduce_result_with_supervision(f, decider))
1477 }
1478
1479 #[must_use]
1480 pub fn map_error<F>(self, f: F) -> Source<Out, Mat>
1481 where
1482 F: Fn(StreamError) -> StreamError + Send + Sync + 'static,
1483 {
1484 self.via(Flow::identity().map_error(f))
1485 }
1486
1487 #[must_use]
1488 pub fn recover<F>(self, f: F) -> Source<Out, Mat>
1489 where
1490 F: Fn(StreamError) -> Option<Out> + Send + Sync + 'static,
1491 {
1492 self.via(Flow::identity().recover(f))
1493 }
1494
1495 #[must_use]
1496 pub fn recover_with<F>(self, f: F) -> Source<Out, Mat>
1497 where
1498 F: Fn(StreamError) -> Option<Source<Out>> + Send + Sync + 'static,
1499 {
1500 self.via(Flow::identity().recover_with(f))
1501 }
1502
1503 #[must_use]
1504 pub fn recover_with_retries<F>(self, retries: usize, f: F) -> Source<Out, Mat>
1505 where
1506 F: Fn(StreamError) -> Option<Source<Out>> + Send + Sync + 'static,
1507 {
1508 self.via(Flow::identity().recover_with_retries(retries, f))
1509 }
1510
1511 #[must_use]
1512 pub fn on_error_complete(self) -> Source<Out, Mat> {
1513 self.via(Flow::identity().on_error_complete())
1514 }
1515
1516 #[must_use]
1517 pub fn concat<Mat2>(self, that: Source<Out, Mat2>) -> Source<Out, Mat>
1518 where
1519 Mat2: Send + 'static,
1520 {
1521 let factory = self.factory;
1522 let hints = self.hints;
1523 let that_factory = that.factory;
1524 Source::from_materialized_factory_with_hints(
1525 move |materializer| {
1526 let (primary, mat) = Arc::clone(&factory).create(materializer)?;
1527 let secondary = match Arc::clone(&that_factory).create(materializer) {
1528 Ok((stream, _)) => stream,
1529 Err(error) => Box::new(std::iter::once(Err(error))) as BoxStream<Out>,
1530 };
1531 Ok((concat_source_streams(vec![primary, secondary]), mat))
1532 },
1533 hints,
1534 )
1535 }
1536
1537 #[must_use]
1538 pub fn concat_lazy<Mat2>(self, that: Source<Out, Mat2>) -> Source<Out, Mat>
1539 where
1540 Mat2: Send + 'static,
1541 {
1542 let factory = self.factory;
1543 let hints = self.hints;
1544 let that_factory = that.factory;
1545 Source::from_materialized_factory_with_hints(
1546 move |materializer| {
1547 let (primary, mat) = Arc::clone(&factory).create(materializer)?;
1548 Ok((
1549 concat_source_streams_lazy(
1550 primary,
1551 vec![Arc::clone(&that_factory)],
1552 materializer,
1553 ),
1554 mat,
1555 ))
1556 },
1557 hints,
1558 )
1559 }
1560
1561 #[must_use]
1562 pub fn concat_all_lazy<Mat2, I>(self, those: I) -> Source<Out, Mat>
1563 where
1564 Mat2: Send + 'static,
1565 I: IntoIterator<Item = Source<Out, Mat2>>,
1566 {
1567 let factory = self.factory;
1568 let hints = self.hints;
1569 let other_factories: Vec<_> = those.into_iter().map(|source| source.factory).collect();
1570 Source::from_materialized_factory_with_hints(
1571 move |materializer| {
1572 let (primary, mat) = Arc::clone(&factory).create(materializer)?;
1573 Ok((
1574 concat_source_streams_lazy(primary, other_factories.clone(), materializer),
1575 mat,
1576 ))
1577 },
1578 hints,
1579 )
1580 }
1581
1582 #[must_use]
1583 pub fn prepend<Mat2>(self, that: Source<Out, Mat2>) -> Source<Out, Mat>
1584 where
1585 Mat2: Send + 'static,
1586 {
1587 let factory = self.factory;
1588 let hints = self.hints;
1589 let that_factory = that.factory;
1590 Source::from_materialized_factory_with_hints(
1591 move |materializer| {
1592 let (primary, mat) = Arc::clone(&factory).create(materializer)?;
1593 let secondary = match Arc::clone(&that_factory).create(materializer) {
1594 Ok((stream, _)) => stream,
1595 Err(error) => Box::new(std::iter::once(Err(error))) as BoxStream<Out>,
1596 };
1597 Ok((concat_source_streams(vec![secondary, primary]), mat))
1598 },
1599 hints,
1600 )
1601 }
1602
1603 #[must_use]
1604 pub fn prepend_lazy<Mat2>(self, that: Source<Out, Mat2>) -> Source<Out, Mat>
1605 where
1606 Mat2: Send + 'static,
1607 {
1608 self.prepend(that)
1609 }
1610
1611 #[must_use]
1612 pub fn or_else<Mat2>(self, secondary: Source<Out, Mat2>) -> Source<Out, Mat>
1613 where
1614 Mat2: Send + 'static,
1615 {
1616 let factory = self.factory;
1617 let hints = self.hints;
1618 let secondary_factory = secondary.factory;
1619 Source::from_materialized_factory_with_hints(
1620 move |materializer| {
1621 let (primary, mat) = Arc::clone(&factory).create(materializer)?;
1622 let secondary = match Arc::clone(&secondary_factory).create(materializer) {
1623 Ok((stream, _)) => stream,
1624 Err(error) => Box::new(std::iter::once(Err(error))) as BoxStream<Out>,
1625 };
1626 Ok((or_else_source_stream(primary, secondary), mat))
1627 },
1628 hints,
1629 )
1630 }
1631
1632 #[must_use]
1633 pub fn interleave<Mat2>(self, that: Source<Out, Mat2>, segment_size: usize) -> Source<Out, Mat>
1634 where
1635 Mat2: Send + 'static,
1636 {
1637 self.interleave_all([that], segment_size, false)
1638 }
1639
1640 #[must_use]
1641 pub fn interleave_all<Mat2, I>(
1642 self,
1643 those: I,
1644 segment_size: usize,
1645 eager_close: bool,
1646 ) -> Source<Out, Mat>
1647 where
1648 Mat2: Send + 'static,
1649 I: IntoIterator<Item = Source<Out, Mat2>>,
1650 {
1651 let factory = self.factory;
1652 let hints = self.hints;
1653 let other_factories: Vec<_> = those.into_iter().map(|source| source.factory).collect();
1654 Source::from_materialized_factory_with_hints(
1655 move |materializer| {
1656 let (primary, mat) = Arc::clone(&factory).create(materializer)?;
1657 let mut streams = Vec::with_capacity(other_factories.len() + 1);
1658 streams.push(primary);
1659 for other in &other_factories {
1660 let stream = match Arc::clone(other).create(materializer) {
1661 Ok((stream, _)) => stream,
1662 Err(error) => Box::new(std::iter::once(Err(error))) as BoxStream<Out>,
1663 };
1664 streams.push(stream);
1665 }
1666 Ok((
1667 interleave_source_streams(streams, segment_size, eager_close),
1668 mat,
1669 ))
1670 },
1671 hints,
1672 )
1673 }
1674
1675 #[must_use]
1676 pub fn merge_sorted<Mat2>(self, that: Source<Out, Mat2>) -> Source<Out, Mat>
1677 where
1678 Out: Ord,
1679 Mat2: Send + 'static,
1680 {
1681 self.via(Flow::identity().merge_sorted(that))
1682 }
1683
1684 #[must_use]
1685 pub fn merge_latest<Mat2>(
1686 self,
1687 that: Source<Out, Mat2>,
1688 eager_complete: bool,
1689 ) -> Source<Vec<Out>, Mat>
1690 where
1691 Out: Clone,
1692 Mat2: Send + 'static,
1693 {
1694 let factory = self.factory;
1695 let hints = self.hints;
1696 let that_factory = that.factory;
1697 Source::from_materialized_factory_with_hints(
1698 move |materializer| {
1699 let (left, mat) = Arc::clone(&factory).create(materializer)?;
1700 let right = match Arc::clone(&that_factory).create(materializer) {
1701 Ok((stream, _)) => stream,
1702 Err(error) => {
1703 return Ok((
1704 Box::new(std::iter::once(Err(error))) as BoxStream<Vec<Out>>,
1705 mat,
1706 ));
1707 }
1708 };
1709 Ok((merge_latest_streams(vec![left, right], eager_complete), mat))
1710 },
1711 hints,
1712 )
1713 }
1714
1715 #[must_use]
1716 pub fn merge_all<Mat2, I>(self, those: I, eager_complete: bool) -> Source<Out, Mat>
1717 where
1718 Mat2: Send + 'static,
1719 I: IntoIterator<Item = Source<Out, Mat2>>,
1720 {
1721 let factory = self.factory;
1722 let hints = self.hints;
1723 let other_factories: Vec<_> = those.into_iter().map(|source| source.factory).collect();
1724 Source::from_materialized_factory_with_hints(
1725 move |materializer| {
1726 let (primary, mat) = Arc::clone(&factory).create(materializer)?;
1727 let mut streams = Vec::with_capacity(other_factories.len() + 1);
1728 streams.push(primary);
1729 for other in &other_factories {
1730 let stream = match Arc::clone(other).create(materializer) {
1731 Ok((stream, _)) => stream,
1732 Err(error) => {
1733 return Ok((
1734 Box::new(std::iter::once(Err(error))) as BoxStream<Out>,
1735 mat,
1736 ));
1737 }
1738 };
1739 streams.push(stream);
1740 }
1741 Ok((merge_streams(streams, eager_complete), mat))
1742 },
1743 hints,
1744 )
1745 }
1746
1747 #[must_use]
1748 pub fn zip_with<Mat2, Out2, Next, F>(
1749 self,
1750 that: Source<Out2, Mat2>,
1751 combine: F,
1752 ) -> Source<Next, Mat>
1753 where
1754 Out2: Send + 'static,
1755 Next: Send + 'static,
1756 Mat2: Send + 'static,
1757 F: Fn(Out, Out2) -> Next + Send + Sync + 'static,
1758 {
1759 self.via(Flow::identity().zip_with(that, combine))
1760 }
1761
1762 #[must_use]
1763 pub fn zip_latest<Mat2, Out2>(self, that: Source<Out2, Mat2>) -> Source<(Out, Out2), Mat>
1764 where
1765 Out: Clone,
1766 Out2: Clone + Send + 'static,
1767 Mat2: Send + 'static,
1768 {
1769 self.zip_latest_with(that, true, |left, right| (left, right))
1770 }
1771
1772 #[must_use]
1773 pub fn zip_latest_with<Mat2, Out2, Next, F>(
1774 self,
1775 that: Source<Out2, Mat2>,
1776 eager_complete: bool,
1777 combine: F,
1778 ) -> Source<Next, Mat>
1779 where
1780 Out: Clone,
1781 Out2: Clone + Send + 'static,
1782 Next: Send + 'static,
1783 Mat2: Send + 'static,
1784 F: Fn(Out, Out2) -> Next + Send + Sync + 'static,
1785 {
1786 let factory = self.factory;
1787 let hints = self.hints;
1788 let that_factory = that.factory;
1789 let combine = Arc::new(combine);
1790 Source::from_materialized_factory_with_hints(
1791 move |materializer| {
1792 let (left, mat) = Arc::clone(&factory).create(materializer)?;
1793 let right = match Arc::clone(&that_factory).create(materializer) {
1794 Ok((stream, _)) => stream,
1795 Err(error) => {
1796 return Ok((
1797 Box::new(std::iter::once(Err(error))) as BoxStream<Next>,
1798 mat,
1799 ));
1800 }
1801 };
1802 Ok((
1803 zip_latest_with_stream(left, right, eager_complete, Arc::clone(&combine)),
1804 mat,
1805 ))
1806 },
1807 hints,
1808 )
1809 }
1810
1811 #[must_use]
1812 pub fn zip_with_index(self) -> Source<(Out, u64), Mat> {
1813 let factory = self.factory;
1814 let hints = self.hints;
1815 Source::from_materialized_factory_with_hints(
1816 move |materializer| {
1817 let (mut stream, mat) = Arc::clone(&factory).create(materializer)?;
1818 let mut index = 0_u64;
1819 Ok((
1820 Box::new(std::iter::from_fn(move || {
1821 stream.next().map(|item| {
1822 item.map(|value| {
1823 let pair = (value, index);
1824 index = index.wrapping_add(1);
1825 pair
1826 })
1827 })
1828 })) as BoxStream<(Out, u64)>,
1829 mat,
1830 ))
1831 },
1832 hints,
1833 )
1834 }
1835
1836 #[must_use]
1837 pub fn zip_all<Mat2, Out2>(
1838 self,
1839 that: Source<Out2, Mat2>,
1840 this_elem: Out,
1841 that_elem: Out2,
1842 ) -> Source<(Out, Out2), Mat>
1843 where
1844 Out: Clone + Sync,
1845 Out2: Clone + Send + Sync + 'static,
1846 Mat2: Send + 'static,
1847 {
1848 let factory = self.factory;
1849 let hints = self.hints;
1850 let that_factory = that.factory;
1851 Source::from_materialized_factory_with_hints(
1852 move |materializer| {
1853 let (left, mat) = Arc::clone(&factory).create(materializer)?;
1854 let right = match Arc::clone(&that_factory).create(materializer) {
1855 Ok((stream, _)) => stream,
1856 Err(error) => {
1857 return Ok((
1858 Box::new(std::iter::once(Err(error))) as BoxStream<(Out, Out2)>,
1859 mat,
1860 ));
1861 }
1862 };
1863 Ok((
1864 zip_all_stream(left, right, this_elem.clone(), that_elem.clone()),
1865 mat,
1866 ))
1867 },
1868 hints,
1869 )
1870 }
1871
1872 #[must_use]
1873 pub fn also_to<SinkMat>(self, sink: Sink<Out, SinkMat>) -> Source<Out, Mat>
1874 where
1875 Out: Clone,
1876 SinkMat: Send + 'static,
1877 {
1878 self.via(Flow::identity().also_to(sink))
1879 }
1880
1881 #[must_use]
1882 pub fn also_to_all<SinkMat, I>(self, sinks: I) -> Source<Out, Mat>
1883 where
1884 Out: Clone,
1885 SinkMat: Send + 'static,
1886 I: IntoIterator<Item = Sink<Out, SinkMat>>,
1887 {
1888 self.via(Flow::identity().also_to_all(sinks))
1889 }
1890
1891 #[must_use]
1892 pub fn divert_to<SinkMat, F>(self, sink: Sink<Out, SinkMat>, predicate: F) -> Source<Out, Mat>
1893 where
1894 SinkMat: Send + 'static,
1895 F: Fn(&Out) -> bool + Send + Sync + 'static,
1896 {
1897 self.via(Flow::identity().divert_to(sink, predicate))
1898 }
1899
1900 #[must_use]
1901 pub fn wire_tap<SinkMat>(self, sink: Sink<Out, SinkMat>) -> Source<Out, Mat>
1902 where
1903 Out: Clone,
1904 SinkMat: Send + 'static,
1905 {
1906 self.via(Flow::identity().wire_tap(sink))
1907 }
1908
1909 pub fn run_with<SinkMat: Send + 'static>(
1910 self,
1911 sink: Sink<Out, SinkMat>,
1912 ) -> StreamResult<SinkMat> {
1913 let fast_result = self
1916 .split_hook
1917 .as_ref()
1918 .zip(sink.fold_fp.as_deref())
1919 .and_then(|(hook, fp)| fp.try_register(Arc::clone(hook)));
1920 if let Some(result) = fast_result {
1921 return result?.downcast::<SinkMat>().map(|b| *b).map_err(|_| {
1922 StreamError::Failed("split fast path: unexpected mat type (internal error)".into())
1923 });
1924 }
1925 self.to_mat(sink, Keep::right).run()
1926 }
1927
1928 pub fn run_with_materializer<SinkMat: Send + 'static>(
1929 self,
1930 sink: Sink<Out, SinkMat>,
1931 materializer: &Materializer,
1932 ) -> StreamResult<SinkMat> {
1933 self.to_mat(sink, Keep::right)
1934 .run_with_materializer(materializer)
1935 }
1936
1937 #[must_use]
1938 pub fn to<SinkMat>(self, sink: Sink<Out, SinkMat>) -> RunnableGraph<Mat>
1939 where
1940 SinkMat: Send + 'static,
1941 {
1942 self.to_mat(sink, Keep::left)
1943 }
1944
1945 #[must_use]
1946 pub fn to_mat<SinkMat, Combined, F>(
1947 self,
1948 sink: Sink<Out, SinkMat>,
1949 combine: F,
1950 ) -> RunnableGraph<Combined>
1951 where
1952 SinkMat: Send + 'static,
1953 Combined: Send + 'static,
1954 F: Fn(Mat, SinkMat) -> Combined + Send + Sync + 'static,
1955 {
1956 let factory = self.factory;
1957 let terminal_factory = self.terminal_factory;
1958 let hints = self.hints;
1959 let combine = Arc::new(combine);
1960 RunnableGraph::from_runner(move |materializer| {
1961 if let Some(terminal_factory) = &terminal_factory
1962 && let Some(fold_fp) = sink.fold_fp.as_deref()
1963 {
1964 let (hook, source_mat) = terminal_factory(materializer)?;
1965 if hook.supports_direct_terminal()
1966 && let Some(sink_mat) =
1967 fold_fp.try_register_direct_terminal(Arc::clone(&hook), materializer)
1968 {
1969 let sink_mat = sink_mat.and_then(|mat| {
1970 mat.downcast::<SinkMat>().map(|boxed| *boxed).map_err(|_| {
1971 StreamError::Failed(
1972 "terminal fast path: unexpected mat type (internal error)".into(),
1973 )
1974 })
1975 })?;
1976 return Ok(combine(source_mat, sink_mat));
1977 }
1978 if !fold_fp.supports_terminal_drain() {
1979 let (stream, source_mat) = Arc::clone(&factory).create(materializer)?;
1980 let sink_mat = sink.run_from_source(stream, materializer, hints.runtime())?;
1981 return Ok(combine(source_mat, sink_mat));
1982 }
1983 let sink_mat = fold_fp
1984 .try_register_terminal_drain(hook, materializer)
1985 .expect("terminal drain support advertised")
1986 .and_then(|mat| {
1987 mat.downcast::<SinkMat>().map(|boxed| *boxed).map_err(|_| {
1988 StreamError::Failed(
1989 "terminal fast path: unexpected mat type (internal error)".into(),
1990 )
1991 })
1992 })?;
1993 return Ok(combine(source_mat, sink_mat));
1994 }
1995 let (stream, source_mat) = Arc::clone(&factory).create(materializer)?;
1996 let sink_mat = if hints.inline_head_terminal && sink.can_inline() {
1997 let stream =
1998 runtime_checked_stream(stream, Arc::clone(&materializer.inner.state), None);
1999 sink.run_inline(stream, materializer)?
2000 } else {
2001 sink.run_from_source(stream, materializer, hints.runtime())?
2002 };
2003 Ok(combine(source_mat, sink_mat))
2004 })
2005 }
2006
2007 pub fn run_collect(self) -> StreamResult<Vec<Out>> {
2008 self.run_with(Sink::collect())?.wait()
2009 }
2010
2011 pub fn run_fold<Acc, F>(self, zero: Acc, f: F) -> StreamResult<StreamCompletion<Acc>>
2012 where
2013 Acc: Clone + Send + Sync + 'static,
2014 F: Fn(Acc, Out) -> Acc + Send + Sync + 'static,
2015 {
2016 self.run_with(Sink::fold(zero, f))
2017 }
2018
2019 pub fn run_foreach<F>(self, f: F) -> StreamResult<StreamCompletion<NotUsed>>
2020 where
2021 F: Fn(Out) + Send + Sync + 'static,
2022 {
2023 self.run_with(Sink::foreach(f))
2024 }
2025
2026 pub fn run_for_each<F>(self, f: F) -> StreamResult<StreamCompletion<NotUsed>>
2027 where
2028 F: Fn(Out) + Send + Sync + 'static,
2029 {
2030 self.run_with(Sink::foreach(f))
2031 }
2032
2033 pub fn run_reduce<F>(self, f: F) -> StreamResult<StreamCompletion<Out>>
2034 where
2035 F: Fn(Out, Out) -> Out + Send + Sync + 'static,
2036 {
2037 self.run_with(Sink::reduce(f))
2038 }
2039
2040 #[must_use]
2041 pub fn map_materialized_value<NextMat, F>(self, f: F) -> Source<Out, NextMat>
2042 where
2043 NextMat: Send + 'static,
2044 F: Fn(Mat) -> NextMat + Send + Sync + 'static,
2045 {
2046 let factory = self.factory;
2047 let terminal_factory = self.terminal_factory;
2048 let hints = self.hints;
2049 let f = Arc::new(f);
2050 let factory_f = Arc::clone(&f);
2051 let mapped_terminal_factory = terminal_factory.map(|terminal_factory| {
2052 let f = Arc::clone(&f);
2053 Arc::new(move |materializer: &Materializer| {
2054 let (hook, mat) = terminal_factory(materializer)?;
2055 Ok((hook, f(mat)))
2056 }) as Arc<TerminalSourceFactory<Out, NextMat>>
2057 });
2058 Source {
2059 factory: Arc::new(FnSourceFactory(move |materializer: &Materializer| {
2060 let (stream, mat) = Arc::clone(&factory).create(materializer)?;
2061 Ok((stream, factory_f(mat)))
2062 })),
2063 terminal_factory: mapped_terminal_factory,
2064 hints,
2065 attributes: Attributes::default(),
2066 split_hook: None,
2067 }
2068 }
2069}
2070
2071impl<Out: Clone + Send + Sync + 'static> Source<Out, NotUsed> {
2072 #[must_use]
2073 pub fn combine<Mat1, Mat2, MatRest, I>(
2074 first: Source<Out, Mat1>,
2075 second: Source<Out, Mat2>,
2076 rest: I,
2077 strategy: SourceCombineStrategy,
2078 ) -> Source<Out, NotUsed>
2079 where
2080 Mat1: Send + 'static,
2081 Mat2: Send + 'static,
2082 MatRest: Send + 'static,
2083 I: IntoIterator<Item = Source<Out, MatRest>>,
2084 {
2085 let mut factories: Vec<Arc<CombinedSourceFactory<Out>>> = vec![
2086 Arc::new(move |materializer| {
2087 Arc::clone(&first.factory)
2088 .create(materializer)
2089 .map(|(stream, _)| stream)
2090 }),
2091 Arc::new(move |materializer| {
2092 Arc::clone(&second.factory)
2093 .create(materializer)
2094 .map(|(stream, _)| stream)
2095 }),
2096 ];
2097 factories.extend(rest.into_iter().map(|source| {
2098 Arc::new(move |materializer: &Materializer| {
2099 Arc::clone(&source.factory)
2100 .create(materializer)
2101 .map(|(stream, _)| stream)
2102 }) as Arc<CombinedSourceFactory<Out>>
2103 }));
2104 Source::from_materialized_factory(move |materializer| {
2105 let mut streams = Vec::with_capacity(factories.len());
2106 for factory in &factories {
2107 let stream = match factory(materializer) {
2108 Ok(stream) => stream,
2109 Err(error) => {
2110 return Ok((
2111 Box::new(std::iter::once(Err(error))) as BoxStream<Out>,
2112 NotUsed,
2113 ));
2114 }
2115 };
2116 streams.push(stream);
2117 }
2118 let stream = match &strategy {
2119 SourceCombineStrategy::Merge { eager_complete } => {
2120 merge_streams(streams, *eager_complete)
2121 }
2122 SourceCombineStrategy::Concat => concat_source_streams(streams),
2123 SourceCombineStrategy::Prioritized {
2124 priorities,
2125 eager_complete,
2126 } => {
2127 if priorities.len() != streams.len() {
2128 return Err(StreamError::GraphValidation(format!(
2129 "combine priorities length {} did not match source count {}",
2130 priorities.len(),
2131 streams.len()
2132 )));
2133 }
2134 merge_prioritized_streams(streams, priorities.clone(), *eager_complete)
2135 }
2136 };
2137 Ok((stream, NotUsed))
2138 })
2139 }
2140
2141 #[must_use]
2142 pub fn zip_n<Mat2, I>(sources: I) -> Source<Vec<Out>, NotUsed>
2143 where
2144 I: IntoIterator<Item = Source<Out, Mat2>>,
2145 Mat2: Send + 'static,
2146 Out: Clone,
2147 {
2148 Self::zip_with_n(sources, |values| values)
2149 }
2150
2151 #[must_use]
2152 pub fn zip_with_n<Mat2, I, Next, F>(sources: I, zipper: F) -> Source<Next, NotUsed>
2153 where
2154 I: IntoIterator<Item = Source<Out, Mat2>>,
2155 Mat2: Send + 'static,
2156 Next: Send + 'static,
2157 F: Fn(Vec<Out>) -> Next + Send + Sync + 'static,
2158 {
2159 let factories: Vec<_> = sources.into_iter().map(|source| source.factory).collect();
2160 let zipper = Arc::new(zipper);
2161 Source::from_materialized_factory(move |materializer| {
2162 let mut streams = Vec::with_capacity(factories.len());
2163 for factory in &factories {
2164 let stream = match Arc::clone(factory).create(materializer) {
2165 Ok((stream, _)) => stream,
2166 Err(error) => {
2167 return Ok((
2168 Box::new(std::iter::once(Err(error))) as BoxStream<Next>,
2169 NotUsed,
2170 ));
2171 }
2172 };
2173 streams.push(stream);
2174 }
2175 Ok((zip_n_streams(streams, Arc::clone(&zipper)), NotUsed))
2176 })
2177 }
2178
2179 #[must_use]
2180 pub fn merge_prioritized_n<Mat2, I>(
2181 sources_and_priorities: I,
2182 eager_complete: bool,
2183 ) -> Source<Out, NotUsed>
2184 where
2185 I: IntoIterator<Item = (Source<Out, Mat2>, usize)>,
2186 Mat2: Send + 'static,
2187 {
2188 let sources_and_priorities: Vec<_> = sources_and_priorities.into_iter().collect();
2189 if sources_and_priorities.is_empty() {
2190 return Source::empty();
2191 }
2192 let (factories, priorities): (Vec<_>, Vec<_>) = sources_and_priorities
2193 .into_iter()
2194 .map(|(source, priority)| (source.factory, priority))
2195 .unzip();
2196 Source::from_materialized_factory(move |materializer| {
2197 let mut streams = Vec::with_capacity(factories.len());
2198 for factory in &factories {
2199 let stream = match Arc::clone(factory).create(materializer) {
2200 Ok((stream, _)) => stream,
2201 Err(error) => {
2202 return Ok((
2203 Box::new(std::iter::once(Err(error))) as BoxStream<Out>,
2204 NotUsed,
2205 ));
2206 }
2207 };
2208 streams.push(stream);
2209 }
2210 Ok((
2211 merge_prioritized_streams(streams, priorities.clone(), eager_complete),
2212 NotUsed,
2213 ))
2214 })
2215 }
2216
2217 #[must_use]
2218 pub fn maybe() -> (MaybeHandle<Out>, Self) {
2219 let value = Arc::new(Mutex::new(None));
2220 let handle = MaybeHandle {
2221 value: Arc::clone(&value),
2222 };
2223 let source = Self::from_factory(move || {
2224 let result = value
2225 .lock()
2226 .expect("maybe source poisoned")
2227 .clone()
2228 .unwrap_or(Err(StreamError::MaybeIncomplete));
2229 Box::new(std::iter::once(result))
2230 });
2231 (handle, source)
2232 }
2233
2234 #[must_use]
2235 pub fn single(item: Out) -> Self {
2236 Self::from_factory_with_hints(
2237 move || Box::new(std::iter::once(Ok(item.clone()))),
2238 SourceHints::with_inline_micro(1),
2239 )
2240 }
2241
2242 #[must_use]
2243 pub fn repeat(item: Out) -> Self {
2244 Self::from_factory(move || {
2245 let item = item.clone();
2246 Box::new(std::iter::repeat_with(move || Ok(item.clone())))
2247 })
2248 }
2249
2250 #[must_use]
2251 pub fn from_iterable<I>(items: I) -> Self
2252 where
2253 I: IntoIterator<Item = Out>,
2254 {
2255 items.into_iter().collect()
2256 }
2257}
2258
2259impl<Out: Clone + Send + Sync + 'static> FromIterator<Out> for Source<Out, NotUsed> {
2260 fn from_iter<T: IntoIterator<Item = Out>>(iter: T) -> Self {
2261 let items: Arc<[Out]> = iter.into_iter().collect();
2264 let len = items.len();
2265 Self::from_factory_with_hints(
2266 move || {
2267 let items = Arc::clone(&items);
2268 let mut index = 0;
2269 Box::new(std::iter::from_fn(move || {
2270 let item = items.get(index)?.clone();
2271 index += 1;
2272 Some(Ok(item))
2273 }))
2274 },
2275 SourceHints::with_inline_micro(len),
2277 )
2278 }
2279}
2280
2281impl<Out: Clone + Send + Sync + 'static> From<Vec<Out>> for Source<Out, NotUsed> {
2282 fn from(items: Vec<Out>) -> Self {
2283 Source::from_iter(items)
2284 }
2285}
2286
2287impl<Out: Clone + Send + Sync + 'static, const N: usize> From<[Out; N]> for Source<Out, NotUsed> {
2288 fn from(items: [Out; N]) -> Self {
2289 Source::from_iter(items)
2290 }
2291}
2292
2293pub trait IntoSource: IntoIterator + Sized {
2323 #[must_use]
2324 fn into_source(self) -> Source<Self::Item, NotUsed>
2325 where
2326 Self::Item: Clone + Send + Sync + 'static,
2327 {
2328 Source::from_iter(self)
2329 }
2330}
2331
2332impl<I> IntoSource for I where I: IntoIterator {}
2333
2334#[cfg(test)]
2339pub(in crate::stream) fn test_source_with_inline_micro_hint<Out: Send + 'static>(
2340 factory: impl Fn() -> BoxStream<Out> + Send + Sync + 'static,
2341 max_success_items: usize,
2342) -> Source<Out, NotUsed> {
2343 Source::from_factory_with_hints(factory, SourceHints::with_inline_micro(max_success_items))
2344}
2345
2346struct UnfoldResourceStream<Resource, Out, Create, Read, Close>
2347where
2348 Create: Fn() -> StreamResult<Resource>,
2349 Read: Fn(&mut Resource) -> StreamResult<Option<Out>>,
2350 Close: Fn(Resource) -> StreamResult<()>,
2351{
2352 create: Arc<Create>,
2353 read: Arc<Read>,
2354 close: Arc<Close>,
2355 resource: Option<Resource>,
2356 created: bool,
2357 terminated: bool,
2358 _marker: PhantomData<fn() -> Out>,
2359}
2360
2361impl<Resource, Out, Create, Read, Close> UnfoldResourceStream<Resource, Out, Create, Read, Close>
2362where
2363 Create: Fn() -> StreamResult<Resource>,
2364 Read: Fn(&mut Resource) -> StreamResult<Option<Out>>,
2365 Close: Fn(Resource) -> StreamResult<()>,
2366{
2367 fn ensure_created(&mut self) -> StreamResult<()> {
2368 if self.created {
2369 return Ok(());
2370 }
2371 self.created = true;
2372 let resource = catch_unwind_failed("unfold_resource create", || (self.create)())
2373 .and_then(|result| result)?;
2374 self.resource = Some(resource);
2375 Ok(())
2376 }
2377
2378 fn close_resource(&mut self) -> StreamResult<()> {
2379 match self.resource.take() {
2380 Some(resource) => {
2381 catch_unwind_failed("unfold_resource close", || (self.close)(resource))
2382 .and_then(|result| result)
2383 }
2384 None => Ok(()),
2385 }
2386 }
2387}
2388
2389impl<Resource, Out, Create, Read, Close> Iterator
2390 for UnfoldResourceStream<Resource, Out, Create, Read, Close>
2391where
2392 Create: Fn() -> StreamResult<Resource>,
2393 Read: Fn(&mut Resource) -> StreamResult<Option<Out>>,
2394 Close: Fn(Resource) -> StreamResult<()>,
2395{
2396 type Item = StreamResult<Out>;
2397
2398 fn next(&mut self) -> Option<Self::Item> {
2399 if self.terminated {
2400 return None;
2401 }
2402 if let Err(error) = self.ensure_created() {
2403 self.terminated = true;
2404 return Some(Err(error));
2405 }
2406
2407 let result = {
2408 let resource = self
2409 .resource
2410 .as_mut()
2411 .expect("unfold_resource resource is open");
2412 catch_unwind_failed("unfold_resource read", || (self.read)(resource))
2413 .and_then(|result| result)
2414 };
2415
2416 match result {
2417 Ok(Some(item)) => Some(Ok(item)),
2418 Ok(None) => {
2419 self.terminated = true;
2420 match self.close_resource() {
2421 Ok(()) => None,
2422 Err(error) => Some(Err(error)),
2423 }
2424 }
2425 Err(read_error) => {
2426 self.terminated = true;
2427 let _ = self.close_resource();
2428 Some(Err(read_error))
2429 }
2430 }
2431 }
2432}
2433
2434impl<Resource, Out, Create, Read, Close> Drop
2435 for UnfoldResourceStream<Resource, Out, Create, Read, Close>
2436where
2437 Create: Fn() -> StreamResult<Resource>,
2438 Read: Fn(&mut Resource) -> StreamResult<Option<Out>>,
2439 Close: Fn(Resource) -> StreamResult<()>,
2440{
2441 fn drop(&mut self) {
2442 let _ = self.close_resource();
2443 }
2444}
2445
2446type UnfoldResourceAsyncMarker<Out, CreateFut, ReadFut, CloseFut> =
2447 fn() -> (Out, CreateFut, ReadFut, CloseFut);
2448
2449struct UnfoldResourceAsyncStream<Resource, Out, Create, CreateFut, Read, ReadFut, Close, CloseFut>
2450where
2451 Resource: Send + 'static,
2452 Create: Fn() -> CreateFut,
2453 CreateFut: Future<Output = StreamResult<Resource>> + Send + 'static,
2454 Read: Fn(&mut Resource) -> ReadFut,
2455 ReadFut: Future<Output = StreamResult<Option<Out>>> + Send + 'static,
2456 Close: Fn(Resource) -> CloseFut,
2457 CloseFut: Future<Output = StreamResult<()>> + Send + 'static,
2458{
2459 create: Arc<Create>,
2460 read: Arc<Read>,
2461 close: Arc<Close>,
2462 resource: Option<Resource>,
2463 created: bool,
2464 terminated: bool,
2465 _marker: PhantomData<UnfoldResourceAsyncMarker<Out, CreateFut, ReadFut, CloseFut>>,
2466}
2467
2468impl<Resource, Out, Create, CreateFut, Read, ReadFut, Close, CloseFut>
2469 UnfoldResourceAsyncStream<Resource, Out, Create, CreateFut, Read, ReadFut, Close, CloseFut>
2470where
2471 Resource: Send + 'static,
2472 Create: Fn() -> CreateFut,
2473 CreateFut: Future<Output = StreamResult<Resource>> + Send + 'static,
2474 Read: Fn(&mut Resource) -> ReadFut,
2475 ReadFut: Future<Output = StreamResult<Option<Out>>> + Send + 'static,
2476 Close: Fn(Resource) -> CloseFut,
2477 CloseFut: Future<Output = StreamResult<()>> + Send + 'static,
2478{
2479 fn ensure_created(&mut self) -> StreamResult<()> {
2480 if self.created {
2481 return Ok(());
2482 }
2483 self.created = true;
2484 let resource = catch_unwind_failed("unfold_resource_async create", || (self.create)())
2485 .and_then(flow::run_future_inline_or_spawn)?;
2486 self.resource = Some(resource);
2487 Ok(())
2488 }
2489
2490 fn close_resource(&mut self) -> StreamResult<()> {
2491 match self.resource.take() {
2492 Some(resource) => {
2493 catch_unwind_failed("unfold_resource_async close", || (self.close)(resource))
2494 .and_then(flow::run_future_inline_or_spawn)
2495 }
2496 None => Ok(()),
2497 }
2498 }
2499}
2500
2501impl<Resource, Out, Create, CreateFut, Read, ReadFut, Close, CloseFut> Iterator
2502 for UnfoldResourceAsyncStream<Resource, Out, Create, CreateFut, Read, ReadFut, Close, CloseFut>
2503where
2504 Resource: Send + 'static,
2505 Out: Send + 'static,
2506 Create: Fn() -> CreateFut,
2507 CreateFut: Future<Output = StreamResult<Resource>> + Send + 'static,
2508 Read: Fn(&mut Resource) -> ReadFut,
2509 ReadFut: Future<Output = StreamResult<Option<Out>>> + Send + 'static,
2510 Close: Fn(Resource) -> CloseFut,
2511 CloseFut: Future<Output = StreamResult<()>> + Send + 'static,
2512{
2513 type Item = StreamResult<Out>;
2514
2515 fn next(&mut self) -> Option<Self::Item> {
2516 if self.terminated {
2517 return None;
2518 }
2519 if let Err(error) = self.ensure_created() {
2520 self.terminated = true;
2521 return Some(Err(error));
2522 }
2523
2524 let result = {
2525 let resource = self
2526 .resource
2527 .as_mut()
2528 .expect("unfold_resource_async resource is open");
2529 catch_unwind_failed("unfold_resource_async read", || (self.read)(resource))
2530 .and_then(flow::run_future_inline_or_spawn)
2531 };
2532
2533 match result {
2534 Ok(Some(item)) => Some(Ok(item)),
2535 Ok(None) => {
2536 self.terminated = true;
2537 match self.close_resource() {
2538 Ok(()) => None,
2539 Err(error) => Some(Err(error)),
2540 }
2541 }
2542 Err(read_error) => {
2543 self.terminated = true;
2544 let _ = self.close_resource();
2545 Some(Err(read_error))
2546 }
2547 }
2548 }
2549}
2550
2551impl<Resource, Out, Create, CreateFut, Read, ReadFut, Close, CloseFut> Drop
2552 for UnfoldResourceAsyncStream<Resource, Out, Create, CreateFut, Read, ReadFut, Close, CloseFut>
2553where
2554 Resource: Send + 'static,
2555 Create: Fn() -> CreateFut,
2556 CreateFut: Future<Output = StreamResult<Resource>> + Send + 'static,
2557 Read: Fn(&mut Resource) -> ReadFut,
2558 ReadFut: Future<Output = StreamResult<Option<Out>>> + Send + 'static,
2559 Close: Fn(Resource) -> CloseFut,
2560 CloseFut: Future<Output = StreamResult<()>> + Send + 'static,
2561{
2562 fn drop(&mut self) {
2563 let _ = self.close_resource();
2564 }
2565}
2566
2567struct LazySourceStream<Out, InnerMat, F> {
2568 create: Arc<F>,
2569 materializer: Materializer,
2570 current: Option<BoxStream<Out>>,
2571 mat_sender: Option<oneshot::Sender<StreamResult<InnerMat>>>,
2572 initialized: bool,
2573 terminated: bool,
2574}
2575
2576impl<Out, InnerMat, F> LazySourceStream<Out, InnerMat, F>
2577where
2578 Out: Send + 'static,
2579 InnerMat: Send + 'static,
2580 F: Fn() -> Source<Out, InnerMat>,
2581{
2582 fn complete_mat(&mut self, result: StreamResult<InnerMat>) {
2583 if let Some(sender) = self.mat_sender.take() {
2584 let _ = sender.send(result);
2585 }
2586 }
2587
2588 fn initialize(&mut self) -> StreamResult<()> {
2589 if self.initialized {
2590 return Ok(());
2591 }
2592 self.initialized = true;
2593 let source = match catch_unwind_failed("lazy_source factory", || (self.create)()) {
2594 Ok(source) => source,
2595 Err(error) => {
2596 self.complete_mat(Err(error.clone()));
2597 return Err(error);
2598 }
2599 };
2600 match Arc::clone(&source.factory).create(&self.materializer) {
2601 Ok((stream, mat)) => {
2602 self.current = Some(stream);
2603 self.complete_mat(Ok(mat));
2604 Ok(())
2605 }
2606 Err(error) => {
2607 self.complete_mat(Err(error.clone()));
2608 Err(error)
2609 }
2610 }
2611 }
2612}
2613
2614impl<Out, InnerMat, F> Iterator for LazySourceStream<Out, InnerMat, F>
2615where
2616 Out: Send + 'static,
2617 InnerMat: Send + 'static,
2618 F: Fn() -> Source<Out, InnerMat>,
2619{
2620 type Item = StreamResult<Out>;
2621
2622 fn next(&mut self) -> Option<Self::Item> {
2623 if self.terminated {
2624 return None;
2625 }
2626 if let Err(error) = self.initialize() {
2627 self.terminated = true;
2628 return Some(Err(error));
2629 }
2630 match self
2631 .current
2632 .as_mut()
2633 .expect("lazy_source current stream initialized")
2634 .next()
2635 {
2636 Some(Ok(item)) => Some(Ok(item)),
2637 Some(Err(error)) => {
2638 self.terminated = true;
2639 Some(Err(error))
2640 }
2641 None => {
2642 self.terminated = true;
2643 None
2644 }
2645 }
2646 }
2647}
2648
2649impl<Out, InnerMat, F> Drop for LazySourceStream<Out, InnerMat, F> {
2650 fn drop(&mut self) {
2651 if !self.initialized
2652 && let Some(sender) = self.mat_sender.take()
2653 {
2654 let _ = sender.send(Err(StreamError::Failed(
2655 "lazy source was never materialized".into(),
2656 )));
2657 }
2658 }
2659}
2660
2661struct LazyFutureSourceStream<Out, InnerMat, F, Fut> {
2662 create: Arc<F>,
2663 materializer: Materializer,
2664 current: Option<BoxStream<Out>>,
2665 mat_sender: Option<oneshot::Sender<StreamResult<InnerMat>>>,
2666 initialized: bool,
2667 terminated: bool,
2668 _marker: PhantomData<fn() -> Fut>,
2669}
2670
2671impl<Out, InnerMat, F, Fut> LazyFutureSourceStream<Out, InnerMat, F, Fut>
2672where
2673 Out: Send + 'static,
2674 InnerMat: Send + 'static,
2675 F: Fn() -> Fut,
2676 Fut: Future<Output = StreamResult<Source<Out, InnerMat>>> + Send + 'static,
2677{
2678 fn complete_mat(&mut self, result: StreamResult<InnerMat>) {
2679 if let Some(sender) = self.mat_sender.take() {
2680 let _ = sender.send(result);
2681 }
2682 }
2683
2684 fn initialize(&mut self) -> StreamResult<()> {
2685 if self.initialized {
2686 return Ok(());
2687 }
2688 self.initialized = true;
2689 let source = match catch_unwind_failed("lazy_future_source factory", || (self.create)())
2690 .and_then(flow::run_future_inline_or_spawn)
2691 {
2692 Ok(source) => source,
2693 Err(error) => {
2694 self.complete_mat(Err(error.clone()));
2695 return Err(error);
2696 }
2697 };
2698 match Arc::clone(&source.factory).create(&self.materializer) {
2699 Ok((stream, mat)) => {
2700 self.current = Some(stream);
2701 self.complete_mat(Ok(mat));
2702 Ok(())
2703 }
2704 Err(error) => {
2705 self.complete_mat(Err(error.clone()));
2706 Err(error)
2707 }
2708 }
2709 }
2710}
2711
2712impl<Out, InnerMat, F, Fut> Iterator for LazyFutureSourceStream<Out, InnerMat, F, Fut>
2713where
2714 Out: Send + 'static,
2715 InnerMat: Send + 'static,
2716 F: Fn() -> Fut,
2717 Fut: Future<Output = StreamResult<Source<Out, InnerMat>>> + Send + 'static,
2718{
2719 type Item = StreamResult<Out>;
2720
2721 fn next(&mut self) -> Option<Self::Item> {
2722 if self.terminated {
2723 return None;
2724 }
2725 if let Err(error) = self.initialize() {
2726 self.terminated = true;
2727 return Some(Err(error));
2728 }
2729 match self
2730 .current
2731 .as_mut()
2732 .expect("lazy_future_source current stream initialized")
2733 .next()
2734 {
2735 Some(Ok(item)) => Some(Ok(item)),
2736 Some(Err(error)) => {
2737 self.terminated = true;
2738 Some(Err(error))
2739 }
2740 None => {
2741 self.terminated = true;
2742 None
2743 }
2744 }
2745 }
2746}
2747
2748impl<Out, InnerMat, F, Fut> Drop for LazyFutureSourceStream<Out, InnerMat, F, Fut> {
2749 fn drop(&mut self) {
2750 if !self.initialized
2751 && let Some(sender) = self.mat_sender.take()
2752 {
2753 let _ = sender.send(Err(StreamError::Failed(
2754 "lazy future source was never materialized".into(),
2755 )));
2756 }
2757 }
2758}
2759
2760fn concat_source_streams<Out>(streams: Vec<BoxStream<Out>>) -> BoxStream<Out>
2761where
2762 Out: Send + 'static,
2763{
2764 let mut streams: VecDeque<_> = streams.into();
2765 let mut current = streams.pop_front();
2766 Box::new(std::iter::from_fn(move || {
2767 loop {
2768 match current.as_mut() {
2769 Some(stream) => match stream.next() {
2770 Some(item) => return Some(item),
2771 None => current = streams.pop_front(),
2772 },
2773 None => return None,
2774 }
2775 }
2776 }))
2777}
2778
2779fn concat_source_streams_lazy<Out, Mat>(
2780 initial: BoxStream<Out>,
2781 factories: Vec<Arc<dyn SourceFactory<Out, Mat>>>,
2782 materializer: &Materializer,
2783) -> BoxStream<Out>
2784where
2785 Out: Send + 'static,
2786 Mat: Send + 'static,
2787{
2788 let mut current = Some(initial);
2789 let mut remaining: VecDeque<_> = factories.into();
2790 let materializer = materializer.with_name_prefix(materializer.name_prefix().to_owned());
2791 Box::new(std::iter::from_fn(move || {
2792 loop {
2793 match current.as_mut() {
2794 Some(stream) => match stream.next() {
2795 Some(item) => return Some(item),
2796 None => {
2797 current = remaining.pop_front().map(|factory| {
2798 match factory.create(&materializer) {
2799 Ok((stream, _)) => stream,
2800 Err(error) => {
2801 Box::new(std::iter::once(Err(error))) as BoxStream<Out>
2802 }
2803 }
2804 });
2805 }
2806 },
2807 None => return None,
2808 }
2809 }
2810 }))
2811}
2812
2813fn or_else_source_stream<Out>(
2814 mut primary: BoxStream<Out>,
2815 mut secondary: BoxStream<Out>,
2816) -> BoxStream<Out>
2817where
2818 Out: Send + 'static,
2819{
2820 let mut primary_emitted = false;
2821 let mut using_secondary = false;
2822 Box::new(std::iter::from_fn(move || {
2823 loop {
2824 if using_secondary {
2825 return secondary.next();
2826 }
2827
2828 match primary.next() {
2829 Some(Ok(item)) => {
2830 primary_emitted = true;
2831 return Some(Ok(item));
2832 }
2833 Some(Err(error)) => return Some(Err(error)),
2834 None if primary_emitted => return None,
2835 None => using_secondary = true,
2836 }
2837 }
2838 }))
2839}
2840
2841fn interleave_source_streams<Out>(
2842 streams: Vec<BoxStream<Out>>,
2843 segment_size: usize,
2844 eager_close: bool,
2845) -> BoxStream<Out>
2846where
2847 Out: Send + 'static,
2848{
2849 if segment_size == 0 {
2850 return Box::new(std::iter::once(Err(StreamError::GraphValidation(
2851 "interleave segment size must be greater than zero".into(),
2852 ))));
2853 }
2854
2855 let mut streams: Vec<Option<BoxStream<Out>>> = streams.into_iter().map(Some).collect();
2856 let mut pending: Vec<Option<StreamResult<Out>>> = (0..streams.len()).map(|_| None).collect();
2857 let mut current = 0usize;
2858 let mut emitted = 0usize;
2859 Box::new(std::iter::from_fn(move || {
2860 loop {
2861 if streams.iter().all(Option::is_none) {
2862 return None;
2863 }
2864 if streams[current].is_none() {
2865 match next_active_source_stream(&streams, current) {
2866 Some(next) => {
2867 current = next;
2868 emitted = 0;
2869 }
2870 None => return None,
2871 }
2872 }
2873
2874 let Some(stream) = streams[current].as_mut() else {
2875 continue;
2876 };
2877 let next_item = pending[current].take().or_else(|| stream.next());
2878 match next_item {
2879 Some(Ok(item)) => {
2880 emitted += 1;
2881 if emitted == segment_size {
2882 emitted = 0;
2883 if let Some(next) = next_active_source_stream(&streams, current) {
2884 current = next;
2885 }
2886 }
2887 return Some(Ok(item));
2888 }
2889 Some(Err(error)) => return Some(Err(error)),
2890 None => {
2891 streams[current] = None;
2892 emitted = 0;
2893 if eager_close {
2894 return None;
2895 }
2896 match next_active_source_stream(&streams, current) {
2897 Some(next) => current = next,
2898 None => return None,
2899 }
2900 }
2901 }
2902 }
2903 }))
2904}
2905
2906fn next_active_source_stream<Out>(
2907 streams: &[Option<BoxStream<Out>>],
2908 current: usize,
2909) -> Option<usize>
2910where
2911 Out: Send + 'static,
2912{
2913 if streams.is_empty() {
2914 return None;
2915 }
2916 for offset in 1..=streams.len() {
2917 let index = (current + offset) % streams.len();
2918 if streams[index].is_some() {
2919 return Some(index);
2920 }
2921 }
2922 None
2923}