Skip to main content

moirai_iter/parallel/adapters/
position.rs

1use super::super::{Consumer, ParallelIterator, VecParIter};
2
3/// Position adapter that yields logical indices for matching items.
4pub struct Positions<I, F> {
5    base: I,
6    predicate: F,
7}
8
9/// Fused map-position adapter that yields logical indices without materializing mapped items.
10pub struct MapPositions<I, MapFn, Predicate> {
11    base: I,
12    map_fn: MapFn,
13    predicate: Predicate,
14}
15
16impl<I, F> Positions<I, F> {
17    pub(in crate::parallel) fn new(base: I, predicate: F) -> Self {
18        Self { base, predicate }
19    }
20}
21
22impl<I, MapFn, Predicate> MapPositions<I, MapFn, Predicate> {
23    pub(in crate::parallel) fn new(base: I, map_fn: MapFn, predicate: Predicate) -> Self {
24        Self {
25            base,
26            map_fn,
27            predicate,
28        }
29    }
30}
31
32impl<I, F> ParallelIterator for Positions<I, F>
33where
34    I: ParallelIterator,
35    F: Fn(I::Item) -> bool + Send + Sync + Clone,
36{
37    type Item = usize;
38
39    fn seq_items(self) -> Vec<Self::Item> {
40        self.base
41            .seq_items()
42            .into_iter()
43            .enumerate()
44            .filter_map(|(index, item)| (self.predicate)(item).then_some(index))
45            .collect()
46    }
47
48    fn drive<C, R>(self, consumer: C) -> R
49    where
50        C: Consumer<Self::Item, Result = R> + Send + Sync,
51        R: Send,
52    {
53        consumer.consume(VecParIter::new(self.seq_items()))
54    }
55}
56
57impl<I, MapFn, Predicate, Mapped> ParallelIterator for MapPositions<I, MapFn, Predicate>
58where
59    I: ParallelIterator,
60    MapFn: Fn(I::Item) -> Mapped + Send + Sync + Clone,
61    Predicate: Fn(Mapped) -> bool + Send + Sync + Clone,
62    Mapped: Send,
63{
64    type Item = usize;
65
66    fn seq_items(self) -> Vec<Self::Item> {
67        let map_fn = self.map_fn;
68        let predicate = self.predicate;
69
70        self.base
71            .seq_items()
72            .into_iter()
73            .enumerate()
74            .filter_map(|(index, item)| predicate(map_fn(item)).then_some(index))
75            .collect()
76    }
77
78    fn drive<C, R>(self, consumer: C) -> R
79    where
80        C: Consumer<Self::Item, Result = R> + Send + Sync,
81        R: Send,
82    {
83        consumer.consume(VecParIter::new(self.seq_items()))
84    }
85}