1 //! Parallel iterator types for [results][std::result]
2 //!
3 //! You will rarely need to interact with this module directly unless you need
4 //! to name one of the iterator types.
5 //!
6 //! [std::result]: https://doc.rust-lang.org/stable/std/result/
7 
8 use crate::iter::plumbing::*;
9 use crate::iter::*;
10 use std::sync::Mutex;
11 
12 use crate::option;
13 
14 /// Parallel iterator over a result
15 #[derive(Debug, Clone)]
16 pub struct IntoIter<T: Send> {
17     inner: option::IntoIter<T>,
18 }
19 
20 impl<T: Send, E> IntoParallelIterator for Result<T, E> {
21     type Item = T;
22     type Iter = IntoIter<T>;
23 
into_par_iter(self) -> Self::Iter24     fn into_par_iter(self) -> Self::Iter {
25         IntoIter {
26             inner: self.ok().into_par_iter(),
27         }
28     }
29 }
30 
31 delegate_indexed_iterator! {
32     IntoIter<T> => T,
33     impl<T: Send>
34 }
35 
36 /// Parallel iterator over an immutable reference to a result
37 #[derive(Debug)]
38 pub struct Iter<'a, T: Sync> {
39     inner: option::IntoIter<&'a T>,
40 }
41 
42 impl<'a, T: Sync> Clone for Iter<'a, T> {
clone(&self) -> Self43     fn clone(&self) -> Self {
44         Iter {
45             inner: self.inner.clone(),
46         }
47     }
48 }
49 
50 impl<'a, T: Sync, E> IntoParallelIterator for &'a Result<T, E> {
51     type Item = &'a T;
52     type Iter = Iter<'a, T>;
53 
into_par_iter(self) -> Self::Iter54     fn into_par_iter(self) -> Self::Iter {
55         Iter {
56             inner: self.as_ref().ok().into_par_iter(),
57         }
58     }
59 }
60 
61 delegate_indexed_iterator! {
62     Iter<'a, T> => &'a T,
63     impl<'a, T: Sync + 'a>
64 }
65 
66 /// Parallel iterator over a mutable reference to a result
67 #[derive(Debug)]
68 pub struct IterMut<'a, T: Send> {
69     inner: option::IntoIter<&'a mut T>,
70 }
71 
72 impl<'a, T: Send, E> IntoParallelIterator for &'a mut Result<T, E> {
73     type Item = &'a mut T;
74     type Iter = IterMut<'a, T>;
75 
into_par_iter(self) -> Self::Iter76     fn into_par_iter(self) -> Self::Iter {
77         IterMut {
78             inner: self.as_mut().ok().into_par_iter(),
79         }
80     }
81 }
82 
83 delegate_indexed_iterator! {
84     IterMut<'a, T> => &'a mut T,
85     impl<'a, T: Send + 'a>
86 }
87 
88 /// Collect an arbitrary `Result`-wrapped collection.
89 ///
90 /// If any item is `Err`, then all previous `Ok` items collected are
91 /// discarded, and it returns that error.  If there are multiple errors, the
92 /// one returned is not deterministic.
93 impl<C, T, E> FromParallelIterator<Result<T, E>> for Result<C, E>
94 where
95     C: FromParallelIterator<T>,
96     T: Send,
97     E: Send,
98 {
from_par_iter<I>(par_iter: I) -> Self where I: IntoParallelIterator<Item = Result<T, E>>,99     fn from_par_iter<I>(par_iter: I) -> Self
100     where
101         I: IntoParallelIterator<Item = Result<T, E>>,
102     {
103         fn ok<T, E>(saved: &Mutex<Option<E>>) -> impl Fn(Result<T, E>) -> Option<T> + '_ {
104             move |item| match item {
105                 Ok(item) => Some(item),
106                 Err(error) => {
107                     // We don't need a blocking `lock()`, as anybody
108                     // else holding the lock will also be writing
109                     // `Some(error)`, and then ours is irrelevant.
110                     if let Ok(mut guard) = saved.try_lock() {
111                         if guard.is_none() {
112                             *guard = Some(error);
113                         }
114                     }
115                     None
116                 }
117             }
118         }
119 
120         let saved_error = Mutex::new(None);
121         let collection = par_iter
122             .into_par_iter()
123             .map(ok(&saved_error))
124             .while_some()
125             .collect();
126 
127         match saved_error.into_inner().unwrap() {
128             Some(error) => Err(error),
129             None => Ok(collection),
130         }
131     }
132 }
133