1 use super::plumbing
::*;
4 use super::private
::Try
;
5 use std
::fmt
::{self, Debug}
;
6 use std
::marker
::PhantomData
;
8 impl<U
, I
, ID
, F
> TryFold
<I
, U
, ID
, F
>
11 F
: Fn(U
::Ok
, I
::Item
) -> U
+ Sync
+ Send
,
12 ID
: Fn() -> U
::Ok
+ Sync
+ Send
,
15 pub(super) fn new(base
: I
, identity
: ID
, fold_op
: F
) -> Self {
25 /// `TryFold` is an iterator that applies a function over an iterator producing a single value.
26 /// This struct is created by the [`try_fold()`] method on [`ParallelIterator`]
28 /// [`try_fold()`]: trait.ParallelIterator.html#method.try_fold
29 /// [`ParallelIterator`]: trait.ParallelIterator.html
30 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
32 pub struct TryFold
<I
, U
, ID
, F
> {
36 marker
: PhantomData
<U
>,
39 impl<U
, I
: ParallelIterator
+ Debug
, ID
, F
> Debug
for TryFold
<I
, U
, ID
, F
> {
40 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
41 f
.debug_struct("TryFold").field("base", &self.base
).finish()
45 impl<U
, I
, ID
, F
> ParallelIterator
for TryFold
<I
, U
, ID
, F
>
48 F
: Fn(U
::Ok
, I
::Item
) -> U
+ Sync
+ Send
,
49 ID
: Fn() -> U
::Ok
+ Sync
+ Send
,
54 fn drive_unindexed
<C
>(self, consumer
: C
) -> C
::Result
56 C
: UnindexedConsumer
<Self::Item
>,
58 let consumer1
= TryFoldConsumer
{
60 identity
: &self.identity
,
61 fold_op
: &self.fold_op
,
64 self.base
.drive_unindexed(consumer1
)
68 struct TryFoldConsumer
<'c
, U
, C
, ID
: 'c
, F
: 'c
> {
72 marker
: PhantomData
<U
>,
75 impl<'r
, U
, T
, C
, ID
, F
> Consumer
<T
> for TryFoldConsumer
<'r
, U
, C
, ID
, F
>
78 F
: Fn(U
::Ok
, T
) -> U
+ Sync
,
79 ID
: Fn() -> U
::Ok
+ Sync
,
82 type Folder
= TryFoldFolder
<'r
, C
::Folder
, U
, F
>;
83 type Reducer
= C
::Reducer
;
84 type Result
= C
::Result
;
86 fn split_at(self, index
: usize) -> (Self, Self, Self::Reducer
) {
87 let (left
, right
, reducer
) = self.base
.split_at(index
);
89 TryFoldConsumer { base: left, ..self }
,
98 fn into_folder(self) -> Self::Folder
{
100 base
: self.base
.into_folder(),
101 result
: Ok((self.identity
)()),
102 fold_op
: self.fold_op
,
106 fn full(&self) -> bool
{
111 impl<'r
, U
, T
, C
, ID
, F
> UnindexedConsumer
<T
> for TryFoldConsumer
<'r
, U
, C
, ID
, F
>
113 C
: UnindexedConsumer
<U
>,
114 F
: Fn(U
::Ok
, T
) -> U
+ Sync
,
115 ID
: Fn() -> U
::Ok
+ Sync
,
118 fn split_off_left(&self) -> Self {
120 base
: self.base
.split_off_left(),
125 fn to_reducer(&self) -> Self::Reducer
{
126 self.base
.to_reducer()
130 struct TryFoldFolder
<'r
, C
, U
: Try
, F
: 'r
> {
133 result
: Result
<U
::Ok
, U
::Error
>,
136 impl<'r
, C
, U
, F
, T
> Folder
<T
> for TryFoldFolder
<'r
, C
, U
, F
>
139 F
: Fn(U
::Ok
, T
) -> U
+ Sync
,
142 type Result
= C
::Result
;
144 fn consume(mut self, item
: T
) -> Self {
145 let fold_op
= self.fold_op
;
146 if let Ok(acc
) = self.result
{
147 self.result
= fold_op(acc
, item
).into_result();
152 fn complete(self) -> C
::Result
{
153 let item
= match self.result
{
154 Ok(ok
) => U
::from_ok(ok
),
155 Err(error
) => U
::from_error(error
),
157 self.base
.consume(item
).complete()
160 fn full(&self) -> bool
{
161 self.result
.is_err() || self.base
.full()
165 // ///////////////////////////////////////////////////////////////////////////
167 impl<U
, I
, F
> TryFoldWith
<I
, U
, F
>
170 F
: Fn(U
::Ok
, I
::Item
) -> U
+ Sync
,
174 pub(super) fn new(base
: I
, item
: U
::Ok
, fold_op
: F
) -> Self {
183 /// `TryFoldWith` is an iterator that applies a function over an iterator producing a single value.
184 /// This struct is created by the [`try_fold_with()`] method on [`ParallelIterator`]
186 /// [`try_fold_with()`]: trait.ParallelIterator.html#method.try_fold_with
187 /// [`ParallelIterator`]: trait.ParallelIterator.html
188 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
190 pub struct TryFoldWith
<I
, U
: Try
, F
> {
196 impl<I
: ParallelIterator
+ Debug
, U
: Try
, F
> Debug
for TryFoldWith
<I
, U
, F
>
200 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
201 f
.debug_struct("TryFoldWith")
202 .field("base", &self.base
)
203 .field("item", &self.item
)
208 impl<U
, I
, F
> ParallelIterator
for TryFoldWith
<I
, U
, F
>
211 F
: Fn(U
::Ok
, I
::Item
) -> U
+ Sync
+ Send
,
217 fn drive_unindexed
<C
>(self, consumer
: C
) -> C
::Result
219 C
: UnindexedConsumer
<Self::Item
>,
221 let consumer1
= TryFoldWithConsumer
{
224 fold_op
: &self.fold_op
,
226 self.base
.drive_unindexed(consumer1
)
230 struct TryFoldWithConsumer
<'c
, C
, U
: Try
, F
: 'c
> {
236 impl<'r
, U
, T
, C
, F
> Consumer
<T
> for TryFoldWithConsumer
<'r
, C
, U
, F
>
239 F
: Fn(U
::Ok
, T
) -> U
+ Sync
,
243 type Folder
= TryFoldFolder
<'r
, C
::Folder
, U
, F
>;
244 type Reducer
= C
::Reducer
;
245 type Result
= C
::Result
;
247 fn split_at(self, index
: usize) -> (Self, Self, Self::Reducer
) {
248 let (left
, right
, reducer
) = self.base
.split_at(index
);
250 TryFoldWithConsumer
{
252 item
: self.item
.clone(),
255 TryFoldWithConsumer
{
263 fn into_folder(self) -> Self::Folder
{
265 base
: self.base
.into_folder(),
266 result
: Ok(self.item
),
267 fold_op
: self.fold_op
,
271 fn full(&self) -> bool
{
276 impl<'r
, U
, T
, C
, F
> UnindexedConsumer
<T
> for TryFoldWithConsumer
<'r
, C
, U
, F
>
278 C
: UnindexedConsumer
<U
>,
279 F
: Fn(U
::Ok
, T
) -> U
+ Sync
,
283 fn split_off_left(&self) -> Self {
284 TryFoldWithConsumer
{
285 base
: self.base
.split_off_left(),
286 item
: self.item
.clone(),
291 fn to_reducer(&self) -> Self::Reducer
{
292 self.base
.to_reducer()