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 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
#![warn(missing_docs, clippy::all, clippy::pedantic, clippy::cargo)] #![deny(intra_doc_link_resolution_failure, missing_debug_implementations)] //! A small crate for handling resources that must be consumed at the end of their lifetime. //! //! Since Rust's type system is affine rather than linear, `Drop::drop` mutably borrows `self`, //! rather than consuming it. For the most part, this is fine, but for some cases (such as working //! with the crate `gfx_hal`) resources must be consumed on drop. This crate and the //! `dispose_derive` crate serve to cover the typical boilerplate for such cases by managing the //! `ManuallyDrop` wrapper for you. //! //! As a bonus, this crate makes it easy to defer the execution of an `FnOnce` closure to the end //! of a scope, which can be done using the [`defer`] function. //! //! **NOTE:** The `Dispose` trait does _not_ provide a `Drop` impl by itself. For that, a value //! implementing `Dispose` must be wrapped in a [`Disposable`] struct. //! //! # Examples //! //! ``` //! use dispose::{Dispose, Disposable}; //! //! struct MyStruct; //! //! impl Dispose for MyStruct { //! fn dispose(self) { println!("Goodbye, world!"); } //! } //! //! { //! let _my_struct = Disposable::new(MyStruct); //! } // prints "Goodbye, world!" //! ``` //! //! As a design consideration, values implementing `Dispose` should _always_ be returned from //! functions within `Disposable` or any other wrapper properly implementing `Drop`. `Disposable` //! is recommended as it contains an unsafe [`leak`] function to retrieve the inner value, if //! necessary. //! //! ``` //! use dispose::{Dispose, Disposable}; //! //! mod secrets { //! # use dispose::{Dispose, Disposable}; //! //! pub struct Secrets { //! launch_codes: u32, //! } //! //! impl Secrets { //! pub fn new(launch_codes: u32) -> Disposable<Self> { //! Self { launch_codes }.into() //! } //! } //! //! impl Dispose for Secrets { //! fn dispose(mut self) { self.launch_codes = 0x0; } // Nice try, hackers! //! } //! } //! //! fn main() { //! let secret = secrets::Secrets::new(0xDEADBEEF); //! } // secret is properly disposed at the end of the scope //! //! fn BAD() { //! let secret = secrets::Secrets::new(0o1337); //! //! let mwahaha = unsafe { Disposable::leak(secret) }; //! } // .dispose() was not called - data has been leaked! //! ``` //! //! (My lawyers have advised me to note that the above example is not cryptographically secure. //! Please do not clean up secure memory by simply setting it to zero.) //! //! [`defer`]: ./fn.defer.html //! [`Disposable`]: ./struct.Disposable.html //! [`leak`]: ./struct.Disposable.html#tymethod.leak mod defer; mod disposable; mod dispose; mod dispose_with; pub use crate::{defer::*, disposable::*, dispose::*, dispose_with::*}; pub use dispose_derive::*; /// Contains all the basic traits and derive macros exported by this crate. pub mod prelude { #[doc(no_inline)] pub use super::{Dispose, DisposeWith}; #[doc(no_inline)] pub use dispose_derive::*; }