polars_utils/
with_drop.rs1use core::fmt::{self, Debug};
4use core::mem::ManuallyDrop;
5use core::ops::{Deref, DerefMut};
6
7pub struct WithDrop<T, F>
8where
9 F: FnOnce(T),
10{
11 inner: ManuallyDrop<T>,
12 f: ManuallyDrop<F>,
13}
14
15impl<T, F> WithDrop<T, F>
16where
17 F: FnOnce(T),
18{
19 #[must_use]
20 pub const fn new(inner: T, f: F) -> Self {
21 Self {
22 inner: ManuallyDrop::new(inner),
23 f: ManuallyDrop::new(f),
24 }
25 }
26
27 #[inline]
28 pub fn into_inner(guard: Self) -> T {
29 let mut guard = ManuallyDrop::new(guard);
32
33 let value = unsafe { ManuallyDrop::take(&mut guard.inner) };
37
38 unsafe { ManuallyDrop::drop(&mut guard.f) };
44 value
45 }
46}
47
48impl<T, F> Deref for WithDrop<T, F>
49where
50 F: FnOnce(T),
51{
52 type Target = T;
53
54 fn deref(&self) -> &T {
55 &self.inner
56 }
57}
58
59impl<T, F> DerefMut for WithDrop<T, F>
60where
61 F: FnOnce(T),
62{
63 fn deref_mut(&mut self) -> &mut T {
64 &mut self.inner
65 }
66}
67
68impl<T, F> Drop for WithDrop<T, F>
69where
70 F: FnOnce(T),
71{
72 fn drop(&mut self) {
73 let inner = unsafe { ManuallyDrop::take(&mut self.inner) };
75
76 let f = unsafe { ManuallyDrop::take(&mut self.f) };
78
79 f(inner);
80 }
81}
82
83impl<T, F> Debug for WithDrop<T, F>
84where
85 T: Debug,
86 F: FnOnce(T),
87{
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 fmt::Debug::fmt(&**self, f)
90 }
91}