IterScan

Trait IterScan 

Source
pub trait IterScan: Iterator + Sized {
    // Provided methods
    fn scan_clone<Compute, State>(
        self,
        initial: State,
        compute: Compute,
    ) -> ScanClone<Self, Compute, State> 
       where State: Clone,
             Compute: FnMut(State, Self::Item) -> State { ... }
    fn scan_copy<Compute, State>(
        self,
        initial: State,
        compute: Compute,
    ) -> ScanCopy<Self, Compute, State> 
       where State: Copy,
             Compute: FnMut(State, Self::Item) -> State { ... }
    fn scan_state_clone<Compute, State, Value>(
        self,
        initial: State,
        compute: Compute,
    ) -> ScanStateClone<Self, Compute, State, Value> 
       where State: Clone,
             Compute: FnMut(State, Self::Item) -> (State, Value) { ... }
    fn scan_state_copy<Compute, State, Value>(
        self,
        initial: State,
        compute: Compute,
    ) -> ScanStateCopy<Self, Compute, State, Value> 
       where State: Copy,
             Compute: FnMut(State, Self::Item) -> (State, Value) { ... }
    fn scan_with_tuple<Compute, State, Value>(
        self,
        initial: State,
        compute: Compute,
    ) -> ScanWithTuple<Self, Compute, State, Value> 
       where Compute: FnMut(State, Self::Item) -> (State, Value) { ... }
}
Expand description

Iterator scan methods that don’t suck.

Provided Methods§

Source

fn scan_clone<Compute, State>( self, initial: State, compute: Compute, ) -> ScanClone<Self, Compute, State>
where State: Clone, Compute: FnMut(State, Self::Item) -> State,

This iterator adapter holds an internal state and emit this state on each iteration.

This internal state can be cloned.

scan_clone() takes 2 arguments:

  • An initial value which seeds the internal state.
  • A closure that:
    • Takes 2 arguments: Copy of the internal state from the previous iteration and the current item.
    • Returns the new state for the next iteration.

Example: Basic usage

use iter_scan::IterScan;
let input = ['a', 'b', 'c', 'd', 'e', 'f'];
let output: Vec<_> = input
    .into_iter()
    .scan_clone(String::new(), |acc, x| format!("{acc}{x}"))
    .collect();
assert_eq!(output, ["a", "ab", "abc", "abcd", "abcde", "abcdef"]);
Source

fn scan_copy<Compute, State>( self, initial: State, compute: Compute, ) -> ScanCopy<Self, Compute, State>
where State: Copy, Compute: FnMut(State, Self::Item) -> State,

This iterator adapter holds an internal state and emit this state on each iteration.

This internal state can be copied.

scan_copy() takes 2 arguments:

  • An initial value which seeds the internal state.
  • A closure that:
    • Takes 2 arguments: Copy of the internal state from the previous iteration and the current item.
    • Returns the new state for the next iteration.

Example: Basic usage

use iter_scan::IterScan;
let input = [2, 3, 4, 5];
let output: Vec<u64> = input
    .into_iter()
    .scan_copy(1, |acc, x| acc * x)
    .collect();
assert_eq!(output, [2, 6, 24, 120]);
Source

fn scan_state_clone<Compute, State, Value>( self, initial: State, compute: Compute, ) -> ScanStateClone<Self, Compute, State, Value>
where State: Clone, Compute: FnMut(State, Self::Item) -> (State, Value),

This iterator adapter holds an internal state and emit a tuple of this state and a mapped value on each iteration.

This internal state can be cloned.

scan_state_clone() takes 2 arguments:

  • An initial value which seeds the internal state.
  • A closure that:
    • Takes 2 arguments: Copy of the internal state from the previous iteration and the current item.
    • Returns the new state and the mapped value of the item.

Example: Group indexing.

use iter_scan::IterScan;

