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}