1use std::{
16 fmt,
17 mem::ManuallyDrop,
18 ops::{Deref, DerefMut},
19};
20
21pub struct DropGuard<T, F>
22where
23 F: FnOnce(T),
24{
25 inner: ManuallyDrop<T>,
26 f: ManuallyDrop<F>,
27}
28
29impl<T, F: FnOnce(T)> DropGuard<T, F> {
30 pub const fn new(inner: T, f: F) -> Self {
31 Self { inner: ManuallyDrop::new(inner), f: ManuallyDrop::new(f) }
32 }
33
34 pub fn into_inner(guard: Self) -> T {
35 let mut guard = ManuallyDrop::new(guard);
36 let value = unsafe { ManuallyDrop::take(&mut guard.inner) };
37 unsafe { ManuallyDrop::drop(&mut guard.f) };
38 value
39 }
40}
41
42impl<T, F: FnOnce(T)> Deref for DropGuard<T, F> {
43 type Target = T;
44
45 fn deref(&self) -> &T {
46 &self.inner
47 }
48}
49
50impl<T, F: FnOnce(T)> DerefMut for DropGuard<T, F> {
51 fn deref_mut(&mut self) -> &mut T {
52 &mut self.inner
53 }
54}
55
56impl<T, F: FnOnce(T)> Drop for DropGuard<T, F> {
57 fn drop(&mut self) {
58 let inner = unsafe { ManuallyDrop::take(&mut self.inner) };
59 let f = unsafe { ManuallyDrop::take(&mut self.f) };
60 f(inner);
61 }
62}
63
64impl<T: fmt::Debug, F: FnOnce(T)> fmt::Debug for DropGuard<T, F> {
65 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66 fmt::Debug::fmt(&**self, f)
67 }
68}