Skip to main content

ParOption

Trait ParOption 

Source
pub trait ParOption: Sized + ParOptionCore {
Show 36 methods // Required methods fn runner<Q: ParRunner>( self, runner: Q, ) -> impl ParOption<Elem = Self::Elem, Xap1 = Self::Xap1, M = Self::M, Xap2 = Self::Xap2, Input = Self::Input, Size = Self::Size>; fn runner_with_diagnostics( self, ) -> impl ParOption<Elem = Self::Elem, Xap1 = Self::Xap1, M = Self::M, Xap2 = Self::Xap2, Input = Self::Input, Size = Self::Size>; fn num_threads(self, num_threads: impl Into<NumThreads>) -> Self; fn chunk_size(self, chunk_size: impl Into<ChunkSize>) -> Self; fn iteration_order(self, collect: IterationOrder) -> Self; fn map<Q, H>( self, h: H, ) -> impl ParOption<Elem = Q, Xap1 = Self::Xap1, M = Self::M, Xap2 = MapOf<Self::Xap2, Q, H>, Input = Self::Input, Size = Self::Size> where H: Fn(Self::Elem) -> Q + Copy + Send; fn inspect<H>( self, h: H, ) -> impl ParOption<Elem = Self::Elem, Xap1 = Self::Xap1, M = Self::M, Xap2 = InsOf<Self::Xap2, H>, Input = Self::Input, Size = Self::Size> where H: Fn(&Self::Elem) + Copy + Send; fn filter<H>( self, h: H, ) -> impl ParOption<Elem = Self::Elem, Xap1 = Self::Xap1, M = Self::M, Xap2 = FilOf<Self::Xap2, H>, Input = Self::Input, Size = <Self::Size as SizePair>::ThenBin> where H: Fn(&Self::Elem) -> bool + Copy + Send; fn filter_map<Q, H>( self, h: H, ) -> impl ParOption<Elem = Q, Xap1 = Self::Xap1, M = Self::M, Xap2 = FilMapOf<Self::Xap2, Q, H>, Input = Self::Input, Size = <Self::Size as SizePair>::ThenBin> where H: Fn(Self::Elem) -> Option<Q> + Copy + Send; fn flat_map<V, H>( self, h: H, ) -> impl ParOption<Elem = V::Item, Xap1 = Self::Xap1, M = Self::M, Xap2 = FlatMapOf<Self::Xap2, V, H>, Input = Self::Input, Size = <Self::Size as SizePair>::ThenMany> where V: IntoIterator, H: Fn(Self::Elem) -> V + Copy + Send; fn flatten( self, ) -> impl ParOption<Elem = <Self::Elem as IntoIterator>::Item, Xap1 = Self::Xap1, M = Self::M, Xap2 = FlattenOf<Self::Xap2>, Input = Self::Input, Size = <Self::Size as SizePair>::ThenMany> where Self::Elem: IntoIterator; fn size_hint(&self) -> (usize, Option<usize>); fn first(self) -> Option<Option<Self::Elem>> where Self::Elem: Send; fn reduce<F>(self, f: F) -> Option<Option<Self::Elem>> where F: Fn(Self::Elem, Self::Elem) -> Self::Elem + Send + Copy, Self::Elem: Send; fn collect_into<P>(self, dst: &mut P) -> Option<()> where P: ParExtend<Self::Elem>, Self::Elem: Send; // Provided methods fn use_new<U, F>( self, f: F, ) -> impl ParUseOption<Elem = Self::Elem, Use = U, Xap1 = IdUse<Self::Xap1, U>, M = Self::M, Xap2 = IdUse<Self::Xap2, U>, Input = Self::Input, Size = Self::Size> where U: Send, F: Fn(usize) -> U + Sync { ... } fn use_vec<U, F>( self, use_vec: &mut UseVec<U, F>, ) -> impl ParUseOption<Elem = Self::Elem, Use = U, Xap1 = IdUse<Self::Xap1, U>, M = Self::M, Xap2 = IdUse<Self::Xap2, U>, Input = Self::Input, Size = Self::Size> where U: Send, F: Fn(usize) -> U + Sync { ... } fn use_slice<'a, U>( self, slice: &'a mut [U], ) -> impl ParUseOption<Elem = Self::Elem, Use = U, Xap1 = IdUse<Self::Xap1, U>, M = Self::M, Xap2 = IdUse<Self::Xap2, U>, Input = Self::Input, Size = Self::Size> where U: Send + 'a { ... } fn copied<'a, O>( self, ) -> impl ParOption<Elem = O, Xap1 = Self::Xap1, M = Self::M, Xap2 = MappedOf<Self::Xap2, FnCopied<'a, O>>, Input = Self::Input, Size = Self::Size> where Self: ParOption<Elem = &'a O>, O: Copy + 'a { ... } fn cloned<'a, O>( self, ) -> impl ParOption<Elem = O, Xap1 = Self::Xap1, M = Self::M, Xap2 = MappedOf<Self::Xap2, FnCloned<'a, O>>, Input = Self::Input, Size = Self::Size> where Self: ParOption<Elem = &'a O>, O: Clone + 'a { ... } fn len(&self) -> usize where Self::Input: ExactSizeConcurrentIter, Self: ParOption<Size = OneOne> { ... } fn is_empty(&self) -> bool where Self::Input: ExactSizeConcurrentIter, Self: ParOption<Size = OneOne> { ... } fn collect<P>(self) -> Option<P> where P: ParExtend<Self::Elem> + Default, Self::Elem: Send { ... } fn all<F>(self, f: F) -> Option<bool> where Self::Elem: Send, F: Fn(&Self::Elem) -> bool + Sync { ... } fn any<F>(self, f: F) -> Option<bool> where Self::Elem: Send, F: Fn(&Self::Elem) -> bool + Sync { ... } fn count(self) -> Option<usize> { ... } fn find<F>(self, f: F) -> Option<Option<Self::Elem>> where Self::Elem: Send, F: Fn(&Self::Elem) -> bool + Sync { ... } fn fold<B, I, F>(self, init: I, f: F) -> Option<Vec<B>> where B: Send, I: Fn() -> B + Sync, F: Fn(&mut B, Self::Elem) + Copy + Send { ... } fn for_each<F>(self, f: F) -> Option<()> where F: Fn(Self::Elem) + Send + Copy { ... } fn max(self) -> Option<Option<Self::Elem>> where Self::Elem: Ord + Send { ... } fn max_by<F>(self, f: F) -> Option<Option<Self::Elem>> where Self::Elem: Send, F: Fn(&Self::Elem, &Self::Elem) -> Ordering + Sync { ... } fn max_by_key<B, F>(self, f: F) -> Option<Option<Self::Elem>> where Self::Elem: Send, B: Ord, F: Fn(&Self::Elem) -> B + Sync { ... } fn min(self) -> Option<Option<Self::Elem>> where Self::Elem: Ord + Send { ... } fn min_by<F>(self, f: F) -> Option<Option<Self::Elem>> where Self::Elem: Send, F: Fn(&Self::Elem, &Self::Elem) -> Ordering + Sync { ... } fn min_by_key<B, F>(self, f: F) -> Option<Option<Self::Elem>> where Self::Elem: Send, B: Ord, F: Fn(&Self::Elem) -> B + Sync { ... } fn sum<S>(self) -> Option<S> where Self::Elem: Sum<S>, S: Send { ... }
}
Expand description

