use std::sync::mpsc::channel;
use rayon::iter::ParallelIterator;
pub trait RayonConsumer {
type Item: Send;
fn consume(self, func: impl FnMut(Self::Item));
}
impl<P, I> RayonConsumer for P
where
P: ParallelIterator<Item = I>,
I: Send,
{
type Item = I;
#[cfg(not(target_family = "wasm"))]
fn consume(self, mut func: impl FnMut(Self::Item)) {
let (tx, rx) = channel::<Self::Item>();
std::thread::scope(|s| {
s.spawn(move || {
self.for_each(|item| tx.send(item).expect("should send success"));
});
while let Ok(data) = rx.recv() {
func(data);
}
});
}
#[cfg(target_family = "wasm")]
fn consume(self, mut func: impl FnMut(Self::Item)) {
let items: Vec<Self::Item> = self.collect();
for item in items {
func(item)
}
}
}
#[cfg(test)]
mod test {
use rayon::prelude::*;
use super::RayonConsumer;
#[test]
fn available() {
(0..10)
.into_par_iter()
.map(|item| item * 2)
.consume(|item| assert_eq!(item % 2, 0));
}
}