use core::marker::PhantomData;
use super::*;
pub struct FromFn<F, R> {
f: F,
_marker: PhantomData<fn() -> R>,
}
pub struct BreakValue<'a> {
_invariant: PhantomData<fn(&'a ()) -> &'a ()>,
}
impl<F, R> InternalIterator for FromFn<F, R>
where
F: for<'a> FnOnce(&mut dyn FnMut(R) -> ControlFlow<BreakValue<'a>>) -> ControlFlow<BreakValue<'a>>,
{
type Item = R;
fn try_for_each<RR, FF>(self, mut f: FF) -> ControlFlow<RR>
where
FF: FnMut(Self::Item) -> ControlFlow<RR>,
{
let mut result = ControlFlow::Continue(());
(self.f)(&mut |item| {
match f(item) {
ControlFlow::Continue(()) => ControlFlow::Continue(()),
ControlFlow::Break(res) => {
result = ControlFlow::Break(res);
ControlFlow::Break(BreakValue { _invariant: PhantomData })
}
}
});
result
}
}
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>>,
{
FromFn { f, _marker: PhantomData }
}
#[test]
fn pipeline_tests() {
fn check(iter: impl InternalIterator<Item = i32>, expect: &[i32]) {
assert_eq!(iter.collect::<Vec<_>>(), expect);
}
fn make_iter() -> impl InternalIterator<Item = i32> {
from_fn(|f| {
f(1)?;
f(2)?;
f(3)?;
f(4)?;
ControlFlow::Continue(())
})
}
check(make_iter(), &[1, 2, 3, 4]);
check(make_iter().map(|x| x * 2), &[2, 4, 6, 8]);
check(make_iter().filter(|&x| x > 2), &[3, 4]);
check(make_iter().filter(|&x| x <= 2), &[1, 2]);
check(make_iter().chain([7, 8, 9]), &[1, 2, 3, 4, 7, 8, 9]);
}
#[test]
fn can_be_static() {
fn use_static_iterator(iter: impl InternalIterator<Item = i32> + 'static) {
assert_eq!(iter.collect::<Vec<_>>(), &[1, 2, 3]);
}
let mut a = 1;
let iter = from_fn(move |f| {
f(a)?;
a += 1;
f(a)?;
a += 1;
f(a)?;
ControlFlow::Continue(())
});
use_static_iterator(iter);
}
fn __compile_fail_check() {}