Skip to main content

orx_parallel/result_use/
par.rs

1#![allow(clippy::type_complexity)]
2
3use crate::infallible_use::fun::{UFnCloned, UFnCopied};
4use crate::infallible_use::{
5    FilMapOf, FilOf, FlatMapOf, FlattenOf, InsOf, MapOf, MappedOf, XapUse,
6};
7use crate::result_use::ParUseResultIter;
8use crate::result_use::par_core::ParUseResultCore;
9use crate::runner::ParRunner;
10use crate::sizes::{OneOne, SizePair};
11use crate::{ChunkSize, IterationOrder, NumThreads, ParExtend, Sum};
12use core::cmp::Ordering;
13use orx_concurrent_iter::ExactSizeConcurrentIter;
14
15/// Fallible parallel iterator with worker-local mutable state.
16///
17/// `ParUseResult` combines:
18/// - fallible processing (`Result`-based short-circuiting), and
19/// - mutable worker-local state (`&mut Use` passed to closures).
20///
21/// You can enter this mode from [`ParResult`](crate::ParResult) via
22/// [`use_new`](crate::ParResult::use_new),
23/// [`use_vec`](crate::ParResult::use_vec), or
24/// [`use_slice`](crate::ParResult::use_slice).
25///
26/// Similar to using `?`, this trait keeps pipeline logic focused on successful
27/// values while computation short-circuits to `Err(e)` when any element fails.
28///
29/// Related traits:
30/// - [`ParResult`](crate::ParResult) for `Result`-fallible pipelines without worker-local state,
31/// - [`ParUse`](crate::ParUse) for worker-local state in infallible pipelines.
32///
33/// # Examples
34///
35/// Reusing a per-worker buffer:
36///
37/// ```
38/// use core::fmt::Write;
39/// use orx_parallel::*;
40///
41/// let out: Result<Vec<usize>, _> = ["0", "1", "2", "3", "4", "5", "6", "7"]
42///     .into_par()
43///     .map(|s| s.parse::<usize>())
44///     .into_fallible()
45///     .use_new(|_| String::with_capacity(32))
46///     .map(|buffer, x| {
47///         buffer.clear();
48///         write!(buffer, "{x}").unwrap();
49///         buffer.parse::<usize>().unwrap()
50///     })
51///     .collect();
52///
53/// assert_eq!(out, Ok((0..8).collect::<Vec<_>>()));
54/// ```
55///
56/// Using RNG as mutable worker-local state:
57///
58/// ```
59/// use orx_parallel::*;
60/// use rand::prelude::*;
61/// use rand_chacha::ChaCha8Rng;
62///
63/// let out: Result<Vec<usize>, _> = ["0", "1", "2", "3", "4", "5", "6", "7"]
64///     .into_par()
65///     .map(|s| s.parse::<usize>())
66///     .into_fallible()
67///     .use_new(|thread_idx| ChaCha8Rng::seed_from_u64(100 + thread_idx as u64))
68///     .map(|rng, x| x + rng.random_range(0..10))
69///     .collect();
70///
71/// assert_eq!(out.as_ref().map(Vec::len), Ok(8));
72/// ```
73pub trait ParUseResult: Sized + ParUseResultCore {
74    // configuration
75
76    /// Replaces the current parallel runner with `runner`.
77    ///
78    /// # Examples
79    ///
80    /// ```
81    /// use orx_parallel::*;
82    ///
83    /// let par = ["1", "2", "3"]
84    ///     .into_par()
85    ///     .map(|s| s.parse::<usize>())
86    ///     .into_fallible()
87    ///     .use_new(|_| ());
88    ///
89    /// let par = par.runner(Runner::fixed());
90    ///
91    /// let out: Result<Vec<_>, _> = par.collect();
92    /// assert_eq!(out, Ok(vec![1, 2, 3]));
93    /// ```
94    fn runner<Q: ParRunner>(
95        self,
96        runner: Q,
97    ) -> impl ParUseResult<
98        Elem = Self::Elem,
99        Error = Self::Error,
100        Use = Self::Use,
101        Xap1 = Self::Xap1,
102        M = Self::M,
103        Xap2 = Self::Xap2,
104        Input = Self::Input,
105        Size = Self::Size,
106    >;
107
108    #[cfg(feature = "std")]
109    /// Wraps the current runner with diagnostics-enabled execution.
110    ///
111    /// # Examples
112    ///
113    /// ```
114    /// use orx_parallel::*;
115    ///
116    /// let par = ["1", "2", "3"]
117    ///     .into_par()
118    ///     .map(|s| s.parse::<usize>())
119    ///     .into_fallible()
120    ///     .use_new(|_| ());
121    ///
122    /// #[cfg(feature = "std")]
123    /// let par = par.runner_with_diagnostics();
124    ///
125    /// let out: Result<Vec<_>, _> = par.collect();
126    /// assert_eq!(out, Ok(vec![1, 2, 3]));
127    /// ```
128    fn runner_with_diagnostics(
129        self,
130    ) -> impl ParUseResult<
131        Elem = Self::Elem,
132        Error = Self::Error,
133        Use = Self::Use,
134        Xap1 = Self::Xap1,
135        M = Self::M,
136        Xap2 = Self::Xap2,
137        Input = Self::Input,
138        Size = Self::Size,
139    >;
140
141    /// Sets the maximum number of worker threads for this computation.
142    ///
143    /// # Examples
144    ///
145    /// ```
146    /// use orx_parallel::*;
147    ///
148    /// let out: Result<Vec<_>, _> = ["1", "2", "3", "4", "5"]
149    ///     .into_par()
150    ///     .map(|s| s.parse::<usize>())
151    ///     .into_fallible()
152    ///     .use_new(|_| ())
153    ///     .num_threads(1)
154    ///     .collect();
155    ///
156    /// assert_eq!(out, Ok(vec![1, 2, 3, 4, 5]));
157    /// ```
158    fn num_threads(self, num_threads: impl Into<NumThreads>) -> Self;
159
160    /// Sets chunk size used when pulling items from the concurrent input.
161    ///
162    /// # Examples
163    ///
164    /// ```
165    /// use orx_parallel::*;
166    ///
167    /// let out: Result<Vec<_>, _> = ["0", "1", "2", "3", "4", "5", "6", "7"]
168    ///     .into_par()
169    ///     .map(|s| s.parse::<usize>())
170    ///     .into_fallible()
171    ///     .use_new(|_| ())
172    ///     .chunk_size(2)
173    ///     .collect();
174    ///
175    /// assert_eq!(out, Ok((0..8).collect::<Vec<_>>()));
176    /// ```
177    fn chunk_size(self, chunk_size: impl Into<ChunkSize>) -> Self;
178
179    /// Sets iteration-order semantics for order-sensitive operations.
180    ///
181    /// # Examples
182    ///
183    /// ```
184    /// use orx_parallel::*;
185    ///
186    /// let ordered = (1..10_000)
187    ///     .map(|x| x.to_string())
188    ///     .collect::<Vec<_>>()
189    ///     .into_par()
190    ///     .map(|s| s.parse::<usize>())
191    ///     .into_fallible()
192    ///     .use_new(|_| ())
193    ///     .iteration_order(IterationOrder::Ordered)
194    ///     .find(|_, x| x % 3421 == 0);
195    ///
196    /// assert_eq!(ordered, Ok(Some(3421)));
197    /// ```
198    fn iteration_order(self, collect: IterationOrder) -> Self;
199
200    // kind transformations
201
202    /// Copies elements of a reference iterator on the success path.
203    ///
204    /// # Examples
205    ///
206    /// ```
207    /// use orx_parallel::*;
208    ///
209    /// let data = vec![1, 2, 3];
210    /// let out: Result<Vec<_>, &'static str> = data
211    ///     .par()
212    ///     .map(Ok::<_, &'static str>)
213    ///     .into_fallible()
214    ///     .use_new(|_| ())
215    ///     .copied()
216    ///     .collect();
217    ///
218    /// assert_eq!(out, Ok(vec![1, 2, 3]));
219    /// ```
220    fn copied<'a, O>(
221        self,
222    ) -> impl ParUseResult<
223        Elem = O,
224        Error = Self::Error,
225        Use = Self::Use,
226        Xap1 = Self::Xap1,
227        M = Self::M,
228        Xap2 = MappedOf<Self::Xap2, UFnCopied<'a, Self::Use, O>>,
229        Input = Self::Input,
230        Size = Self::Size,
231    >
232    where
233        Self: ParUseResult<Elem = &'a O>,
234        O: Copy + 'a,
235        Self::Use: 'a,
236    {
237        let (u, iter, x1, x2, exe, _, params) = self.destruct();
238        ParUseResultIter::new(u, iter, x1, x2.mapped(UFnCopied::new()), exe, params)
239    }
240
241    /// Clones elements of a reference iterator on the success path.
242    ///
243    /// # Examples
244    ///
245    /// ```
246    /// use orx_parallel::*;
247    ///
248    /// let data = vec!["a".to_string(), "b".to_string()];
249    /// let out: Result<Vec<_>, &'static str> = data
250    ///     .par()
251    ///     .map(Ok::<_, &'static str>)
252    ///     .into_fallible()
253    ///     .use_new(|_| ())
254    ///     .cloned()
255    ///     .collect();
256    ///
257    /// assert_eq!(out, Ok(vec!["a".to_string(), "b".to_string()]));
258    /// ```
259    fn cloned<'a, O>(
260        self,
261    ) -> impl ParUseResult<
262        Elem = O,
263        Error = Self::Error,
264        Use = Self::Use,
265        Xap1 = Self::Xap1,
266        M = Self::M,
267        Xap2 = MappedOf<Self::Xap2, UFnCloned<'a, Self::Use, O>>,
268        Input = Self::Input,
269        Size = Self::Size,
270    >
271    where
272        Self: ParUseResult<Elem = &'a O>,
273        O: Clone + 'a,
274        Self::Use: 'a,
275    {
276        let (u, iter, x1, x2, exe, _, params) = self.destruct();
277        ParUseResultIter::new(u, iter, x1, x2.mapped(UFnCloned::new()), exe, params)
278    }
279
280    // transformations
281
282    /// Maps each successful element with closure `h`.
283    ///
284    /// # Examples
285    ///
286    /// ```
287    /// use orx_parallel::*;
288    ///
289    /// let out: Result<Vec<_>, _> = ["1", "2", "3"]
290    ///     .into_par()
291    ///     .map(|s| s.parse::<usize>())
292    ///     .into_fallible()
293    ///     .use_new(|_| ())
294    ///     .map(|_, x| 2 * x)
295    ///     .collect();
296    ///
297    /// assert_eq!(out, Ok(vec![2, 4, 6]));
298    /// ```
299    fn map<Q, H>(
300        self,
301        h: H,
302    ) -> impl ParUseResult<
303        Elem = Q,
304        Error = Self::Error,
305        Use = Self::Use,
306        Xap1 = Self::Xap1,
307        M = Self::M,
308        Xap2 = MapOf<Self::Xap2, Q, H>,
309        Input = Self::Input,
310        Size = Self::Size,
311    >
312    where
313        H: Fn(&mut Self::Use, Self::Elem) -> Q + Copy + Send;
314
315    /// Runs `h` on each successful element and forwards the item unchanged.
316    ///
317    /// # Examples
318    ///
319    /// ```
320    /// use orx_parallel::*;
321    ///
322    /// let mut use_vec = UseVec::new(|_| 0usize);
323    /// let out: Result<Vec<_>, _> = ["1", "2", "3", "4"]
324    ///     .into_par()
325    ///     .map(|s| s.parse::<usize>())
326    ///     .into_fallible()
327    ///     .use_vec(&mut use_vec)
328    ///     .inspect(|count, _| *count += 1)
329    ///     .collect();
330    ///
331    /// assert_eq!(out, Ok(vec![1, 2, 3, 4]));
332    /// assert_eq!(use_vec.into_vec().into_iter().sum::<usize>(), 4);
333    /// ```
334    fn inspect<H>(
335        self,
336        h: H,
337    ) -> impl ParUseResult<
338        Elem = Self::Elem,
339        Error = Self::Error,
340        Use = Self::Use,
341        Xap1 = Self::Xap1,
342        M = Self::M,
343        Xap2 = InsOf<Self::Xap2, H>,
344        Input = Self::Input,
345        Size = Self::Size,
346    >
347    where
348        H: Fn(&mut Self::Use, &Self::Elem) + Copy + Send;
349
350    /// Keeps successful elements satisfying predicate `h`.
351    ///
352    /// # Examples
353    ///
354    /// ```
355    /// use orx_parallel::*;
356    ///
357    /// let out: Result<Vec<_>, _> = ["1", "2", "3", "4", "5", "6"]
358    ///     .into_par()
359    ///     .map(|s| s.parse::<usize>())
360    ///     .into_fallible()
361    ///     .use_new(|_| ())
362    ///     .filter(|_, x| x % 2 == 1)
363    ///     .collect();
364    ///
365    /// assert_eq!(out, Ok(vec![1, 3, 5]));
366    /// ```
367    fn filter<H>(
368        self,
369        h: H,
370    ) -> impl ParUseResult<
371        Elem = Self::Elem,
372        Error = Self::Error,
373        Use = Self::Use,
374        Xap1 = Self::Xap1,
375        M = Self::M,
376        Xap2 = FilOf<Self::Xap2, H>,
377        Input = Self::Input,
378        Size = <Self::Size as SizePair>::ThenBin,
379    >
380    where
381        H: Fn(&mut Self::Use, &Self::Elem) -> bool + Copy + Send;
382
383    /// Maps and filters successful elements in one pass.
384    ///
385    /// # Examples
386    ///
387    /// ```
388    /// use orx_parallel::*;
389    ///
390    /// let out: Result<Vec<_>, _> = ["1", "x", "5"]
391    ///     .into_par()
392    ///     .map(Ok::<_, &'static str>)
393    ///     .into_fallible()
394    ///     .use_new(|_| ())
395    ///     .filter_map(|_, s| s.parse::<usize>().ok())
396    ///     .collect();
397    ///
398    /// assert_eq!(out, Ok(vec![1, 5]));
399    /// ```
400    fn filter_map<Q, H>(
401        self,
402        h: H,
403    ) -> impl ParUseResult<
404        Elem = Q,
405        Error = Self::Error,
406        Use = Self::Use,
407        Xap1 = Self::Xap1,
408        M = Self::M,
409        Xap2 = FilMapOf<Self::Xap2, Q, H>,
410        Input = Self::Input,
411        Size = <Self::Size as SizePair>::ThenBin,
412    >
413    where
414        H: Fn(&mut Self::Use, Self::Elem) -> Option<Q> + Copy + Send;
415
416    /// Maps each successful element to an iterator and flattens one level.
417    ///
418    /// # Examples
419    ///
420    /// ```
421    /// use orx_parallel::*;
422    ///
423    /// let out: Result<Vec<_>, _> = ["1", "2", "3"]
424    ///     .into_par()
425    ///     .map(|s| s.parse::<usize>())
426    ///     .into_fallible()
427    ///     .use_new(|_| ())
428    ///     .flat_map(|_, x| [x, x + 10])
429    ///     .collect();
430    ///
431    /// assert_eq!(out, Ok(vec![1, 11, 2, 12, 3, 13]));
432    /// ```
433    fn flat_map<V, H>(
434        self,
435        h: H,
436    ) -> impl ParUseResult<
437        Elem = V::Item,
438        Error = Self::Error,
439        Use = Self::Use,
440        Xap1 = Self::Xap1,
441        M = Self::M,
442        Xap2 = FlatMapOf<Self::Xap2, V, H>,
443        Input = Self::Input,
444        Size = <Self::Size as SizePair>::ThenMany,
445    >
446    where
447        V: IntoIterator,
448        H: Fn(&mut Self::Use, Self::Elem) -> V + Copy + Send;
449
450    /// Flattens one level of nested iterables on the success path.
451    ///
452    /// # Examples
453    ///
454    /// ```
455    /// use orx_parallel::*;
456    ///
457    /// let nested = vec![vec![1, 2], vec![3, 4]];
458    /// let out: Result<Vec<_>, &'static str> = nested
459    ///     .into_par()
460    ///     .map(Ok::<_, &'static str>)
461    ///     .into_fallible()
462    ///     .use_new(|_| ())
463    ///     .flatten()
464    ///     .collect();
465    ///
466    /// assert_eq!(out, Ok(vec![1, 2, 3, 4]));
467    /// ```
468    fn flatten(
469        self,
470    ) -> impl ParUseResult<
471        Elem = <Self::Elem as IntoIterator>::Item,
472        Error = Self::Error,
473        Use = Self::Use,
474        Xap1 = Self::Xap1,
475        M = Self::M,
476        Xap2 = FlattenOf<Self::Xap2>,
477        Input = Self::Input,
478        Size = <Self::Size as SizePair>::ThenMany,
479    >
480    where
481        Self::Elem: IntoIterator;
482
483    /// Returns a lower and optional upper bound on the number of successful output items.
484    ///
485    /// The bounds follow the usual [`Iterator::size_hint`] convention.
486    /// The upper bound includes items that may be removed by filtering or short-circuiting.
487    ///
488    /// # Examples
489    ///
490    /// ```
491    /// use orx_parallel::*;
492    ///
493    /// let values = (0..4)
494    ///     .into_par()
495    ///     .map(Ok::<_, ()>)
496    ///     .into_fallible()
497    ///     .use_new(|_| ())
498    ///     .filter(|_, x| x % 2 == 0);
499    ///
500    /// assert_eq!(values.size_hint(), (0, Some(4)));
501    /// ```
502    fn size_hint(&self) -> (usize, Option<usize>);
503
504    /// Returns the exact number of output items.
505    fn len(&self) -> usize
506    where
507        Self::Input: ExactSizeConcurrentIter,
508        Self: ParUseResult<Size = OneOne>,
509    {
510        self.size_hint().0
511    }
512
513    /// Returns `true` when the parallel iterator has no output items.
514    fn is_empty(&self) -> bool
515    where
516        Self::Input: ExactSizeConcurrentIter,
517        Self: ParUseResult<Size = OneOne>,
518    {
519        self.len() == 0
520    }
521
522    // compute
523
524    /// Returns the first successful item according to iteration order.
525    ///
526    /// Returns:
527    /// - `Err(e)` if computation short-circuits due to a failure
528    /// - `Ok(None)` if no successful element exists
529    /// - `Ok(Some(x))` for the first successful element
530    ///
531    /// # Examples
532    ///
533    /// ```
534    /// use orx_parallel::*;
535    ///
536    /// let ok = ["1", "2", "3"]
537    ///     .into_par()
538    ///     .map(|s| s.parse::<usize>())
539    ///     .into_fallible()
540    ///     .use_new(|_| ())
541    ///     .first();
542    /// assert_eq!(ok, Ok(Some(1)));
543    ///
544    /// let fail = ["bad", "1", "3"]
545    ///     .into_par()
546    ///     .map(|s| s.parse::<usize>())
547    ///     .into_fallible()
548    ///     .use_new(|_| ())
549    ///     .first();
550    /// assert!(fail.is_err());
551    /// ```
552    fn first(self) -> Result<Option<Self::Elem>, Self::Error>
553    where
554        Self::Elem: Send,
555        Self::Error: Send;
556
557    /// Reduces successful items into one value using `f`.
558    ///
559    /// Returns `Err(e)` on short-circuit failure.
560    ///
561    /// # Examples
562    ///
563    /// ```
564    /// use orx_parallel::*;
565    ///
566    /// let ok = ["1", "2", "3", "4", "5"]
567    ///     .into_par()
568    ///     .map(|s| s.parse::<usize>())
569    ///     .into_fallible()
570    ///     .use_new(|_| ())
571    ///     .reduce(|_, a, b| a + b);
572    /// assert_eq!(ok, Ok(Some(15)));
573    ///
574    /// let fail = ["1", "x", "3"]
575    ///     .into_par()
576    ///     .map(|s| s.parse::<usize>().map_err(|_| "parse"))
577    ///     .into_fallible()
578    ///     .use_new(|_| ())
579    ///     .reduce(|_, a, b| a + b);
580    /// assert_eq!(fail, Err("parse"));
581    /// ```
582    fn reduce<F>(self, f: F) -> Result<Option<Self::Elem>, Self::Error>
583    where
584        F: Fn(&mut Self::Use, Self::Elem, Self::Elem) -> Self::Elem + Send + Copy,
585        Self::Elem: Send,
586        Self::Error: Send;
587
588    /// Collects successful items into `dst`.
589    ///
590    /// Returns `Err(e)` on short-circuit failure.
591    ///
592    /// # Examples
593    ///
594    /// ```
595    /// use orx_parallel::*;
596    ///
597    /// let mut dst = vec![10usize];
598    /// let ok = ["0", "1", "2"]
599    ///     .into_par()
600    ///     .map(|s| s.parse::<usize>())
601    ///     .into_fallible()
602    ///     .use_new(|_| ())
603    ///     .collect_into(&mut dst);
604    ///
605    /// assert_eq!(ok, Ok(()));
606    /// assert_eq!(dst, vec![10, 0, 1, 2]);
607    /// ```
608    fn collect_into<P>(self, dst: &mut P) -> Result<(), Self::Error>
609    where
610        P: ParExtend<Self::Elem>,
611        Self::Elem: Send,
612        Self::Error: Send;
613
614    /// Collects successful items into a new collection.
615    ///
616    /// Returns `Err(e)` on short-circuit failure.
617    ///
618    /// # Examples
619    ///
620    /// ```
621    /// use orx_parallel::*;
622    ///
623    /// let out: Result<Vec<_>, _> = ["1", "2", "3"]
624    ///     .into_par()
625    ///     .map(|s| s.parse::<usize>())
626    ///     .into_fallible()
627    ///     .use_new(|_| ())
628    ///     .collect();
629    ///
630    /// assert_eq!(out, Ok(vec![1, 2, 3]));
631    /// ```
632    fn collect<P>(self) -> Result<P, Self::Error>
633    where
634        P: ParExtend<Self::Elem> + Default,
635        Self::Elem: Send,
636        Self::Error: Send,
637    {
638        let mut dst = P::default();
639        self.collect_into(&mut dst)?;
640        Ok(dst)
641    }
642
643    // compute - derived
644
645    /// Returns `Ok(true)` if all successful items satisfy `f`.
646    ///
647    /// Returns `Err(e)` on short-circuit failure.
648    ///
649    /// # Examples
650    ///
651    /// ```
652    /// use orx_parallel::*;
653    ///
654    /// let ok = ["1", "2", "3", "4"]
655    ///     .into_par()
656    ///     .map(|s| s.parse::<usize>())
657    ///     .into_fallible()
658    ///     .use_new(|_| ())
659    ///     .all(|_, x| x > &0);
660    /// assert_eq!(ok, Ok(true));
661    /// ```
662    fn all<F>(self, f: F) -> Result<bool, Self::Error>
663    where
664        Self::Elem: Send,
665        F: Fn(&mut Self::Use, &Self::Elem) -> bool + Sync,
666        Self::Error: Send,
667    {
668        self.map(|u, x| f(u, &x))
669            .find(|_, x| !*x)
670            .map(|x| x.map(|_| false).unwrap_or(true))
671    }
672
673    /// Returns `Ok(true)` if any successful item satisfies `f`.
674    ///
675    /// Returns `Err(e)` on short-circuit failure.
676    ///
677    /// # Examples
678    ///
679    /// ```
680    /// use orx_parallel::*;
681    ///
682    /// let ok = ["1", "2", "3", "4"]
683    ///     .into_par()
684    ///     .map(|s| s.parse::<usize>())
685    ///     .into_fallible()
686    ///     .use_new(|_| ())
687    ///     .any(|_, x| x % 2 == 0);
688    /// assert_eq!(ok, Ok(true));
689    /// ```
690    fn any<F>(self, f: F) -> Result<bool, Self::Error>
691    where
692        Self::Elem: Send,
693        F: Fn(&mut Self::Use, &Self::Elem) -> bool + Sync,
694        Self::Error: Send,
695    {
696        self.map(|u, x| f(u, &x))
697            .find(|_, x| *x)
698            .map(|x| x.is_some())
699    }
700
701    /// Counts successful elements.
702    ///
703    /// Returns `Err(e)` on short-circuit failure.
704    ///
705    /// # Examples
706    ///
707    /// ```
708    /// use orx_parallel::*;
709    ///
710    /// let ok = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
711    ///     .into_par()
712    ///     .map(|s| s.parse::<usize>())
713    ///     .into_fallible()
714    ///     .use_new(|_| ())
715    ///     .filter(|_, x| x % 3 == 0)
716    ///     .count();
717    ///
718    /// assert_eq!(ok, Ok(3));
719    /// ```
720    fn count(self) -> Result<usize, Self::Error>
721    where
722        Self::Elem: Send,
723        Self::Error: Send,
724    {
725        self.map(|_, _| 1)
726            .reduce(|_, a, b| a + b)
727            .map(|x| x.unwrap_or(0))
728    }
729
730    /// Finds first (ordered) or any (arbitrary) successful item satisfying `f`.
731    ///
732    /// Returns `Err(e)` on short-circuit failure.
733    ///
734    /// # Examples
735    ///
736    /// ```
737    /// use orx_parallel::*;
738    ///
739    /// let found = (1..101)
740    ///     .map(|x| x.to_string())
741    ///     .collect::<Vec<_>>()
742    ///     .into_par()
743    ///     .map(|s| s.parse::<usize>())
744    ///     .into_fallible()
745    ///     .use_new(|_| ())
746    ///     .find(|_, x| x % 17 == 0);
747    ///
748    /// assert_eq!(found, Ok(Some(17)));
749    /// ```
750    fn find<F>(self, f: F) -> Result<Option<Self::Elem>, Self::Error>
751    where
752        Self::Elem: Send,
753        F: Fn(&mut Self::Use, &Self::Elem) -> bool + Sync,
754        Self::Error: Send,
755    {
756        self.filter(&f).first()
757    }
758
759    /// Executes `f` for each successful element.
760    ///
761    /// Returns `Err(e)` on short-circuit failure.
762    ///
763    /// # Examples
764    ///
765    /// ```
766    /// use orx_parallel::*;
767    ///
768    /// let mut sums = UseVec::new(|_| 0usize);
769    /// let result = ["1", "2", "3", "4"]
770    ///     .into_par()
771    ///     .map(|s| s.parse::<usize>())
772    ///     .into_fallible()
773    ///     .use_vec(&mut sums)
774    ///     .for_each(|local, x| *local += x);
775    ///
776    /// assert_eq!(result, Ok(()));
777    /// assert_eq!(sums.into_vec().into_iter().sum::<usize>(), 10);
778    /// ```
779    fn for_each<F>(self, f: F) -> Result<(), Self::Error>
780    where
781        F: Fn(&mut Self::Use, Self::Elem) + Send + Copy,
782        Self::Error: Send,
783    {
784        self.map(f).reduce(|_, _, _| {}).map(|_| ())
785    }
786
787    /// Returns maximum successful element.
788    ///
789    /// Returns `Err(e)` on short-circuit failure.
790    ///
791    /// # Examples
792    ///
793    /// ```
794    /// use orx_parallel::*;
795    ///
796    /// let m = ["1", "2", "3", "4"]
797    ///     .into_par()
798    ///     .map(|s| s.parse::<usize>())
799    ///     .into_fallible()
800    ///     .use_new(|_| ())
801    ///     .max();
802    ///
803    /// assert_eq!(m, Ok(Some(4)));
804    /// ```
805    fn max(self) -> Result<Option<Self::Elem>, Self::Error>
806    where
807        Self::Elem: Ord + Send,
808        Self::Error: Send,
809    {
810        self.reduce(|_, a, b| Ord::max(a, b))
811    }
812
813    /// Returns successful element considered maximum by comparator `f`.
814    ///
815    /// Returns `Err(e)` on short-circuit failure.
816    ///
817    /// # Examples
818    ///
819    /// ```
820    /// use orx_parallel::*;
821    ///
822    /// let x = vec![-3_i32, 0, 1, 5, -10]
823    ///     .into_par()
824    ///     .map(Ok::<_, &'static str>)
825    ///     .into_fallible()
826    ///     .use_new(|_| ())
827    ///     .max_by(|_, a, b| a.cmp(b));
828    ///
829    /// assert_eq!(x, Ok(Some(5)));
830    /// ```
831    fn max_by<F>(self, f: F) -> Result<Option<Self::Elem>, Self::Error>
832    where
833        Self::Elem: Send,
834        F: Fn(&mut Self::Use, &Self::Elem, &Self::Elem) -> Ordering + Sync,
835        Self::Error: Send,
836    {
837        let reduce = |u: &mut Self::Use, x, y| match f(u, &x, &y) {
838            Ordering::Greater | Ordering::Equal => x,
839            Ordering::Less => y,
840        };
841        self.reduce(reduce)
842    }
843
844    /// Returns successful element with maximum key value.
845    ///
846    /// Returns `Err(e)` on short-circuit failure.
847    ///
848    /// # Examples
849    ///
850    /// ```
851    /// use orx_parallel::*;
852    ///
853    /// let x = vec![-3_i32, 0, 1, 5, -10]
854    ///     .into_par()
855    ///     .map(Ok::<_, &'static str>)
856    ///     .into_fallible()
857    ///     .use_new(|_| ())
858    ///     .max_by_key(|_, x| x.abs());
859    ///
860    /// assert_eq!(x, Ok(Some(-10)));
861    /// ```
862    fn max_by_key<B, F>(self, f: F) -> Result<Option<Self::Elem>, Self::Error>
863    where
864        Self::Elem: Send,
865        B: Ord,
866        F: Fn(&mut Self::Use, &Self::Elem) -> B + Sync,
867        Self::Error: Send,
868    {
869        let reduce = |u: &mut Self::Use, x, y| match f(u, &x).cmp(&f(u, &y)) {
870            Ordering::Greater | Ordering::Equal => x,
871            Ordering::Less => y,
872        };
873        self.reduce(reduce)
874    }
875
876    /// Returns minimum successful element.
877    ///
878    /// Returns `Err(e)` on short-circuit failure.
879    ///
880    /// # Examples
881    ///
882    /// ```
883    /// use orx_parallel::*;
884    ///
885    /// let m = ["1", "2", "3", "4"]
886    ///     .into_par()
887    ///     .map(|s| s.parse::<usize>())
888    ///     .into_fallible()
889    ///     .use_new(|_| ())
890    ///     .min();
891    ///
892    /// assert_eq!(m, Ok(Some(1)));
893    /// ```
894    fn min(self) -> Result<Option<Self::Elem>, Self::Error>
895    where
896        Self::Elem: Ord + Send,
897        Self::Error: Send,
898    {
899        self.reduce(|_, a, b| Ord::min(a, b))
900    }
901
902    /// Returns successful element considered minimum by comparator `f`.
903    ///
904    /// Returns `Err(e)` on short-circuit failure.
905    ///
906    /// # Examples
907    ///
908    /// ```
909    /// use orx_parallel::*;
910    ///
911    /// let x = vec![-3_i32, 0, 1, 5, -10]
912    ///     .into_par()
913    ///     .map(Ok::<_, &'static str>)
914    ///     .into_fallible()
915    ///     .use_new(|_| ())
916    ///     .min_by(|_, a, b| a.cmp(b));
917    ///
918    /// assert_eq!(x, Ok(Some(-10)));
919    /// ```
920    fn min_by<F>(self, f: F) -> Result<Option<Self::Elem>, Self::Error>
921    where
922        Self::Elem: Send,
923        F: Fn(&mut Self::Use, &Self::Elem, &Self::Elem) -> Ordering + Sync,
924        Self::Error: Send,
925    {
926        let reduce = |u: &mut Self::Use, x, y| match f(u, &x, &y) {
927            Ordering::Less | Ordering::Equal => x,
928            Ordering::Greater => y,
929        };
930        self.reduce(reduce)
931    }
932
933    /// Returns successful element with minimum key value.
934    ///
935    /// Returns `Err(e)` on short-circuit failure.
936    ///
937    /// # Examples
938    ///
939    /// ```
940    /// use orx_parallel::*;
941    ///
942    /// let x = vec![-3_i32, 0, 1, 5, -10]
943    ///     .into_par()
944    ///     .map(Ok::<_, &'static str>)
945    ///     .into_fallible()
946    ///     .use_new(|_| ())
947    ///     .min_by_key(|_, x| x.abs());
948    ///
949    /// assert_eq!(x, Ok(Some(0)));
950    /// ```
951    fn min_by_key<B, F>(self, f: F) -> Result<Option<Self::Elem>, Self::Error>
952    where
953        Self::Elem: Send,
954        B: Ord,
955        F: Fn(&mut Self::Use, &Self::Elem) -> B + Sync,
956        Self::Error: Send,
957    {
958        let reduce = |u: &mut Self::Use, x, y| match f(u, &x).cmp(&f(u, &y)) {
959            Ordering::Less | Ordering::Equal => x,
960            Ordering::Greater => y,
961        };
962        self.reduce(reduce)
963    }
964
965    /// Sums successful elements using [`Sum`] implementation.
966    ///
967    /// Returns `Err(e)` on short-circuit failure.
968    ///
969    /// # Examples
970    ///
971    /// ```
972    /// use orx_parallel::*;
973    ///
974    /// let s: Result<usize, _> = ["1", "2", "3", "4"]
975    ///     .into_par()
976    ///     .map(|s| s.parse::<usize>())
977    ///     .into_fallible()
978    ///     .use_new(|_| ())
979    ///     .sum();
980    ///
981    /// assert_eq!(s, Ok(10));
982    /// ```
983    fn sum<S>(self) -> Result<S, Self::Error>
984    where
985        Self::Elem: Sum<S>,
986        S: Send,
987        Self::Error: Send,
988    {
989        self.map(|_, x| Self::Elem::owned(x))
990            .reduce(|_, a, b| Self::Elem::add(a, b))
991            .map(|x| x.unwrap_or(Self::Elem::zero()))
992    }
993}