Skip to main content

orx_parallel/extendable/
par_extend.rs

1use crate::extendable::ParExtendCore;
2use crate::{Par, ParOption, ParResult};
3
4/// Extends an existing collection with items produced by a parallel iterator.
5pub trait ParExtend<T>: ParExtendCore<T> {
6    /// Collects items from `iter` into this collection.
7    ///
8    /// # Examples
9    ///
10    /// ```
11    /// use orx_parallel::{IntoParIter, Par, ParExtend};
12    /// use std::collections::BTreeSet;
13    ///
14    /// let mut values = vec![0];
15    /// values.par_extend((1..=4).into_par());
16    /// assert_eq!(values, vec![0, 1, 2, 3, 4]);
17    ///
18    /// let mut values = BTreeSet::from([0]);
19    /// values.par_extend((1..=4).into_par());
20    /// assert_eq!(values, BTreeSet::from([0, 1, 2, 3, 4]));
21    /// ```
22    fn par_extend(&mut self, iter: impl Par<Item = T>)
23    where
24        T: Send;
25
26    /// Extends this collection with values from an optional parallel iterator.
27    ///
28    /// Returns `Some(())` when the iterator completes, or `None` when it encounters `None`.
29    /// Values produced before the stop condition remain in the collection.
30    ///
31    /// # Examples
32    ///
33    /// ```
34    /// use orx_parallel::{IntoParIter, Par, ParExtend};
35    ///
36    /// let mut values = vec![0];
37    /// let result = (1..=4).into_par().map(Some).into_optional();
38    /// assert_eq!(values.par_extend_optional(result), Some(()));
39    /// assert_eq!(values, vec![0, 1, 2, 3, 4]);
40    ///
41    /// let mut values = vec![0];
42    /// let result = (1..=4)
43    ///     .into_par()
44    ///     .map(|value| (value < 3).then_some(value))
45    ///     .into_optional();
46    /// assert_eq!(values.par_extend_optional(result), None);
47    /// ```
48    fn par_extend_optional(&mut self, iter: impl ParOption<Elem = T>) -> Option<()>
49    where
50        T: Send;
51
52    /// Extends this collection with values from a fallible parallel iterator.
53    ///
54    /// Returns `Ok(())` when the iterator completes, or the first error reported by the iterator.
55    /// Values produced before the error remain in the collection.
56    ///
57    /// # Examples
58    ///
59    /// ```
60    /// use orx_parallel::{IntoParIter, Par, ParExtend};
61    ///
62    /// let mut values = vec![0];
63    /// let result = (1..=4)
64    ///     .into_par()
65    ///     .map(Result::<_, &str>::Ok)
66    ///     .into_fallible();
67    /// assert_eq!(values.par_extend_fallible(result), Ok(()));
68    /// assert_eq!(values, vec![0, 1, 2, 3, 4]);
69    ///
70    /// let mut values = vec![0];
71    /// let result = (1..=4)
72    ///     .into_par()
73    ///     .map(|value| if value < 3 { Ok(value) } else { Err("stopped") })
74    ///     .into_fallible();
75    /// assert_eq!(values.par_extend_fallible(result), Err("stopped"));
76    /// ```
77    fn par_extend_fallible<I>(&mut self, iter: I) -> Result<(), I::Error>
78    where
79        I: ParResult<Elem = T>,
80        I::Error: Send,
81        T: Send;
82}
83
84impl<T, P: ParExtendCore<T>> ParExtend<T> for P {
85    fn par_extend(&mut self, iter: impl Par<Item = T>)
86    where
87        T: Send,
88    {
89        iter.collect_into(self);
90    }
91
92    fn par_extend_optional(&mut self, iter: impl ParOption<Elem = T>) -> Option<()>
93    where
94        T: Send,
95    {
96        iter.collect_into(self)
97    }
98
99    fn par_extend_fallible<I>(&mut self, iter: I) -> Result<(), I::Error>
100    where
101        I: ParResult<Elem = T>,
102        I::Error: Send,
103        T: Send,
104    {
105        iter.collect_into(self)
106    }
107}