terrified to start testing
This commit is contained in:
@@ -9,11 +9,8 @@ use futures::{FutureExt, SinkExt, StreamExt};
|
||||
use never::Never;
|
||||
use orchid_base::OrcRes;
|
||||
|
||||
use crate::atom::Atomic;
|
||||
use crate::atom_owned::{OwnedAtom, OwnedVariant};
|
||||
use crate::conv::{ToExpr, TryFromExpr};
|
||||
use crate::expr::Expr;
|
||||
use crate::gen_expr::{GExpr, arg, call, lam, new_atom, seq};
|
||||
use crate::{Atomic, Expr, OwnedAtom, OwnedVariant, ToExpr, TryFromExpr};
|
||||
|
||||
enum Command {
|
||||
Execute(GExpr, Sender<Expr>),
|
||||
@@ -30,7 +27,7 @@ impl BuilderCoroutine {
|
||||
pub async fn run(self) -> GExpr {
|
||||
let cmd = self.0.receiver.lock().await.next().await;
|
||||
match cmd {
|
||||
None => panic!("Before the stream ends, we should have gotten a Halt"),
|
||||
None => panic!("Exec handle dropped and coroutine blocked instead of returning"),
|
||||
Some(Command::Halt(expr)) => expr,
|
||||
Some(Command::Execute(expr, reply)) =>
|
||||
call(lam::<0>(seq(arg(0), call(new_atom(Replier { reply, builder: self }), arg(0)))), expr)
|
||||
@@ -40,7 +37,7 @@ impl BuilderCoroutine {
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Replier {
|
||||
pub(crate) struct Replier {
|
||||
reply: Sender<Expr>,
|
||||
builder: BuilderCoroutine,
|
||||
}
|
||||
@@ -52,12 +49,14 @@ impl OwnedAtom for Replier {
|
||||
type Refs = Never;
|
||||
async fn val(&self) -> Cow<'_, Self::Data> { Cow::Owned(()) }
|
||||
async fn call(mut self, arg: Expr) -> impl ToExpr {
|
||||
self.reply.send(arg).await.expect("What the heck");
|
||||
self.reply.send(arg).await.expect("Resolution request dropped after sending");
|
||||
std::mem::drop(self.reply);
|
||||
self.builder.run().await
|
||||
}
|
||||
}
|
||||
|
||||
/// A long-lived async context that can yield to the executor. The expression
|
||||
/// representing an in-progress exec block is not serializable.
|
||||
pub async fn exec<R: ToExpr>(f: impl for<'a> AsyncFnOnce(ExecHandle<'a>) -> R + 'static) -> GExpr {
|
||||
let (cmd_snd, cmd_recv) = channel(0);
|
||||
let halt =
|
||||
@@ -70,8 +69,11 @@ pub async fn exec<R: ToExpr>(f: impl for<'a> AsyncFnOnce(ExecHandle<'a>) -> R +
|
||||
|
||||
static WEIRD_DROP_ERR: &str = "Coroutine dropped while we are being polled somehow";
|
||||
|
||||
/// The handle an [exec] callback uses to yield to the executor
|
||||
pub struct ExecHandle<'a>(Sender<Command>, PhantomData<&'a ()>);
|
||||
impl ExecHandle<'_> {
|
||||
/// Yield to the executor by resolving to an expression that normalizes the
|
||||
/// value and then calls the continuation of the body with the result.
|
||||
pub async fn exec<T: TryFromExpr>(&mut self, val: impl ToExpr) -> OrcRes<T> {
|
||||
let (reply_snd, mut reply_recv) = channel(1);
|
||||
self.0.send(Command::Execute(val.to_gen().await, reply_snd)).await.expect(WEIRD_DROP_ERR);
|
||||
|
||||
Reference in New Issue
Block a user