#![allow(unused)]
use std::fmt::Display;
use std::iter::repeat_n;
use std::marker::PhantomPinned;
use std::pin::pin;
use generator_light::Generator;
use generator_light::GeneratorState;
use generator_light::Yielder;
use generator_light::ext::GeneratorIterator;
use generator_light::ext::complete_with;
use generator_light::ext::context;
use generator_light::ext::from_fn;
use generator_light::ext::from_iter;
use generator_light::ext::once;
use generator_light::ext::once_with;
use generator_light::generator;
use generator_light::suspend_;
use generator_light::yield_;
use generator_light::ext::GeneratorExt;
use std::convert::Infallible;
fn list_printer<D: Display>(
sep: impl Display,
) -> impl Generator<D, Yield = (), Return = Infallible> {
generator(async move |mut yielder: Yielder<_, _>| {
let mut item = suspend_!(yielder);
print!("{item}");
loop {
item = yield_!(yielder, ());
print!("{sep}{item}")
}
})
}
fn print_list(s: impl IntoIterator<Item: Display>, sep: impl Display) {
let g = from_iter(s).compose(list_printer(sep)).map_complete(drop);
let g = pin!(g);
g.into_iter().for_each(drop);
}
fn show_triangle(h: usize) -> impl Generator<Yield = char, Return = ()> {
from_iter(1..=h)
.map_yield(|w| {
from_iter(repeat_n('*', w))
.map_complete(|_| '\n')
.and_then(once)
})
.flatten()
}
fn adjacent_difference() -> impl Generator<i32, Yield = i32, Return = Infallible> {
complete_with(|x| x).and_then(|mut init| {
from_fn(GeneratorState::Yield).receiving(move |x| x - std::mem::replace(&mut init, x))
})
}
fn main() {
from_iter((1..15).map(|x| x * x))
.compose(adjacent_difference())
.map_complete(drop)
.into_iter()
.for_each(|c| print!("{c}\n"));
let popper = pin!(test_context_gen("hello".into()));
popper.into_iter().for_each(|c| print!("{c}\n"));
}
fn test_context_gen(s: String) -> impl Generator<Yield = char, Return = ()> {
fn str_pop(s: &mut String) -> impl Generator<Yield = char, Return = ()> {
from_fn(|_| {
s.pop()
.map_or(GeneratorState::Complete(()), GeneratorState::Yield)
})
}
context(s, str_pop).map_complete(drop)
}
fn adjacent_difference1() -> impl Generator<i32, Yield = i32, Return = Infallible> {
complete_with(|x| x).and_then(|init| {
fn diff(prev: &mut i32) -> impl Generator<i32, Yield = i32, Return = ()> {
from_fn(GeneratorState::Yield).receiving(|x| x - std::mem::replace(prev, x))
}
context(init, diff).map_complete(|_| loop {})
})
}
fn landing(s: Vec<u8>) {
fn byte_iter<'a>(s: &'a mut Vec<u8>) -> impl Generator<(), Yield = &'a mut u8, Return = ()> {
from_iter(s.iter_mut())
}
}