enum SourceItem {
    Separator,
    Value(&'static str),
}

let source = [
    SourceItem::Value("zero"),
    SourceItem::Value("one"),
    SourceItem::Value("two"),
    SourceItem::Separator,
    SourceItem::Value("three"),
    SourceItem::Value("four"),
    SourceItem::Separator,
    SourceItem::Value("five"),
    SourceItem::Separator,
    SourceItem::Value("six"),
];

let tagged: Vec<_> = source
    .into_iter()
    .scan_state_clone(0u32, |count, item| match item {
        SourceItem::Separator => (count + 1, None),
        SourceItem::Value(value) => (count, Some(value)),
    })
    .flat_map(|(count, item)| item.map(|item| (count, item)))
    .collect();

assert_eq!(
    &tagged,
    &[
        (0, "zero"),
        (0, "one"),
        (0, "two"),
        (1, "three"),
        (1, "four"),
        (2, "five"),
        (3, "six"),
    ],
);
Source

fn scan_state_copy<Compute, State, Value>( self, initial: State, compute: Compute, ) -> ScanStateCopy<Self, Compute, State, Value>
where State: Copy, Compute: FnMut(State, Self::Item) -> (State, Value),

This iterator adapter holds an internal state and emit a tuple of this state and a mapped value on each iteration.

This internal state can be copied.

scan_state_copy() takes 2 arguments:

  • An initial value which seeds the internal state.
  • A closure that:
    • Takes 2 arguments: Copy of the internal state from the previous iteration and the current item.
    • Returns the new state and the mapped value of the item.

Example: Group indexing.

use iter_scan::IterScan;

enum SourceItem {
    Separator,
    Value(&'static str),
}

let source = [
    SourceItem::Value("zero"),
    SourceItem::Value("one"),
    SourceItem::Value("two"),
    SourceItem::Separator,
    SourceItem::Value("three"),
    SourceItem::Value("four"),
    SourceItem::Separator,
    SourceItem::Value("five"),
    SourceItem::Separator,
    SourceItem::Value("six"),
];

let tagged: Vec<_> = source
    .into_iter()
    .scan_state_copy(0u32, |count, item| match item {
        SourceItem::Separator => (count + 1, None),
        SourceItem::Value(value) => (count, Some(value)),
    })
    .flat_map(|(count, item)| item.map(|item| (count, item)))
    .collect();

assert_eq!(
    &tagged,
    &[
        (0, "zero"),
        (0, "one"),
        (0, "two"),
        (1, "three"),
        (1, "four"),
        (2, "five"),
        (3, "six"),
    ],
);
Source

fn scan_with_tuple<Compute, State, Value>( self, initial: State, compute: Compute, ) -> ScanWithTuple<Self, Compute, State, Value>
where Compute: FnMut(State, Self::Item) -> (State, Value),

This iterator adapter holds an internal state and emit this state on each iteration.

This adapter should be used when the internal state can neither be cloned nor copied.

scan_with_tuple() takes 2 arguments:

  • An initial value which seeds the internal state.
  • A closure that:
    • Takes 2 arguments: Copy of the internal state from the previous iteration and the current item.
    • Returns a tuple of the new state and a value.

Example: Group indexing.

use iter_scan::IterScan;

enum SourceItem {
    Separator,
    Value(&'static str),
}

let source = [
    SourceItem::Value("zero"),
    SourceItem::Value("one"),
    SourceItem::Value("two"),
    SourceItem::Separator,
    SourceItem::Value("three"),
    SourceItem::Value("four"),
    SourceItem::Separator,
    SourceItem::Value("five"),
    SourceItem::Separator,
    SourceItem::Value("six"),
];

let tagged: Vec<_> = source
    .into_iter()
    .scan_with_tuple(0u32, |prev_tag, item| match item {
        SourceItem::Separator => (prev_tag + 1, None),
        SourceItem::Value(value) => (prev_tag, Some((prev_tag, value))),
    })
    .flatten()
    .collect();

assert_eq!(
    &tagged,
    &[
        (0, "zero"),
        (0, "one"),
        (0, "two"),
        (1, "three"),
        (1, "four"),
        (2, "five"),
        (3, "six"),
    ],
);

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§