2 use crate::iter
::{adapters::SourceIter, InPlaceIterable}
;
3 use crate::ops
::{ControlFlow, Try}
;
5 /// An iterator to maintain state while iterating another iterator.
7 /// This `struct` is created by the [`scan`] method on [`Iterator`]. See its
8 /// documentation for more.
10 /// [`scan`]: Iterator::scan
11 /// [`Iterator`]: trait.Iterator.html
12 #[must_use = "iterators are lazy and do nothing unless consumed"]
13 #[stable(feature = "rust1", since = "1.0.0")]
15 pub struct Scan
<I
, St
, F
> {
21 impl<I
, St
, F
> Scan
<I
, St
, F
> {
22 pub(in crate::iter
) fn new(iter
: I
, state
: St
, f
: F
) -> Scan
<I
, St
, F
> {
23 Scan { iter, state, f }
27 #[stable(feature = "core_impl_debug", since = "1.9.0")]
28 impl<I
: fmt
::Debug
, St
: fmt
::Debug
, F
> fmt
::Debug
for Scan
<I
, St
, F
> {
29 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
30 f
.debug_struct("Scan").field("iter", &self.iter
).field("state", &self.state
).finish()
34 #[stable(feature = "rust1", since = "1.0.0")]
35 impl<B
, I
, St
, F
> Iterator
for Scan
<I
, St
, F
>
38 F
: FnMut(&mut St
, I
::Item
) -> Option
<B
>,
43 fn next(&mut self) -> Option
<B
> {
44 let a
= self.iter
.next()?
;
45 (self.f
)(&mut self.state
, a
)
49 fn size_hint(&self) -> (usize, Option
<usize>) {
50 let (_
, upper
) = self.iter
.size_hint();
51 (0, upper
) // can't know a lower bound, due to the scan function
55 fn try_fold
<Acc
, Fold
, R
>(&mut self, init
: Acc
, fold
: Fold
) -> R
58 Fold
: FnMut(Acc
, Self::Item
) -> R
,
61 fn scan
<'a
, T
, St
, B
, Acc
, R
: Try
<Output
= Acc
>>(
63 f
: &'a
mut impl FnMut(&mut St
, T
) -> Option
<B
>,
64 mut fold
: impl FnMut(Acc
, B
) -> R
+ 'a
,
65 ) -> impl FnMut(Acc
, T
) -> ControlFlow
<R
, Acc
> + 'a
{
66 move |acc
, x
| match f(state
, x
) {
67 None
=> ControlFlow
::Break(try { acc }
),
68 Some(x
) => ControlFlow
::from_try(fold(acc
, x
)),
72 let state
= &mut self.state
;
74 self.iter
.try_fold(init
, scan(state
, f
, fold
)).into_try()
78 fn fold
<Acc
, Fold
>(mut self, init
: Acc
, fold
: Fold
) -> Acc
81 Fold
: FnMut(Acc
, Self::Item
) -> Acc
,
84 fn ok
<B
, T
>(mut f
: impl FnMut(B
, T
) -> B
) -> impl FnMut(B
, T
) -> Result
<B
, !> {
85 move |acc
, x
| Ok(f(acc
, x
))
88 self.try_fold(init
, ok(fold
)).unwrap()
92 #[unstable(issue = "none", feature = "inplace_iteration")]
93 unsafe impl<St
, F
, B
, S
: Iterator
, I
: Iterator
> SourceIter
for Scan
<I
, St
, F
>
95 I
: SourceIter
<Source
= S
>,
96 F
: FnMut(&mut St
, I
::Item
) -> Option
<B
>,
101 unsafe fn as_inner(&mut self) -> &mut S
{
102 // SAFETY: unsafe function forwarding to unsafe function with the same requirements
103 unsafe { SourceIter::as_inner(&mut self.iter) }
107 #[unstable(issue = "none", feature = "inplace_iteration")]
108 unsafe impl<St
, F
, B
, I
: InPlaceIterable
> InPlaceIterable
for Scan
<I
, St
, F
> where
109 F
: FnMut(&mut St
, I
::Item
) -> Option
<B
>