I want to be able to compose iterators that even support genawaiter
crate and avoid the boilerplate for every iterator adapter
I want to be able to iterator.compose(fn) like below (I know I can use the map operator but this is a simplified example for when I need to have some state in the iterators):
use genawaiter::{rc::gen, yield_};
use std::iter::Iterator;
fn wrap_with_option<Input, I: Iterator<Item = Input>>(iter: I) -> impl Iterator<Item = Option<Input>> {
return gen!({
for item in iter {
yield_!(Some(item));
}
})
.into_iter();
}
fn run() {
let input: Vec<i32> = vec![1, 2, 3, 4, 5];
let output: Vec<Option<&i32>> = input
.iter()
.compose(wrap_with_option)
.collect();
let expected = vec![
Some(&1),
Some(&2),
Some(&3),
Some(&4),
Some(&5)
];
assert_eq!(output, expected);
}
There is the tap crate that provides this general functionality. It provides methods to use function calls in a method-chained way.
You would use the .pipe()
method via its Pipe
trait.
use tap::Pipe;
let output: Vec<Option<&i32>> = input
.iter()
.pipe(wrap_with_option)
.collect();