rayon/iter/
once.rs

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