drop-guard.rs/src/macros.rs

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;