use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use foundation_core::valtron::{execute, task, valtron, Ctx, StreamIteratorExt, TaskStatus};
struct Work(u32);
impl Future for Work {
type Output = ();
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if self.0 == 0 {
Poll::Ready(())
} else {
self.0 -= 1;
cx.waker().wake_by_ref(); Poll::Pending
}
}
}
#[derive(Clone, Debug, PartialEq)]
struct House {
walls: u32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Building {
Raising(u32),
Done,
}
#[task]
async fn build_house(ctx: Ctx, walls: Building) -> Option<(Building, TaskStatus<House, ()>)> {
let _ = ctx;
match walls {
Building::Done => None,
Building::Raising(n) => {
if n < 4 {
Work(2).await; Some((Building::Raising(n + 1), TaskStatus::Ignore))
} else {
Some((Building::Done, TaskStatus::Ready(House { walls: n })))
}
}
}
}
#[valtron]
async fn main() {
let (house, _rest) = execute(build_house::new(Building::Raising(0)), None)
.expect("engine live")
.into_ready_future()
.await
.expect("a house was built");
assert_eq!(house, House { walls: 4 });
println!("async build_house -> {house:?}");
}