use crate::coro::Coro;
use crate::suspend::Suspend;
pub trait SuspendedVisitor<I, Y, R, N>
where
N: Coro<I, Y, R>,
{
type Out;
fn on_yield(self, y: Y, next: N) -> Self::Out;
fn on_return(self, r: R) -> Self::Out;
}
pub trait Suspended<I, Y, R>: Sized {
type Next: Coro<I, Y, R>;
fn visit<X>(
self,
visitor: impl SuspendedVisitor<I, Y, R, Self::Next, Out = X>,
) -> X;
fn into_enum(self) -> Suspend<Y, R, Self::Next> {
self.visit({
use Suspend::*;
struct AsEnum;
impl<I, Y, R, N> SuspendedVisitor<I, Y, R, N> for AsEnum
where
N: Coro<I, Y, R>,
{
type Out = Suspend<Y, R, N>;
fn on_yield(self, y: Y, next: N) -> Self::Out {
Yield(y, next)
}
fn on_return(self, r: R) -> Self::Out {
Return(r)
}
}
AsEnum
})
}
fn into_yield(self) -> Option<(Y, Self::Next)> {
self.into_enum().into_yield()
}
fn into_return(self) -> Option<R> {
self.into_enum().into_return()
}
}