1//! Types for controlling when drop is invoked.
2use core::mem;
3use core::mem::MaybeUninit;
4
5/// A type to delay the drop handler invocation.
6#[must_use = "to delay the drop handler invocation to the end of the scope"]
7pub struct OnDrop<F: FnOnce()> {
8 f: MaybeUninit<F>,
9}
10
11impl<F: FnOnce()> OnDrop<F> {
12 /// Create a new instance.
13 pub fn new(f: F) -> Self {
14 Self { f: MaybeUninit::new(val:f) }
15 }
16
17 /// Prevent drop handler from running.
18 pub fn defuse(self) {
19 mem::forget(self)
20 }
21}
22
23impl<F: FnOnce()> Drop for OnDrop<F> {
24 fn drop(&mut self) {
25 unsafe { self.f.as_ptr().read()() }
26 }
27}
28
29/// An explosive ordinance that panics if it is improperly disposed of.
30///
31/// This is to forbid dropping futures, when there is absolutely no other choice.
32///
33/// To correctly dispose of this device, call the [defuse](struct.DropBomb.html#method.defuse)
34/// method before this object is dropped.
35#[must_use = "to delay the drop bomb invokation to the end of the scope"]
36pub struct DropBomb {
37 _private: (),
38}
39
40impl DropBomb {
41 /// Create a new instance.
42 pub fn new() -> Self {
43 Self { _private: () }
44 }
45
46 /// Defuses the bomb, rendering it safe to drop.
47 pub fn defuse(self) {
48 mem::forget(self)
49 }
50}
51
52impl Drop for DropBomb {
53 fn drop(&mut self) {
54 panic!("boom")
55 }
56}
57