use crate::prelude::*;
use beet_utils::prelude::*;
use flume::Sender;
use std::future::Future;
use std::pin::Pin;
use std::task;
use std::task::Poll;
use test::TestDesc;
use wasm_bindgen::prelude::*;
pub struct TestFuture<F> {
desc: TestDesc,
result_tx: Sender<TestDescAndResult>,
test: F,
}
impl<F> TestFuture<F> {
pub fn new(
desc: TestDesc,
result_tx: Sender<TestDescAndResult>,
test: F,
) -> Self {
Self {
desc,
result_tx,
test,
}
}
}
impl<F: Future<Output = Result<(), String>>> Future for TestFuture<F> {
type Output = ();
fn poll(
self: Pin<&mut Self>,
cx: &mut task::Context,
) -> Poll<Self::Output> {
let self_mut = unsafe { self.get_unchecked_mut() };
let test = unsafe { Pin::new_unchecked(&mut self_mut.test) };
let desc = &self_mut.desc;
let result_tx = &self_mut.result_tx;
let mut future_poll_output = None;
let panic_output = PanicStore::with_scope(desc, || {
let mut test = Some(test);
js_runtime::panic_to_error(&mut || {
let test = test.take().unwrap_throw();
let out = test.poll(cx);
future_poll_output = Some(match &out {
Poll::Ready(_) => Poll::Ready(()),
Poll::Pending => Poll::Pending,
});
match out {
Poll::Ready(Err(err)) => Err(err),
_ => Ok(()),
}
})
});
if panic_output.panicked() {
panic_output.send(result_tx, desc);
return Poll::Ready(());
}
match future_poll_output {
Some(Poll::Pending) => Poll::Pending,
Some(Poll::Ready(())) => {
panic_output.send(result_tx, desc);
Poll::Ready(())
}
None => Poll::Pending,
}
}
}