1 use super::plumbing
::*;
2 use super::ParallelIterator
;
5 use std
::fmt
::{self, Debug}
;
6 use std
::marker
::PhantomData
;
7 use std
::ops
::ControlFlow
::{self, Break, Continue}
;
9 impl<U
, I
, ID
, F
> TryFold
<I
, U
, ID
, F
>
12 F
: Fn(U
::Output
, I
::Item
) -> U
+ Sync
+ Send
,
13 ID
: Fn() -> U
::Output
+ Sync
+ Send
,
16 pub(super) fn new(base
: I
, identity
: ID
, fold_op
: F
) -> Self {
26 /// `TryFold` is an iterator that applies a function over an iterator producing a single value.
27 /// This struct is created by the [`try_fold()`] method on [`ParallelIterator`]
29 /// [`try_fold()`]: trait.ParallelIterator.html#method.try_fold
30 /// [`ParallelIterator`]: trait.ParallelIterator.html
31 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
33 pub struct TryFold
<I
, U
, ID
, F
> {
37 marker
: PhantomData
<U
>,
40 impl<U
, I
: ParallelIterator
+ Debug
, ID
, F
> Debug
for TryFold
<I
, U
, ID
, F
> {
41 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
42 f
.debug_struct("TryFold").field("base", &self.base
).finish()
46 impl<U
, I
, ID
, F
> ParallelIterator
for TryFold
<I
, U
, ID
, F
>
49 F
: Fn(U
::Output
, I
::Item
) -> U
+ Sync
+ Send
,
50 ID
: Fn() -> U
::Output
+ Sync
+ Send
,
55 fn drive_unindexed
<C
>(self, consumer
: C
) -> C
::Result
57 C
: UnindexedConsumer
<Self::Item
>,
59 let consumer1
= TryFoldConsumer
{
61 identity
: &self.identity
,
62 fold_op
: &self.fold_op
,
65 self.base
.drive_unindexed(consumer1
)
69 struct TryFoldConsumer
<'c
, U
, C
, ID
, F
> {
73 marker
: PhantomData
<U
>,
76 impl<'r
, U
, T
, C
, ID
, F
> Consumer
<T
> for TryFoldConsumer
<'r
, U
, C
, ID
, F
>
79 F
: Fn(U
::Output
, T
) -> U
+ Sync
,
80 ID
: Fn() -> U
::Output
+ Sync
,
83 type Folder
= TryFoldFolder
<'r
, C
::Folder
, U
, F
>;
84 type Reducer
= C
::Reducer
;
85 type Result
= C
::Result
;
87 fn split_at(self, index
: usize) -> (Self, Self, Self::Reducer
) {
88 let (left
, right
, reducer
) = self.base
.split_at(index
);
90 TryFoldConsumer { base: left, ..self }
,
99 fn into_folder(self) -> Self::Folder
{
101 base
: self.base
.into_folder(),
102 control
: Continue((self.identity
)()),
103 fold_op
: self.fold_op
,
107 fn full(&self) -> bool
{
112 impl<'r
, U
, T
, C
, ID
, F
> UnindexedConsumer
<T
> for TryFoldConsumer
<'r
, U
, C
, ID
, F
>
114 C
: UnindexedConsumer
<U
>,
115 F
: Fn(U
::Output
, T
) -> U
+ Sync
,
116 ID
: Fn() -> U
::Output
+ Sync
,
119 fn split_off_left(&self) -> Self {
121 base
: self.base
.split_off_left(),
126 fn to_reducer(&self) -> Self::Reducer
{
127 self.base
.to_reducer()
131 struct TryFoldFolder
<'r
, C
, U
: Try
, F
> {
134 control
: ControlFlow
<U
::Residual
, U
::Output
>,
137 impl<'r
, C
, U
, F
, T
> Folder
<T
> for TryFoldFolder
<'r
, C
, U
, F
>
140 F
: Fn(U
::Output
, T
) -> U
+ Sync
,
143 type Result
= C
::Result
;
145 fn consume(mut self, item
: T
) -> Self {
146 let fold_op
= self.fold_op
;
147 if let Continue(acc
) = self.control
{
148 self.control
= fold_op(acc
, item
).branch();
153 fn complete(self) -> C
::Result
{
154 let item
= match self.control
{
155 Continue(c
) => U
::from_output(c
),
156 Break(r
) => U
::from_residual(r
),
158 self.base
.consume(item
).complete()
161 fn full(&self) -> bool
{
164 _
=> self.base
.full(),
169 // ///////////////////////////////////////////////////////////////////////////
171 impl<U
, I
, F
> TryFoldWith
<I
, U
, F
>
174 F
: Fn(U
::Output
, I
::Item
) -> U
+ Sync
,
176 U
::Output
: Clone
+ Send
,
178 pub(super) fn new(base
: I
, item
: U
::Output
, fold_op
: F
) -> Self {
187 /// `TryFoldWith` is an iterator that applies a function over an iterator producing a single value.
188 /// This struct is created by the [`try_fold_with()`] method on [`ParallelIterator`]
190 /// [`try_fold_with()`]: trait.ParallelIterator.html#method.try_fold_with
191 /// [`ParallelIterator`]: trait.ParallelIterator.html
192 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
194 pub struct TryFoldWith
<I
, U
: Try
, F
> {
200 impl<I
: ParallelIterator
+ Debug
, U
: Try
, F
> Debug
for TryFoldWith
<I
, U
, F
>
204 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
205 f
.debug_struct("TryFoldWith")
206 .field("base", &self.base
)
207 .field("item", &self.item
)
212 impl<U
, I
, F
> ParallelIterator
for TryFoldWith
<I
, U
, F
>
215 F
: Fn(U
::Output
, I
::Item
) -> U
+ Sync
+ Send
,
217 U
::Output
: Clone
+ Send
,
221 fn drive_unindexed
<C
>(self, consumer
: C
) -> C
::Result
223 C
: UnindexedConsumer
<Self::Item
>,
225 let consumer1
= TryFoldWithConsumer
{
228 fold_op
: &self.fold_op
,
230 self.base
.drive_unindexed(consumer1
)
234 struct TryFoldWithConsumer
<'c
, C
, U
: Try
, F
> {
240 impl<'r
, U
, T
, C
, F
> Consumer
<T
> for TryFoldWithConsumer
<'r
, C
, U
, F
>
243 F
: Fn(U
::Output
, T
) -> U
+ Sync
,
245 U
::Output
: Clone
+ Send
,
247 type Folder
= TryFoldFolder
<'r
, C
::Folder
, U
, F
>;
248 type Reducer
= C
::Reducer
;
249 type Result
= C
::Result
;
251 fn split_at(self, index
: usize) -> (Self, Self, Self::Reducer
) {
252 let (left
, right
, reducer
) = self.base
.split_at(index
);
254 TryFoldWithConsumer
{
256 item
: self.item
.clone(),
259 TryFoldWithConsumer
{
267 fn into_folder(self) -> Self::Folder
{
269 base
: self.base
.into_folder(),
270 control
: Continue(self.item
),
271 fold_op
: self.fold_op
,
275 fn full(&self) -> bool
{
280 impl<'r
, U
, T
, C
, F
> UnindexedConsumer
<T
> for TryFoldWithConsumer
<'r
, C
, U
, F
>
282 C
: UnindexedConsumer
<U
>,
283 F
: Fn(U
::Output
, T
) -> U
+ Sync
,
285 U
::Output
: Clone
+ Send
,
287 fn split_off_left(&self) -> Self {
288 TryFoldWithConsumer
{
289 base
: self.base
.split_off_left(),
290 item
: self.item
.clone(),
295 fn to_reducer(&self) -> Self::Reducer
{
296 self.base
.to_reducer()