use core::future::Future;
pub trait Detach: Sized {
fn detach(self) {
drop(self)
}
}
impl<T> Detach for std::thread::JoinHandle<T> {}
pub trait AsyncSpawner: Copy + Send + Sync + 'static {
type JoinHandle<F>: Detach + Future + Send + Sync + 'static
where
F: Send + 'static;
fn spawn<F>(future: F) -> Self::JoinHandle<F::Output>
where
F::Output: Send + 'static,
F: Future + Send + 'static;
fn spawn_detach<F>(future: F)
where
F::Output: Send + 'static,
F: Future + Send + 'static,
{
core::mem::drop(Self::spawn(future));
}
}
pub trait AsyncLocalSpawner: Copy + 'static {
type JoinHandle<F>: Detach + Future + 'static
where
F: 'static;
fn spawn_local<F>(future: F) -> Self::JoinHandle<F::Output>
where
F::Output: 'static,
F: Future + 'static;
fn spawn_local_detach<F>(future: F)
where
F::Output: 'static,
F: Future + 'static,
{
core::mem::drop(Self::spawn_local(future));
}
}
pub trait AsyncBlockingSpawner: Copy + 'static {
type JoinHandle<R>: Detach
where
R: Send + 'static;
fn spawn_blocking<F, R>(f: F) -> Self::JoinHandle<R>
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static;
fn spawn_blocking_detach<F, R>(f: F)
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
Self::spawn_blocking(f);
}
}
#[derive(Debug, Clone, Copy)]
#[cfg(all(
feature = "time",
any(
feature = "async-std",
feature = "tokio",
feature = "smol",
feature = "wasm"
)
))]
pub(crate) struct Canceled;
#[cfg(all(
feature = "time",
any(
feature = "async-std",
feature = "tokio",
feature = "smol",
feature = "wasm"
)
))]
impl core::fmt::Display for Canceled {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "after canceled")
}
}
#[cfg(all(
feature = "time",
any(
feature = "async-std",
feature = "tokio",
feature = "smol",
feature = "wasm"
)
))]
impl std::error::Error for Canceled {}
#[cfg(feature = "time")]
#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
#[derive(Debug)]
pub enum AfterHandleError<E> {
Canceled,
Join(E),
}
#[cfg(feature = "time")]
impl<E: core::fmt::Display> core::fmt::Display for AfterHandleError<E> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Canceled => write!(f, "after function was canceled"),
Self::Join(e) => write!(f, "{e}"),
}
}
}
#[cfg(feature = "time")]
impl<E: core::fmt::Debug + core::fmt::Display> std::error::Error for AfterHandleError<E> {}
#[cfg(feature = "time")]
#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
pub trait AfterHandle<F: Send + 'static, E>:
Send + Detach + Future<Output = Result<F, AfterHandleError<E>>> + 'static
{
fn cancel(self) -> impl Future<Output = Option<Result<F, AfterHandleError<E>>>> + Send;
}
#[cfg(feature = "time")]
#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
pub trait AsyncAfterSpawner: Copy + Send + Sync + 'static {
type JoinError: core::fmt::Debug + core::fmt::Display + 'static;
type JoinHandle<F>: AfterHandle<F, Self::JoinError>
where
F: Send + 'static;
fn spawn_after<F>(duration: core::time::Duration, future: F) -> Self::JoinHandle<F::Output>
where
F::Output: Send + 'static,
F: Future + Send + 'static;
fn spawn_after_detach<F>(duration: core::time::Duration, future: F)
where
F::Output: Send + 'static,
F: Future + Send + 'static,
{
core::mem::drop(Self::spawn_after(duration, future));
}
fn spawn_after_at<F>(instant: std::time::Instant, future: F) -> Self::JoinHandle<F::Output>
where
F::Output: Send + 'static,
F: Future + Send + 'static;
fn spawn_after_at_detach<F>(instant: std::time::Instant, future: F)
where
F::Output: Send + 'static,
F: Future + Send + 'static,
{
Self::spawn_after_at(instant, future).detach()
}
}
#[cfg(feature = "time")]
#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
pub trait LocalAfterHandle<F: 'static, E>:
Detach + Future<Output = Result<F, AfterHandleError<E>>> + 'static
{
fn cancel(self) -> impl Future<Output = Option<Result<F, AfterHandleError<E>>>>;
}
#[cfg(feature = "time")]
#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
pub trait AsyncLocalAfterSpawner: Copy + 'static {
type JoinError: core::fmt::Debug + core::fmt::Display + 'static;
type JoinHandle<F>: LocalAfterHandle<F, Self::JoinError>
where
F: 'static;
fn spawn_local_after<F>(duration: core::time::Duration, future: F) -> Self::JoinHandle<F::Output>
where
F::Output: 'static,
F: Future + 'static;
fn spawn_local_after_detach<F>(duration: core::time::Duration, future: F)
where
F::Output: 'static,
F: Future + 'static,
{
Self::spawn_local_after(duration, future).detach()
}
fn spawn_local_after_at<F>(instant: std::time::Instant, future: F) -> Self::JoinHandle<F::Output>
where
F::Output: 'static,
F: Future + 'static;
fn spawn_local_after_at_detach<F>(instant: std::time::Instant, future: F)
where
F::Output: 'static,
F: Future + 'static,
{
Self::spawn_local_after_at(instant, future).detach()
}
}