1use super::*;
2
3drop_move_wrap! {
4 #[derive(Clone)]
6 pub struct DropGuard<F: FnOnce()>(DropGuardInner {
7 func: F,
8 });
9}
10
11impl<F: FnOnce()> DropMove for DropGuardInner<F> {
12 fn drop_move(self_: DropHandle<Self>) {
13 (DropHandle::into_inner(self_).func)()
14 }
15}
16
17impl<F: FnOnce()> DropGuard<F> {
18 pub fn new(f: F) -> Self {
20 DropGuardInner { func: f }.into()
21 }
22
23 pub fn into_inner(self) -> F {
25 let inner = DropGuardInner::from(self);
26 inner.func
27 }
28}
29
30impl<F: FnOnce()> Deref for DropGuard<F> {
31 type Target = F;
32
33 fn deref(&self) -> &F {
34 &self.0.func
35 }
36}
37
38impl<F: FnOnce()> DerefMut for DropGuard<F> {
39 fn deref_mut(&mut self) -> &mut F {
40 &mut self.0.func
41 }
42}
43
44impl<F: FnOnce()> From<F> for DropGuard<F> {
45 fn from(f: F) -> Self {
46 DropGuard::new(f)
47 }
48}
49
50#[cfg(test)]
51mod test {
52 use super::*;
53
54 extern crate std;
55 use std::boxed::Box;
56
57 #[test]
58 fn test_drop() {
59 let mut x: u32 = 0;
60 let z: u32 = 0xdeadbeef;
61 let y = Box::<u32>::new(z);
62
63 assert!(x != z);
64 {
65 let x_ref = &mut x;
66 let f = move || *x_ref = *y;
67 let guard = DropGuard::new(f);
68
69 let f = guard.into_inner();
70 DropGuard::new(f);
71 }
72 assert_eq!(x, z);
73 }
74
75 #[test]
76 fn test_get() {
77 let mut x: u32 = 0;
78
79 {
80 let mut f = || x += 1;
81 f();
82
83 let mut guard = DropGuard::new(f);
84 guard.deref_mut()();
85 }
86
87 assert_eq!(x, 3);
88 }
89}