Fallible parallel iterator over Option values.

ParOption represents pipelines where each element may fail as None. It is commonly created from Par with into_optional.

Conceptually, this is similar to using the ? operator in Rust: both let you write logic on the success path while failures short-circuit. In ParOption, the success path works with plain T values (instead of Option<T>), and the parallel computation stops immediately when any element evaluates to None.

Related traits:

  • Par for infallible pipelines,
  • ParUseOption for the same fallibility model with worker-local state.

§Examples

Parse and validate incoming records in parallel. If any record is invalid, the pipeline short-circuits to None.

use orx_parallel::*;

let records = ["3", "8", "21", "34"];

let validated: Option<Vec<usize>> = records
    .into_par()
    .map(|s| s.parse::<usize>().ok())
    .into_optional()
    .map(|x| x * 2)
    .filter(|x| *x <= 70)
    .collect();

assert_eq!(validated, Some(vec![6, 16, 42, 68]));

let with_failure: Option<Vec<usize>> = ["3", "bad", "21", "34"]
    .into_par()
    .map(|s| s.parse::<usize>().ok())
    .into_optional()
    .map(|x| x * 2)
    .collect();

assert_eq!(with_failure, None);

Required Methods§

Source

fn runner<Q: ParRunner>( self, runner: Q, ) -> impl ParOption<Elem = Self::Elem, Xap1 = Self::Xap1, M = Self::M, Xap2 = Self::Xap2, Input = Self::Input, Size = Self::Size>

