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}