use crate::{core::Driver, Consumer, Executor, Folder, ParallelIterator, WithSetup}; use super::noop::NoOpReducer; pub struct ForEach { iterator: X, operation: O, } impl ForEach { pub fn new(iterator: X, operation: O) -> Self { Self { iterator, operation, } } } impl<'a, X, O> Driver<'a, ()> for ForEach where X: ParallelIterator<'a>, O: Fn(X::Item) + Clone + Send + 'a, { fn exec_with(self, executor: E) -> E::Result where E: Executor<'a, ()>, { let iterator = self.iterator; let operation = self.operation; let consumer = ForEachConsumer { operation }; iterator.drive(executor, consumer) } } pub struct ForEachConsumer { operation: O, } impl WithSetup for ForEachConsumer {} impl Consumer for ForEachConsumer where O: Fn(I) + Clone + Send, { type Folder = ForEachConsumer; type Reducer = NoOpReducer; type Result = (); fn split(self) -> (Self, Self, NoOpReducer) { let left = self; let right = ForEachConsumer { operation: left.operation.clone(), }; (left, right, NoOpReducer) } fn split_at(self, _index: usize) -> (Self, Self, NoOpReducer) { let left = self; let right = ForEachConsumer { operation: left.operation.clone(), }; (left, right, NoOpReducer) } fn into_folder(self) -> Self { self } } impl Folder for ForEachConsumer where O: Fn(I), { type Result = (); fn consume(self, item: I) -> Self { (self.operation)(item); self } fn consume_iter(self, iter: X) -> Self where X: IntoIterator, { iter.into_iter().for_each(&self.operation); self } fn complete(self) {} }