amadeus_core/par_stream/
flat_map_sync.rs1use derive_new::new;
2use pin_project::pin_project;
3use serde::{Deserialize, Serialize};
4use serde_closure::traits::FnMut;
5use std::{
6 pin::Pin, task::{Context, Poll}
7};
8
9use super::{ParallelPipe, ParallelStream, PipeTask, StreamTask};
10
11#[pin_project]
12#[derive(new)]
13#[must_use]
14pub struct FlatMapSync<P, F> {
15 #[pin]
16 pipe: P,
17 f: F,
18}
19
20impl_par_dist! {
21 impl<P: ParallelStream, F, R: Iterator> ParallelStream for FlatMapSync<P, F>
22 where
23 F: FnMut<(P::Item,), Output = R> + Clone + Send + 'static,
24 {
25 type Item = R::Item;
26 type Task = FlatMapSyncTask<P::Task, F>;
27
28 fn size_hint(&self) -> (usize, Option<usize>) {
29 (0, None)
30 }
31 fn next_task(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Task>> {
32 let self_ = self.project();
33 let f = self_.f;
34 self_.pipe.next_task(cx).map(|task| {
35 task.map(|task| {
36 let f = f.clone();
37 FlatMapSyncTask { task, f }
38 })
39 })
40 }
41 }
42
43 impl<P: ParallelPipe<Input>, F, R: Iterator, Input> ParallelPipe<Input> for FlatMapSync<P, F>
44 where
45 F: FnMut<(P::Output,), Output = R> + Clone + Send + 'static,
46 {
47 type Output = R::Item;
48 type Task = FlatMapSyncTask<P::Task, F>;
49
50 fn task(&self) -> Self::Task {
51 let task = self.pipe.task();
52 let f = self.f.clone();
53 FlatMapSyncTask { task, f }
54 }
55 }
56}
57
58#[derive(Serialize, Deserialize)]
59pub struct FlatMapSyncTask<C, F> {
60 task: C,
61 f: F,
62}
63impl<C: StreamTask, F: FnMut<(C::Item,), Output = R> + Clone, R: Iterator> StreamTask
64 for FlatMapSyncTask<C, F>
65{
66 type Item = R::Item;
67 type Async = crate::pipe::FlatMapSync<C::Async, F, R>;
68
69 fn into_async(self) -> Self::Async {
70 crate::pipe::FlatMapSync::new(self.task.into_async(), self.f)
71 }
72}
73impl<C: PipeTask<Input>, F: FnMut<(C::Output,), Output = R> + Clone, R: Iterator, Input>
74 PipeTask<Input> for FlatMapSyncTask<C, F>
75{
76 type Output = R::Item;
77 type Async = crate::pipe::FlatMapSync<C::Async, F, R>;
78
79 fn into_async(self) -> Self::Async {
80 crate::pipe::FlatMapSync::new(self.task.into_async(), self.f)
81 }
82}