use some_executor::observer::{
ExecutorNotified, FinishedObservation, Observation, Observer, ObserverNotified,
};
use some_executor::task::{Configuration, Task};
use some_executor::{
BoxedStaticObserver, BoxedStaticObserverFuture, DynStaticExecutor, ObjSafeStaticTask,
SomeStaticExecutor,
};
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll, Waker};
#[derive(Clone, Debug)]
struct TestStaticExecutor;
impl SomeStaticExecutor for TestStaticExecutor {
type ExecutorNotifier = Box<dyn ExecutorNotified>;
fn spawn_static<F, Notifier: ObserverNotified<F::Output>>(
&mut self,
_task: Task<F, Notifier>,
) -> impl Observer<Value = F::Output>
where
Self: Sized,
F: Future + 'static,
F::Output: 'static + Unpin,
{
#[allow(unreachable_code)]
{
unimplemented!()
as some_executor::observer::TypedObserver<F::Output, Self::ExecutorNotifier>
}
}
fn spawn_static_async<F, Notifier: ObserverNotified<F::Output>>(
&mut self,
_task: Task<F, Notifier>,
) -> impl Future<Output = impl Observer<Value = F::Output>>
where
Self: Sized,
F: Future + 'static,
F::Output: 'static + Unpin,
{
#[allow(unreachable_code)]
#[allow(clippy::async_yields_async)]
{
async {
unimplemented!()
as some_executor::observer::TypedObserver<F::Output, Self::ExecutorNotifier>
}
}
}
fn spawn_static_objsafe(&mut self, _task: ObjSafeStaticTask) -> BoxedStaticObserver {
unimplemented!()
}
fn spawn_static_objsafe_async<'s>(
&'s mut self,
_task: ObjSafeStaticTask,
) -> BoxedStaticObserverFuture<'s> {
unimplemented!()
}
fn clone_box(&self) -> Box<DynStaticExecutor> {
Box::new(self.clone())
}
fn executor_notifier(&mut self) -> Option<Self::ExecutorNotifier> {
None
}
}
fn spin_to_completion<F: Future<Output = ()>>(future: F) {
let mut context = Context::from_waker(Waker::noop());
let mut pinned = Box::pin(future);
loop {
if pinned.as_mut().poll(&mut context).is_ready() {
return;
}
}
}
struct PendOnce {
polled: bool,
}
impl Future for PendOnce {
type Output = u32;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<u32> {
if self.polled {
Poll::Ready(42)
} else {
self.polled = true;
cx.waker().wake_by_ref();
Poll::Pending
}
}
}
#[wasm_lite::wasm_lite_test]
fn spawned_static_task_future_delivers_value() {
let mut executor = TestStaticExecutor;
let task = Task::without_notifications(
"static-future".to_string(),
Configuration::default(),
PendOnce { polled: false },
);
let (spawned, observer) = task.spawn_static(&mut executor);
spin_to_completion(spawned);
match observer.observe() {
Observation::Ready(value) => assert_eq!(value, 42),
other => panic!("expected the task's value, got {other:?}"),
}
}
#[wasm_lite::wasm_lite_test]
async fn spawned_static_task_future_delivers_value_to_async_observer() {
let mut executor = TestStaticExecutor;
let task = Task::without_notifications(
"static-future-async".to_string(),
Configuration::default(),
async { 7u32 },
);
let (spawned, observer) = task.spawn_static(&mut executor);
spin_to_completion(spawned);
match observer.await {
FinishedObservation::Ready(value) => assert_eq!(value, 7),
other => panic!("expected the task's value, got {other:?}"),
}
}