Replaces the current parallel runner with runner.

§Examples
use orx_parallel::*;

let par = ["1", "2", "3"]
    .into_par()
    .map(|s| s.parse::<usize>().ok())
    .into_optional();

let par = par.runner(Runner::fixed());

let out: Option<Vec<_>> = par.collect();
assert_eq!(out, Some(vec![1, 2, 3]));
Source

fn runner_with_diagnostics( self, ) -> impl ParOption<Elem = Self::Elem, Xap1 = Self::Xap1, M = Self::M, Xap2 = Self::Xap2, Input = Self::Input, Size = Self::Size>

Wraps the current runner with diagnostics-enabled execution.

§Examples
use orx_parallel::*;

let par = ["1", "2", "3"]
    .into_par()
    .map(|s| s.parse::<usize>().ok())
    .into_optional();

#[cfg(feature = "std")]
let par = par.runner_with_diagnostics();

let out: Option<Vec<_>> = par.collect();
assert_eq!(out, Some(vec![1, 2, 3]));
Source

fn num_threads(self, num_threads: impl Into<NumThreads>) -> Self

Sets the maximum number of worker threads for this computation.

This method configures the computation layer of the thread count decision. The actual number of threads used is determined by combining:

  1. Pool constraint (from pool() method or default pool)
    • Already includes ORX_NUM_THREADS environment variable constraint
  2. Computation constraint (this method)
    • Your per-computation thread preference
  3. Input size constraint
    • Cannot spawn more threads than input elements

The actual thread count is the minimum of all these constraints.

§Parameter Interpretation
  • 0 → NumThreads::Auto (use all available threads, spawn only as needed)
  • n > 0 → NumThreads::Max(n) (cap at n threads)
§Thread Count Decision Logic
available = pool.max_num_threads()      // Pool maximum (includes env variable)

requested = match num_threads {
    0 | Auto => input_size.max(1),      // Limited by input size
    Max(n) => min(input_size, n),       // Limited by input size and this param
};

actual_threads = min(requested, available)
§Examples
ⓘ
use orx_parallel::*;
use std::num::NonZeroUsize;

// Auto: uses all available threads (respects ORX_NUM_THREADS)
let out: Option<Vec<_>> = ["1", "2", "3"]
    .into_par()
    .map(|s| s.parse::<usize>().ok())
    .into_optional()
    .num_threads(NumThreads::Auto)
    .collect();
assert_eq!(out, Some(vec![1, 2, 3]));

// Sequential execution (1 thread, no parallelism)
let out: Option<Vec<_>> = ["1", "2", "3"]
    .into_par()
    .map(|s| s.parse::<usize>().ok())
    .into_optional()
    .num_threads(1)  // Sequential
    .collect();
assert_eq!(out, Some(vec![1, 2, 3]));

// Cap at 4 threads
let out: Option<Vec<_>> = (0..1000)
    .into_par()
    .map(Some)
    .into_optional()
    .num_threads(4)  // Use at most 4 threads
    .collect();
assert_eq!(out.as_ref().map(|v| v.len()), Some(1000));

