core_extensions/
on_drop.rs1use crate::utils::take_manuallydrop;
2
3use std_::mem::ManuallyDrop;
4
5#[cfg(test)]
6mod tests;
7
8
9#[cfg_attr(feature = "docsrs", doc(cfg(feature = "on_drop")))]
31pub struct RunOnDrop<T, F>
32where
33 F: FnOnce(T),
34{
35 value: ManuallyDrop<T>,
36 function: ManuallyDrop<F>,
37}
38
39impl<T, F> RunOnDrop<T, F>
40where
41 F: FnOnce(T),
42{
43 #[inline(always)]
45 pub fn new(value: T, function: F) -> Self {
46 Self {
47 value: ManuallyDrop::new(value),
48 function: ManuallyDrop::new(function),
49 }
50 }
51}
52
53impl<T, F> RunOnDrop<T, F>
54where
55 F: FnOnce(T),
56{
57 #[inline(always)]
59 pub fn get(&self) -> &T {
60 &*self.value
61 }
62
63 #[inline(always)]
65 pub fn get_mut(&mut self) -> &mut T {
66 &mut *self.value
67 }
68
69 pub fn into_inner(self) -> T {
71 let mut this = ManuallyDrop::new(self);
72 unsafe{
73 let ret = take_manuallydrop(&mut this.value);
74 ManuallyDrop::drop(&mut this.function);
75 ret
76 }
77 }
78
79}
80
81impl<T, F> Drop for RunOnDrop<T, F>
82where
83 F: FnOnce(T),
84{
85 #[inline(always)]
86 fn drop(&mut self) {
87 unsafe {
88 let value = take_manuallydrop(&mut self.value);
89 let function = take_manuallydrop(&mut self.function);
90 function(value);
91 }
92 }
93}
94
95
96