use super::AwaitHandle;
use crate::runtime::{Aborted, Attr, Exit, FnOnceFuture, RawTaskContext, SetAborted};
use core::future::Future;
use core::pin::Pin;
use core::task::{Context, Poll};
pub async fn spawn_with<T>(future: T, attr: &Attr) -> AwaitHandle<T::Output>
where
T: Future + Send + 'static,
T::Output: Send + 'static,
{
TaskSpawn {
future: Some(future),
attr: attr.clone(),
}
.await
}
pub async fn spawn<T>(future: T) -> AwaitHandle<T::Output>
where
T: Future + Send + 'static,
T::Output: Send + 'static,
{
spawn_with(future, &Attr::default()).await
}
pub async fn spawn_fn<F, R>(f: F) -> AwaitHandle<R>
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
spawn(FnOnceFuture::new(f)).await
}
pub async fn spawn_fn_with<F, R>(f: F, attr: &Attr) -> AwaitHandle<R>
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
spawn_with(FnOnceFuture::new(f), attr).await
}
pub async fn spawn_local_with<T>(future: T, attr: &Attr) -> AwaitHandle<T::Output>
where
T: Future + 'static,
T::Output: 'static,
{
TaskSpawnLocal {
future: Some(future),
attr: attr.clone(),
}
.await
}
pub async fn spawn_local<T>(future: T) -> AwaitHandle<T::Output>
where
T: Future + 'static,
T::Output: 'static,
{
spawn_local_with(future, &Attr::default()).await
}
pub async fn spawn_fn_local_with<F, R>(f: F, attr: &Attr) -> AwaitHandle<R>
where
F: FnOnce() -> R + 'static,
R: 'static,
{
spawn_local_with(FnOnceFuture::new(f), attr).await
}
pub async fn spawn_fn_local<F, R>(f: F) -> AwaitHandle<R>
where
F: FnOnce() -> R + 'static,
R: 'static,
{
spawn_local(FnOnceFuture::new(f)).await
}
pub async fn exit() {
Exit.await
}
pub async fn aborted() -> bool {
Aborted.await
}
pub async fn set_aborted(aborted: bool) {
SetAborted(aborted).await
}
struct TaskSpawn<T> {
future: Option<T>,
attr: Attr,
}
impl<T> Unpin for TaskSpawn<T> {}
impl<T> Future for TaskSpawn<T>
where
T: Future + Send + 'static,
T::Output: Send + 'static,
{
type Output = AwaitHandle<T::Output>;
fn poll(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
match ctx.spawn(self.future.take().unwrap(), &self.attr) {
Ok(task) => Poll::Ready(AwaitHandle::<T::Output>::new(task)),
Err(_) => Poll::Ready(AwaitHandle::<T::Output>::null()),
}
}
}
struct TaskSpawnLocal<T> {
future: Option<T>,
attr: Attr,
}
impl<T> Unpin for TaskSpawnLocal<T> {}
impl<T> Future for TaskSpawnLocal<T>
where
T: Future + 'static,
T::Output: 'static,
{
type Output = AwaitHandle<T::Output>;
fn poll(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
match ctx.spawn_local(self.future.take().unwrap(), &self.attr) {
Ok(task) => Poll::Ready(AwaitHandle::<T::Output>::new(task)),
Err(_) => Poll::Ready(AwaitHandle::<T::Output>::null()),
}
}
}