// With environment constraint: ORX_NUM_THREADS=2
let out: Option<Vec<_>> = (0..1000)
    .into_par()
    .map(Some)
    .into_optional()
    .num_threads(4)  // Request 4, but env limits to 2
    .collect();      // Result: 2 threads used
§See Also
Source

fn chunk_size(self, chunk_size: impl Into<ChunkSize>) -> Self

Sets chunk size used when pulling items from the concurrent input.

Integer values map as follows:

  • 0 => automatic (default)
  • n > 0 => exact chunk size n
§Examples
use orx_parallel::*;

let out: Option<Vec<_>> = ["1", "2", "3", "4"]
    .into_par()
    .map(|s| s.parse::<usize>().ok())
    .into_optional()
    .chunk_size(2)
    .collect();

assert_eq!(out, Some(vec![1, 2, 3, 4]));
Source

fn iteration_order(self, collect: IterationOrder) -> Self

Sets iteration-order semantics for order-sensitive operations.

§Examples
use orx_parallel::*;

let ordered = (1..10_000)
    .into_par()
    .map(|x| Some(x))
    .into_optional()
    .iteration_order(IterationOrder::Ordered)
    .find(|x| x % 3421 == 0);
assert_eq!(ordered, Some(Some(3421)));

let any = (1..10_000)
    .into_par()
    .map(|x| Some(x))
    .into_optional()
    .iteration_order(IterationOrder::Arbitrary)
    .find(|x| x % 3421 == 0)
    .unwrap()
    .unwrap();
assert!([3421, 6842].contains(&any));
Source

fn map<Q, H>( self, h: H, ) -> impl ParOption<Elem = Q, Xap1 = Self::Xap1, M = Self::M, Xap2 = MapOf<Self::Xap2, Q, H>, Input = Self::Input, Size = Self::Size>
where H: Fn(Self::Elem) -> Q + Copy + Send,

Maps each successful element with closure h.

§Examples
use orx_parallel::*;

let out: Option<Vec<_>> = (1..4).into_par().map(Some).into_optional().map(|x| 2 * x).collect();
assert_eq!(out, Some(vec![2, 4, 6]));
Source

fn inspect<H>( self, h: H, ) -> impl ParOption<Elem = Self::Elem, Xap1 = Self::Xap1, M = Self::M, Xap2 = InsOf<Self::Xap2, H>, Input = Self::Input, Size = Self::Size>
where H: Fn(&Self::Elem) + Copy + Send,

Runs h on each successful element and forwards the element unchanged.

§Examples
use core::sync::atomic::{AtomicUsize, Ordering};
use orx_parallel::*;

let seen = AtomicUsize::new(0);
let out: Option<Vec<_>> = (1..5)
    .into_par()
    .map(Some)
    .into_optional()
    .inspect(|_| {
        seen.fetch_add(1, Ordering::Relaxed);
    })
    .collect();

assert_eq!(out, Some(vec![1, 2, 3, 4]));
assert_eq!(seen.load(Ordering::Relaxed), 4);
Source

fn filter<H>( self, h: H, ) -> impl ParOption<Elem = Self::Elem, Xap1 = Self::Xap1, M = Self::M, Xap2 = FilOf<Self::Xap2, H>, Input = Self::Input, Size = <Self::Size as SizePair>::ThenBin>
where H: Fn(&Self::Elem) -> bool + Copy + Send,

Keeps successful elements satisfying predicate h.

§Examples
use orx_parallel::*;

let out: Option<Vec<_>> = (1..7)
    .into_par()
    .map(Some)
    .into_optional()
    .filter(|x| x % 2 == 1)
    .collect();

assert_eq!(out, Some(vec![1, 3, 5]));
Source

fn filter_map<Q, H>( self, h: H, ) -> impl ParOption<Elem = Q, Xap1 = Self::Xap1, M = Self::M, Xap2 = FilMapOf<Self::Xap2, Q, H>, Input = Self::Input, Size = <Self::Size as SizePair>::ThenBin>
where H: Fn(Self::Elem) -> Option<Q> + Copy + Send,

Maps and filters successful elements in a single pass.

§Examples
use orx_parallel::*;

