use crate::forwarder::Receiver;
use crate::{ExecutorState, Spawner};
use alloc::boxed::Box;
use core::fmt::Debug;
use core::future::{Future, IntoFuture};
use core::pin::Pin;
#[derive(Clone, Copy, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct SpawnError<F>(pub F);
impl<F> Debug for SpawnError<F> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
"SpawnError(_)".fmt(f)
}
}
impl<'a> Spawner<'a> {
#[must_use]
pub fn dead() -> Self {
Self {
state: Default::default(),
}
}
#[allow(clippy::type_complexity)]
pub unsafe fn spawn_pinned(
&self,
future: Pin<Box<dyn Future<Output = ()> + 'a>>,
) -> Result<(), SpawnError<Pin<Box<dyn Future<Output = ()> + 'a>>>> {
if let Some(state) = self.state.upgrade() {
ExecutorState::enqueue(&state, future);
Ok(())
} else {
Err(SpawnError(future))
}
}
pub unsafe fn spawn<F, T>(&self, future: F) -> Result<Receiver<T>, SpawnError<F>>
where
F: IntoFuture<Output = T> + 'a,
T: 'a,
{
if let Some(state) = self.state.upgrade() {
Ok(ExecutorState::enqueue_forwarding(&state, future))
} else {
Err(SpawnError(future))
}
}
}