From e989f0465114db180054557485682fd64d12ffa2 Mon Sep 17 00:00:00 2001 From: Michael Pfaff Date: Wed, 15 Jun 2022 16:41:55 -0400 Subject: [PATCH] async-std support and refactoring --- Cargo.toml | 14 ++++++-- src/impl_arbitrary.rs | 18 ++++++++++ src/impl_async_std.rs | 22 +++++++++++++ src/impl_tokio1.rs | 44 +++++++++++++++++++++++++ src/impl_triggered.rs | 8 +++++ src/lib.rs | 76 ++++++++----------------------------------- 6 files changed, 116 insertions(+), 66 deletions(-) create mode 100644 src/impl_arbitrary.rs create mode 100644 src/impl_async_std.rs create mode 100644 src/impl_tokio1.rs create mode 100644 src/impl_triggered.rs diff --git a/Cargo.toml b/Cargo.toml index bfbb5e3..129af1f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,12 +5,20 @@ edition = "2021" license = "MIT OR Apache-2.0" [features] +# keeping this in default to maintain semver compatibility +default = [ "arbitrary" ] + +arbitrary = [ ] + +std = [ ] + +async-std = [ "dep:async-std", "async-std/alloc", "async-std/default" ] tokio1 = [ "dep:tokio1" ] tokio1-sync = [ "tokio1", "tokio1/sync" ] -tokio1-task = [ "tokio1", "tokio1/rt", "dep:futures-lite" ] +tokio1-task = [ "tokio1", "tokio1/rt" ] triggered = [ "dep:triggered" ] [dependencies] -futures-lite = { version = "1.12", default-features = false, optional = true } +async-std = { version = "1", default-features = false, optional = true } tokio1 = { package = "tokio", version = "1", default-features = false, optional = true } -triggered = { version = "0.1.2", optional = true } +triggered = { version = "0.1.2", default-features = false, optional = true } diff --git a/src/impl_arbitrary.rs b/src/impl_arbitrary.rs new file mode 100644 index 0000000..e736d17 --- /dev/null +++ b/src/impl_arbitrary.rs @@ -0,0 +1,18 @@ +use crate::DropGuarded; + +pub struct ArbitraryDropGuard ()>(Option); + +impl ()> ArbitraryDropGuard { + #[inline] + pub const fn new(f: F) -> Self { + Self(Some(f)) + } +} + +impl ()> DropGuarded for ArbitraryDropGuard { + fn cancel(mut self) { + if let Some(f) = self.0.take() { + f(); + } + } +} diff --git a/src/impl_async_std.rs b/src/impl_async_std.rs new file mode 100644 index 0000000..7a3c0e8 --- /dev/null +++ b/src/impl_async_std.rs @@ -0,0 +1,22 @@ +use async_std::task::JoinHandle; + +use crate::{DropGuard, DropGuarded}; + +impl DropGuarded for JoinHandle { + #[inline] + fn cancel(self) { + let _ = JoinHandle::::cancel(self); + } +} + +impl core::future::Future for DropGuard> { + type Output = T; + + fn poll( + mut self: core::pin::Pin<&mut Self>, + cx: &mut core::task::Context<'_>, + ) -> core::task::Poll { + let handle = (*self).inner.as_mut().expect("can only be None in drop"); + core::pin::Pin::new(handle).poll(cx) + } +} diff --git a/src/impl_tokio1.rs b/src/impl_tokio1.rs new file mode 100644 index 0000000..6a72365 --- /dev/null +++ b/src/impl_tokio1.rs @@ -0,0 +1,44 @@ +use crate::DropGuarded; + +#[cfg(feature = "tokio1-task")] +mod impl_task { + use crate::{DropGuard, DropGuarded}; + + use tokio1::task::{JoinError, JoinHandle}; + + impl DropGuarded for JoinHandle { + #[inline] + fn cancel(self) { + self.abort(); + } + } + + #[cfg(feature = "tokio1-task")] + impl core::future::Future for DropGuard> { + type Output = Result; + + fn poll( + mut self: core::pin::Pin<&mut Self>, + cx: &mut core::task::Context<'_>, + ) -> core::task::Poll { + let handle = (*self).inner.as_mut().expect("can only be None in drop"); + core::pin::Pin::new(handle).poll(cx) + } + } +} + +#[cfg(feature = "tokio1-sync")] +impl DropGuarded for tokio1::sync::oneshot::Sender<()> { + #[inline] + fn cancel(self) { + let _ = self.send(()); + } +} + +#[cfg(all(feature = "tokio1-sync", feature = "std"))] +impl DropGuarded for std::sync::Arc { + #[inline] + fn cancel(self) { + self.close(); + } +} diff --git a/src/impl_triggered.rs b/src/impl_triggered.rs new file mode 100644 index 0000000..41d6b93 --- /dev/null +++ b/src/impl_triggered.rs @@ -0,0 +1,8 @@ +use crate::DropGuarded; + +impl DropGuarded for triggered::Trigger { + #[inline] + fn cancel(self) { + self.trigger(); + } +} diff --git a/src/lib.rs b/src/lib.rs index cdebeb3..2eae83f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,59 +13,9 @@ pub trait DropGuarded { fn cancel(self); } -#[cfg(feature = "tokio1-task")] -impl DropGuarded for tokio1::task::JoinHandle { - #[inline] - fn cancel(self) { - self.abort(); - } -} - -#[cfg(feature = "tokio1-sync")] -impl DropGuarded for tokio1::sync::oneshot::Sender<()> { - #[inline] - fn cancel(self) { - let _ = self.send(()); - } -} - -#[cfg(feature = "tokio1-sync")] -impl DropGuarded for std::sync::Arc { - #[inline] - fn cancel(self) { - self.close(); - } -} - -#[cfg(feature = "triggered")] -impl DropGuarded for triggered::Trigger { - #[inline] - fn cancel(self) { - self.trigger(); - } -} - -#[repr(transparent)] -pub struct ArbitraryDropGuard ()>(Option); - -impl ()> ArbitraryDropGuard { - #[inline] - pub fn new(f: F) -> Self { - Self(Some(f)) - } -} - -impl ()> DropGuarded for ArbitraryDropGuard { - fn cancel(mut self) { - if let Some(f) = self.0.take() { - f(); - } - } -} - impl DropGuard { #[inline] - pub fn new(guarded: T) -> Self { + pub const fn new(guarded: T) -> Self { Self { inner: Some(guarded), } @@ -81,16 +31,16 @@ impl Drop for DropGuard { } } -#[cfg(feature = "tokio1-task")] -impl std::future::Future for DropGuard> { - type Output = Result; +#[cfg(feature = "arbitrary")] +mod impl_arbitrary; +#[cfg(feature = "arbitrary")] +pub use impl_arbitrary::ArbitraryDropGuard; - fn poll( - mut self: std::pin::Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> std::task::Poll { - use futures_lite::future::FutureExt; - let handle = (*self).inner.as_mut().expect("can only be None in drop"); - handle.poll(cx) - } -} +#[cfg(feature = "async-std")] +mod impl_async_std; + +#[cfg(feature = "tokio1")] +mod impl_tokio1; + +#[cfg(feature = "triggered")] +mod impl_triggered;