let out: Option<Vec<_>> = ["1", "x", "5"]
    .into_par()
    .map(|s| Some(s))
    .into_optional()
    .filter_map(|s| s.parse::<usize>().ok())
    .collect();

assert_eq!(out, Some(vec![1, 5]));
Source

fn flat_map<V, H>( self, h: H, ) -> impl ParOption<Elem = V::Item, Xap1 = Self::Xap1, M = Self::M, Xap2 = FlatMapOf<Self::Xap2, V, H>, Input = Self::Input, Size = <Self::Size as SizePair>::ThenMany>
where V: IntoIterator, H: Fn(Self::Elem) -> V + Copy + Send,

Maps each successful element to an iterator and flattens one level.

§Examples
use orx_parallel::*;

let out: Option<Vec<_>> = (1..4)
    .into_par()
    .map(Some)
    .into_optional()
    .flat_map(|x| [x, x + 10])
    .collect();

assert_eq!(out, Some(vec![1, 11, 2, 12, 3, 13]));
Source

fn flatten( self, ) -> impl ParOption<Elem = <Self::Elem as IntoIterator>::Item, Xap1 = Self::Xap1, M = Self::M, Xap2 = FlattenOf<Self::Xap2>, Input = Self::Input, Size = <Self::Size as SizePair>::ThenMany>
where Self::Elem: IntoIterator,

Flattens one level of nested iterables on the success path.

§Examples
use orx_parallel::*;

let nested = vec![vec![1, 2], vec![3, 4]];
let out: Option<Vec<_>> = nested.into_par().map(Some).into_optional().flatten().collect();

assert_eq!(out, Some(vec![1, 2, 3, 4]));
Source

fn size_hint(&self) -> (usize, Option<usize>)

Returns a lower and optional upper bound on the number of successful output items.

The bounds follow the usual Iterator::size_hint convention. The upper bound includes items that may be removed by filtering or short-circuiting.

§Examples
use orx_parallel::*;

let values = (0..4)
    .into_par()
    .map(Some)
    .into_optional()
    .filter(|x| x % 2 == 0);

assert_eq!(values.size_hint(), (0, Some(4)));
Source

fn first(self) -> Option<Option<Self::Elem>>
where Self::Elem: Send,

Returns the first successful item according to iteration order.

Returns:

  • None if computation short-circuits due to a failure (None element)
  • Some(None) if no successful element exists
  • Some(Some(x)) for the first successful element
§Examples
use orx_parallel::*;

assert_eq!((1..4).into_par().map(Some).into_optional().first(), Some(Some(1)));
assert_eq!(Vec::<usize>::new().into_par().map(Some).into_optional().first(), Some(None));
assert_eq!(vec![None, Some(1), Some(3)].into_par().into_optional().first(), None);
Source

fn reduce<F>(self, f: F) -> Option<Option<Self::Elem>>
where F: Fn(Self::Elem, Self::Elem) -> Self::Elem + Send + Copy, Self::Elem: Send,

Reduces successful items into one value using f.

Returns:

  • None if computation short-circuits due to a failure
  • Some(None) if there is no successful value to reduce
  • Some(Some(x)) for the reduced value
§Examples
use orx_parallel::*;

let ok = (1..6).into_par().map(Some).into_optional().reduce(|a, b| a + b);
assert_eq!(ok, Some(Some(15)));

let fail = vec![Some(1), None, Some(3)].into_par().into_optional().reduce(|a, b| a + b);
assert_eq!(fail, None);
Source

fn collect_into<P>(self, dst: &mut P) -> Option<()>
where P: ParExtend<Self::Elem>, Self::Elem: Send,

Collects successful items into dst.

Returns None if any element fails, Some(()) otherwise.

§Examples
use orx_parallel::*;

let mut dst = vec![10usize];
let ok = (0..3).into_par().map(Some).into_optional().collect_into(&mut dst);
assert_eq!(ok, Some(()));
assert_eq!(dst, vec![10, 0, 1, 2]);

let mut dst_fail = vec![];
let fail = vec![Some(1usize), None, Some(3)]
    .into_par()
    .into_optional()
    .collect_into(&mut dst_fail);
