1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
//! `async_dropper` provides two ad-hoc implementations of asynchronous `drop` behavior (`AsyncDrop`).
//!
//! - `async_dropper::simple` uses a wrapper struct (suggested on [StackOverflow by paholg](https://stackoverflow.com/a/75584109))
//! - `async_dropper::derive` introduces a `derive` macro (`AsyncDrop`) which generates code that enables async drop functionality to run during a regular `drop`. That code requires `T: Default + PartialEq + Eq`.
//!
//! Here is a quick example of the shorter `async_dropper::simple`:
//!
//! ```
//! /// This object will be async-dropped (which must be wrapped in AsyncDropper)
//! #[derive(Default)]
//! struct AsyncThing(String);
//!
//! #[async_trait]
//! impl AsyncDrop for AsyncThing {
//! async fn async_drop(&mut self) {
//! tokio::time::sleep(Duration::from_secs(2)).await; // fake work
//! Ok(())
//! }
//! }
//!
//! #[your_async_runtime_of_choice::main] // i.e. tokio::main or async_std::main
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! drop(AsyncDropper::new(AsyncThing(String::from("test"))));
//! Ok(())
//! }
//! ```
//!
//! Note that `AsyncThing` must be wrapped in `async_dropper::simple::AsyncDropper`.
//!
//! For `async_dropper::derive`:
//!
//! ```
//! use async_dropper::derive::AsyncDrop;
//!
//! #[derive(Debug, Default, PartialEq, Eq, AsyncDrop)]
//! struct AsyncThing(String);
//!
//! /// Implementation of [AsyncDrop] that specifies the actual behavior
//! #[async_trait]
//! impl AsyncDrop for AsyncThing {
//! async fn async_drop(&mut self) -> Result<(), AsyncDropError> {
//! tokio::time::sleep(Duration::from_secs(2)).await; // fake work
//! Ok(())
//! }
//!
//! // This method resets an instance of T to equal T::default()
//! fn reset(&mut self) {
//! self.0 = String::default();
//! }
//! }
//!
//! #[your_async_runtime_of_choice::main] // i.e. tokio::main or async_std::main
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! drop(AsyncThing(String::from("test")));
//! Ok(())
//! }
//! ```
//!
//! The `async_dropper::derive` is interesting because it attempts to automatically (if somewhat painfully) determine
//! whether an object should have the defined asynchronous drop behavior performed by checking whether it is equal
//! to `Self::default()`.
//!
//! **Said differently, async drop behavior is skipped if an instance of `T` is exactly equal to a `T::default()`**.
//!
//! If `T` is *not* exactly equal to `T::default()`, the assumption is that `T` must still be holding things that require asynchronous dropping behavior, and as such that behavior will be performed.
//!
//! **If `reset(&mut self)` does not return `T` to a state where it is equal to `T::default()`, `drop` will panic**
pub use async_dropper_derive as derive;
pub use async_dropper_simple as simple;