par_iter/iter/
once.rs

1use crate::iter::{plumbing::*, *};
2
3/// Creates a parallel iterator that produces an element exactly once.
4///
5/// This admits no parallelism on its own, but it could be chained to existing
6/// parallel iterators to extend their contents, or otherwise used for any code
7/// that deals with generic parallel iterators.
8///
9/// # Examples
10///
11/// ```
12/// use par_iter::prelude::*;
13/// use par_iter::iter::once;
14///
15/// let pi = (0..1234).into_par_iter()
16///     .chain(once(-1))
17///     .chain(1234..10_000);
18///
19/// assert_eq!(pi.clone().count(), 10_001);
20/// assert_eq!(pi.clone().filter(|&x| x < 0).count(), 1);
21/// assert_eq!(pi.position_any(|x| x < 0), Some(1234));
22/// ```
23pub fn once<T: Send>(item: T) -> Once<T> {
24    Once { item }
25}
26
27/// Iterator adaptor for [the `once()` function](fn.once.html).
28#[derive(Clone, Debug)]
29pub struct Once<T: Send> {
30    item: T,
31}
32
33impl<T: Send> ParallelIterator for Once<T> {
34    type Item = T;
35
36    fn drive_unindexed<C>(self, consumer: C) -> C::Result
37    where
38        C: UnindexedConsumer<Self::Item>,
39    {
40        self.drive(consumer)
41    }
42
43    fn opt_len(&self) -> Option<usize> {
44        Some(1)
45    }
46}
47
48impl<T: Send> IndexedParallelIterator for Once<T> {
49    fn drive<C>(self, consumer: C) -> C::Result
50    where
51        C: Consumer<Self::Item>,
52    {
53        consumer.into_folder().consume(self.item).complete()
54    }
55
56    fn len(&self) -> usize {
57        1
58    }
59
60    fn with_producer<CB>(self, callback: CB) -> CB::Output
61    where
62        CB: ProducerCallback<Self::Item>,
63    {
64        // Let `OptionProducer` handle it.
65        Some(self.item).into_par_iter().with_producer(callback)
66    }
67}