#![allow(clippy::wildcard_imports)]
use crate::{fib, fib::Fiber};
use core::{future::Future, mem::ManuallyDrop, pin::Pin};
type SessFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
pub trait ProcLoop: Send + 'static {
type Context: Context<Self::Req, Self::ReqRes>;
type Cmd: Send + 'static;
type CmdRes: Send + 'static;
type Req: Send + 'static;
type ReqRes: Send + 'static;
const STACK_SIZE: usize;
fn run_cmd(cmd: Self::Cmd, context: Self::Context) -> Self::CmdRes;
#[inline]
fn on_create() {}
#[inline]
fn on_enter() {}
#[inline]
fn on_drop() {}
}
pub trait Sess: Send {
type ProcLoop: ProcLoop;
type Fiber: Fiber<
Input = In<<Self::ProcLoop as ProcLoop>::Cmd, <Self::ProcLoop as ProcLoop>::ReqRes>,
Yield = Out<<Self::ProcLoop as ProcLoop>::Req, <Self::ProcLoop as ProcLoop>::CmdRes>,
Return = !,
> + Send;
type Error: Send;
fn fib(&mut self) -> Pin<&mut Self::Fiber>;
fn run_req(
&mut self,
req: <Self::ProcLoop as ProcLoop>::Req,
) -> SessFuture<'_, Result<<Self::ProcLoop as ProcLoop>::ReqRes, Self::Error>>;
fn cmd(
&mut self,
cmd: <Self::ProcLoop as ProcLoop>::Cmd,
) -> SessFuture<'_, Result<<Self::ProcLoop as ProcLoop>::CmdRes, Self::Error>> {
let mut input = In::from_cmd(cmd);
Box::pin(async move {
loop {
let fib::Yielded(output) = self.fib().resume(input);
input = match output {
Out::Req(req) => In::from_req_res(self.run_req(req).await?),
Out::CmdRes(res) => break Ok(res),
}
}
})
}
}
pub trait Context<Req, ReqRes>: Copy + 'static {
unsafe fn new() -> Self;
fn req(self, req: Req) -> ReqRes;
}
pub union In<Cmd, ReqRes> {
cmd: ManuallyDrop<Cmd>,
req_res: ManuallyDrop<ReqRes>,
}
pub enum Out<Req, CmdRes> {
Req(Req),
CmdRes(CmdRes),
}
impl<Cmd, ReqRes> In<Cmd, ReqRes> {
pub fn from_cmd(cmd: Cmd) -> Self {
Self { cmd: ManuallyDrop::new(cmd) }
}
pub fn from_req_res(req_res: ReqRes) -> Self {
Self { req_res: ManuallyDrop::new(req_res) }
}
pub unsafe fn into_cmd(self) -> Cmd {
ManuallyDrop::into_inner(unsafe { self.cmd })
}
pub unsafe fn into_req_res(self) -> ReqRes {
ManuallyDrop::into_inner(unsafe { self.req_res })
}
}