assert_eq!(fail, None);

Provided Methods§

Source

fn use_new<U, F>( self, f: F, ) -> impl ParUseOption<Elem = Self::Elem, Use = U, Xap1 = IdUse<Self::Xap1, U>, M = Self::M, Xap2 = IdUse<Self::Xap2, U>, Input = Self::Input, Size = Self::Size>
where U: Send, F: Fn(usize) -> U + Sync,

Creates one mutable Use value per participating worker.

§Examples
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;

let out: Option<Vec<_>> = (0..8usize)
    .into_par()
    .map(Some)
    .into_optional()
    .use_new(|thread_idx| ChaCha8Rng::seed_from_u64(10 + thread_idx as u64))
    .map(|rng, x| x + rng.random_range(0..10))
    .collect();

assert_eq!(out.as_ref().map(Vec::len), Some(8));
Source

fn use_vec<U, F>( self, use_vec: &mut UseVec<U, F>, ) -> impl ParUseOption<Elem = Self::Elem, Use = U, Xap1 = IdUse<Self::Xap1, U>, M = Self::M, Xap2 = IdUse<Self::Xap2, U>, Input = Self::Input, Size = Self::Size>
where U: Send, F: Fn(usize) -> U + Sync,

Uses an externally-owned UseVec as worker-local state.

§Examples
use orx_parallel::*;

let mut sums = UseVec::new(|_| 0usize);

let result = (1..11)
    .into_par()
    .map(Some)
    .into_optional()
    .use_vec(&mut sums)
    .for_each(|local, x| *local += x);

assert_eq!(result, Some(()));
assert_eq!(sums.into_vec().into_iter().sum::<usize>(), 55);
Source

fn use_slice<'a, U>( self, slice: &'a mut [U], ) -> impl ParUseOption<Elem = Self::Elem, Use = U, Xap1 = IdUse<Self::Xap1, U>, M = Self::M, Xap2 = IdUse<Self::Xap2, U>, Input = Self::Input, Size = Self::Size>
where U: Send + 'a,

Uses a caller-provided mutable slice as worker-local mutable state.

§Examples
use orx_parallel::*;

let mut sums = vec![0usize; 4];
let result = (1..11)
    .into_par()
    .map(Some)
    .into_optional()
    .use_slice(&mut sums)
    .for_each(|local, x| *local += x);

assert_eq!(result, Some(()));
assert_eq!(sums.into_iter().sum::<usize>(), 55);
§Panics

Panics if the input produces at least one element but slice is empty.

Source

fn copied<'a, O>( self, ) -> impl ParOption<Elem = O, Xap1 = Self::Xap1, M = Self::M, Xap2 = MappedOf<Self::Xap2, FnCopied<'a, O>>, Input = Self::Input, Size = Self::Size>
where Self: ParOption<Elem = &'a O>, O: Copy + 'a,

Copies elements of a reference iterator.

Equivalent to .map(|x| *x) on the success path.

§Examples
use orx_parallel::*;

let data = vec![1, 2, 3];
let copied: Option<Vec<_>> = data.par().map(Some).into_optional().copied().collect();

assert_eq!(copied, Some(vec![1, 2, 3]));
Source

fn cloned<'a, O>( self, ) -> impl ParOption<Elem = O, Xap1 = Self::Xap1, M = Self::M, Xap2 = MappedOf<Self::Xap2, FnCloned<'a, O>>, Input = Self::Input, Size = Self::Size>
where Self: ParOption<Elem = &'a O>, O: Clone + 'a,

Clones elements of a reference iterator.

§Examples
use orx_parallel::*;

let data = vec!["a".to_string(), "b".to_string()];
let cloned: Option<Vec<_>> = data.par().map(Some).into_optional().cloned().collect();

assert_eq!(cloned, Some(vec!["a".to_string(), "b".to_string()]));
Source

fn len(&self) -> usize
where Self::Input: ExactSizeConcurrentIter, Self: ParOption<Size = OneOne>,

