Function internal_iterator::from_fn

source ·
pub fn from_fn<F, R>(f: F) -> FromFn<F, R>
where F: for<'a> FnOnce(&mut dyn FnMut(R) -> ControlFlow<BreakValue<'a>>) -> ControlFlow<BreakValue<'a>>,
Expand description

Creates an internal iterator from provided closure.

Provided closure should be equivalent to how InternalIterator::try_for_each would be implemented - it should call its parameter with every value that needs to be yielded from the iterator, respect returned ControlFlow value, and return ControlFlow::Continue(()) at the end. Type signature ensures most of that, you only need to take care to use ? operator on every call when yielding values.

If you want to construct an InternalIterator from a closure that yields items one by one, like you would with std::iter::from_fn, then you can use that function with a conversion to internal iterator: std::iter::from_fn(f).into_internal().

let x = 2;
let y = Some(3);

let iter = internal_iterator::from_fn(|f| {
    f(1)?;
    f(x)?;
    if let Some(value) = y {
        f(value)?;
    }
    ControlFlow::Continue(())
});

let values = iter.collect::<Vec<_>>();
assert_eq!(values, [1, 2, 3])

Note that InternalIterator::try_for_each function is generic, but generic closures are not possible. Therefore this function utilizes dynamic dispatch (to be able to provide any function to the closure), and a marker type for break value with the actual value passed via a side channel (to be able to use any type as break value). Because of this, iterators constructed by from_fn might be optimized more poorly. If the need arises such iterators can always be rewritten as explicit structs with generic implementations of InternalIterator::try_for_each, although that will require manually handling captured variables (whereas compiler does that for you when using closures).