35 lines
653 B
Rust
35 lines
653 B
Rust
use core::{cell::UnsafeCell, mem::ManuallyDrop};
|
|
|
|
/// A guard that runs a closure when it is dropped.
|
|
pub struct DropGuard<F: FnOnce()>(UnsafeCell<ManuallyDrop<F>>);
|
|
|
|
impl<F> DropGuard<F>
|
|
where
|
|
F: FnOnce(),
|
|
{
|
|
pub fn new(f: F) -> DropGuard<F> {
|
|
Self(UnsafeCell::new(ManuallyDrop::new(f)))
|
|
}
|
|
}
|
|
|
|
impl<F> Drop for DropGuard<F>
|
|
where
|
|
F: FnOnce(),
|
|
{
|
|
fn drop(&mut self) {
|
|
// SAFETY: drop() is called exactly once.
|
|
unsafe {
|
|
ManuallyDrop::take(&mut *self.0.get())();
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<F> From<F> for DropGuard<F>
|
|
where
|
|
F: FnOnce(),
|
|
{
|
|
fn from(f: F) -> Self {
|
|
DropGuard::new(f)
|
|
}
|
|
}
|