Returns the exact number of output items.

Source

fn is_empty(&self) -> bool
where Self::Input: ExactSizeConcurrentIter, Self: ParOption<Size = OneOne>,

Returns true when the parallel iterator has no output items.

Source

fn collect<P>(self) -> Option<P>
where P: ParExtend<Self::Elem> + Default, Self::Elem: Send,

Collects successful items into a new collection.

Returns None if any element fails, otherwise Some(collection).

§Examples
use orx_parallel::*;

let ok: Option<Vec<_>> = (1..4).into_par().map(Some).into_optional().collect();
assert_eq!(ok, Some(vec![1, 2, 3]));

let fail: Option<Vec<_>> = vec![Some(1), None, Some(3)].into_par().into_optional().collect();
assert_eq!(fail, None);
Source

fn all<F>(self, f: F) -> Option<bool>
where Self::Elem: Send, F: Fn(&Self::Elem) -> bool + Sync,

Returns Some(true) if all successful items satisfy f.

Returns None on short-circuit failure.

§Examples
use orx_parallel::*;

assert_eq!((1..5).into_par().map(Some).into_optional().all(|x| x > &0), Some(true));
assert_eq!((1..5).into_par().map(Some).into_optional().all(|x| x % 2 == 0), Some(false));
assert_eq!(vec![Some(1), None, Some(3)].into_par().into_optional().all(|x| x > &0), None);
Source

fn any<F>(self, f: F) -> Option<bool>
where Self::Elem: Send, F: Fn(&Self::Elem) -> bool + Sync,

Returns Some(true) if any successful item satisfies f.

Returns None on short-circuit failure.

§Examples
use orx_parallel::*;

assert_eq!((1..5).into_par().map(Some).into_optional().any(|x| x % 2 == 0), Some(true));
assert_eq!((1..5).into_par().map(Some).into_optional().any(|x| x > &10), Some(false));
assert_eq!(vec![Some(1), None, Some(3)].into_par().into_optional().any(|x| x % 2 == 0), None);
Source

fn count(self) -> Option<usize>

Counts successful elements.

Returns None on short-circuit failure.

§Examples
use orx_parallel::*;

let ok = (1..11)
    .into_par()
    .map(Some)
    .into_optional()
    .filter(|x| x % 3 == 0)
    .count();
assert_eq!(ok, Some(3));

let fail = vec![Some(1usize), None, Some(3)].into_par().into_optional().count();
assert_eq!(fail, None);
Source

fn find<F>(self, f: F) -> Option<Option<Self::Elem>>
where Self::Elem: Send, F: Fn(&Self::Elem) -> bool + Sync,

Finds first (ordered) or any (arbitrary) successful item satisfying f.

Equivalent to self.filter(f).first().

§Examples
use orx_parallel::*;

let found = (1..101)
    .into_par()
    .map(Some)
    .into_optional()
    .find(|x| x % 17 == 0);
assert_eq!(found, Some(Some(17)));

let fail = vec![Some(1usize), None, Some(34)].into_par().into_optional().find(|x| x % 17 == 0);
assert_eq!(fail, None);
Source

fn fold<B, I, F>(self, init: I, f: F) -> Option<Vec<B>>
where B: Send, I: Fn() -> B + Sync, F: Fn(&mut B, Self::Elem) + Copy + Send,

Folds successful elements into per-thread accumulators.

Returns None on short-circuit failure.

§Examples
use orx_parallel::*;

let partials = (1..6)
    .into_par()
    .map(Some)
    .into_optional()
    .fold(|| 0usize, |acc, x| *acc += x);
assert_eq!(partials.as_ref().map(|v| v.iter().sum::<usize>()), Some(15));

let fail = vec![Some(1usize), None, Some(3)]
    .into_par()
    .into_optional()
    .fold(|| 0usize, |acc, x| *acc += x);
assert_eq!(fail, None);
Source

fn for_each<F>(self, f: F) -> Option<()>
where F: Fn(Self::Elem) + Send + Copy,

Executes f for each successful element.

Returns None on short-circuit failure.

