From 74df738e462a4e13253e157def5faba7c857cf66 Mon Sep 17 00:00:00 2001 From: Avril Date: Wed, 30 Dec 2020 02:44:19 +0000 Subject: [PATCH] added readme --- Cargo.toml | 2 +- README.md | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 8 ++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 README.md diff --git a/Cargo.toml b/Cargo.toml index 0a9a7c7..3253bfd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "phantomdrop" description = "Go-like deferring of function calls" keywords = ["defer", "drop", "go"] -version = "1.0.0" +version = "1.0.1" authors = ["Avril "] edition = "2018" license = "GPL-3.0-or-later" diff --git a/README.md b/README.md new file mode 100644 index 0000000..77f9a52 --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +# `PhantomDrop` + +Small library for `defer`ing the running of function until the end of a block. + +# Usage +It is similar to `marker` types, useful for adding destructors into structs that you don't want to implement `Drop` on themselves, and also for deferring function calls. + +## Extra destructors +To add a destructor into a struct without needing to implement `Drop` on the struct itself (which can have some of its own issues, such as losing the ability for partial moves), we can use `PhantomDrop` as a field in the structure. +Note that when doing this, since closure types are opaque, the field may need to be sized. + +## Deferring +Similar to the `defer` mechanism in Go, we can use this to defer the calling of functions + ```rust +fn do_something() +{ + let _guard = phantomdrop::defer(|| println!("Hello!")); + // do some work +} // "Hello!" will now be printed when the function returns or unwinds (unless unwinds are disabled). + ``` + +# Holding data + +The guard can also hold a value + ```rust +fn do_something(print: String) +{ + let _guard = PhantomDrop::new(print, |string| println!("Dropped: {}", string)); + // do some work +} // `print` will now be printed here. + ``` + +## Capturing + +We can also capture a value, by reference, mutable reference, or moving. +Both holding a value within the guard and a capturing closure can be used at the same time. + ```rust +fn do_something(print: String) +{ + let _guard = phantomdrop::defer(move || println!("Dropped: {}", print)); // Moves `print` into itself. + // do some work +} // `print` will now be printed here. + +fn do_something_by_reference(print: String) +{ + let _guard = phantomdrop::defer(|| println!("Dropped: {}", print)); // Holds an immutable reference to `print`. + let trimmed = print.trim(); // Can still be used +} // `print` will now be printed here. + +fn do_something_by_mutable_reference(print: &mut String) +{ + let _guard = phantomdrop::defer(|| *print = String::from("Dropped")); // Holds a mutable reference to `print`. +} // `print` will now be set to "Dropped" here. + ``` + +# License +GPL'd with <3 diff --git a/src/lib.rs b/src/lib.rs index a99704f..21d419e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,8 @@ //! } // "Hello!" will now be printed when the function returns or unwinds (unless unwinds are disabled). //! ``` //! +//! # Values +//! //! The guard can also hold a value //! ``` //! fn do_something(print: String) @@ -49,6 +51,12 @@ use core::ops::Drop; #[derive(Debug)] pub struct PhantomDrop(MaybeUninit<(T, F)>); +/// `PhantomDrop` with no associated data. +pub type PhantomDropEmpty = PhantomDrop<(), F>; + +/// `PhantomDrop` that does not capture. +pub type PhantomDropPure = PhantomDrop; + impl Clone for PhantomDrop { #[inline] fn clone(&self) -> Self