68 lines
2.0 KiB
Rust
68 lines
2.0 KiB
Rust
macro_rules! ext_trait {
|
|
($name:ident: $sealed:ident for $t:ty {$(
|
|
$(#[$method_meta:meta])*
|
|
fn $method:ident -> $impl:ident;
|
|
)+}) => {
|
|
trait $sealed {}
|
|
#[allow(private_bounds)]
|
|
pub trait $name: $sealed {$(
|
|
$(#[$method_meta])*
|
|
fn $method(self) -> $crate::DropGuard<$impl>;
|
|
)+}
|
|
|
|
impl $sealed for $t {}
|
|
impl $name for $t {$(
|
|
fn $method(self) -> $crate::DropGuard<$impl> {
|
|
$crate::DropGuard::with_data($impl, self)
|
|
}
|
|
)+}
|
|
};
|
|
}
|
|
pub(crate) use ext_trait;
|
|
|
|
macro_rules! join_handle_ext {
|
|
($name:ident for $t:ident, $impl:ident, $call_method:ident, |$result_bind:ident| $result:ty) => {
|
|
use std::marker::PhantomData;
|
|
|
|
use crate::DropGuard;
|
|
|
|
pub struct $impl<T>(PhantomData<fn() -> T>);
|
|
impl<T> DropFn for $impl<T> {
|
|
type Data = $t<T>;
|
|
|
|
fn on_drop(self, data: Self::Data) {
|
|
_ = data.$call_method();
|
|
}
|
|
}
|
|
|
|
trait Sealed {}
|
|
pub trait $name {
|
|
type Result;
|
|
|
|
#[doc = concat!("Wraps the join handle in a [`DropGuard`] that will call [`", stringify!($t), "::", stringify!($call_method), "`] on drop.")]
|
|
fn abort_on_drop(self) -> DropGuard<$impl<Self::Result>>;
|
|
}
|
|
|
|
impl<T> Sealed for $t<T> {}
|
|
impl<T> $name for $t<T> {
|
|
type Result = T;
|
|
|
|
fn abort_on_drop(self) -> DropGuard<$impl<T>> {
|
|
DropGuard::with_data($impl(PhantomData), self)
|
|
}
|
|
}
|
|
|
|
impl<$result_bind> core::future::Future for DropGuard<$impl<$result_bind>> {
|
|
type Output = $result;
|
|
|
|
fn poll(
|
|
mut self: core::pin::Pin<&mut Self>,
|
|
cx: &mut core::task::Context<'_>,
|
|
) -> core::task::Poll<Self::Output> {
|
|
core::pin::Pin::new(&mut **self).poll(cx)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
pub(crate) use join_handle_ext;
|