§Examples
use core::sync::atomic::{AtomicUsize, Ordering};
use orx_parallel::*;

let total = AtomicUsize::new(0);
let ok = (1..5)
    .into_par()
    .map(Some)
    .into_optional()
    .for_each(|x| {
        total.fetch_add(x, Ordering::Relaxed);
    });

assert_eq!(ok, Some(()));
assert_eq!(total.load(Ordering::Relaxed), 10);
Source

fn max(self) -> Option<Option<Self::Elem>>
where Self::Elem: Ord + Send,

Returns maximum successful element.

Returns None on short-circuit failure.

§Examples
use orx_parallel::*;

assert_eq!((1..5).into_par().map(Some).into_optional().max(), Some(Some(4)));
assert_eq!(Vec::<usize>::new().into_par().map(Some).into_optional().max(), Some(None));
assert_eq!(vec![Some(1usize), None, Some(3)].into_par().into_optional().max(), None);
Source

fn max_by<F>(self, f: F) -> Option<Option<Self::Elem>>
where Self::Elem: Send, F: Fn(&Self::Elem, &Self::Elem) -> Ordering + Sync,

Returns successful element considered maximum by comparator f.

Returns None on short-circuit failure.

§Examples
use orx_parallel::*;

let x = vec![-3_i32, 0, 1, 5, -10]
    .into_par()
    .map(Some)
    .into_optional()
    .max_by(|a, b| a.cmp(b));
assert_eq!(x, Some(Some(5)));
Source

fn max_by_key<B, F>(self, f: F) -> Option<Option<Self::Elem>>
where Self::Elem: Send, B: Ord, F: Fn(&Self::Elem) -> B + Sync,

Returns successful element with maximum key value.

Returns None on short-circuit failure.

§Examples
use orx_parallel::*;

let x = vec![-3_i32, 0, 1, 5, -10]
    .into_par()
    .map(Some)
    .into_optional()
    .max_by_key(|x| x.abs());
assert_eq!(x, Some(Some(-10)));
Source

fn min(self) -> Option<Option<Self::Elem>>
where Self::Elem: Ord + Send,

Returns minimum successful element.

Returns None on short-circuit failure.

§Examples
use orx_parallel::*;

assert_eq!((1..5).into_par().map(Some).into_optional().min(), Some(Some(1)));
assert_eq!(Vec::<usize>::new().into_par().map(Some).into_optional().min(), Some(None));
assert_eq!(vec![Some(1usize), None, Some(3)].into_par().into_optional().min(), None);
Source

fn min_by<F>(self, f: F) -> Option<Option<Self::Elem>>
where Self::Elem: Send, F: Fn(&Self::Elem, &Self::Elem) -> Ordering + Sync,

Returns successful element considered minimum by comparator f.

Returns None on short-circuit failure.

§Examples
use orx_parallel::*;

let x = vec![-3_i32, 0, 1, 5, -10]
    .into_par()
    .map(Some)
    .into_optional()
    .min_by(|a, b| a.cmp(b));
assert_eq!(x, Some(Some(-10)));
Source

fn min_by_key<B, F>(self, f: F) -> Option<Option<Self::Elem>>
where Self::Elem: Send, B: Ord, F: Fn(&Self::Elem) -> B + Sync,

Returns successful element with minimum key value.

Returns None on short-circuit failure.

§Examples
use orx_parallel::*;

let x = vec![-3_i32, 0, 1, 5, -10]
    .into_par()
    .map(Some)
    .into_optional()
    .min_by_key(|x| x.abs());
assert_eq!(x, Some(Some(0)));
Source

fn sum<S>(self) -> Option<S>
where Self::Elem: Sum<S>, S: Send,

Sums successful elements using Sum implementation.

Returns None on short-circuit failure.

§Examples
use orx_parallel::*;

let ok: Option<usize> = (1..5).into_par().map(Some).into_optional().sum();
assert_eq!(ok, Some(10));

let fail: Option<usize> = vec![Some(1usize), None, Some(3)].into_par().into_optional().sum();
assert_eq!(fail, None);

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§