pub struct Defer<F: FnOnce()> {
callback: core::mem::ManuallyDrop<F>,
}
impl<F: FnOnce()> Defer<F> {
#[must_use = "Defers won't run unless assigned to a variable"]
pub const fn new(f: F) -> Self {
Self {
callback: core::mem::ManuallyDrop::new(f),
}
}
}
impl<F: FnOnce()> Drop for Defer<F> {
fn drop(&mut self) {
unsafe {
core::mem::ManuallyDrop::take(&mut self.callback)();
}
}
}
#[macro_export]
macro_rules! defer {
($body:block) => {
$crate::defer::Defer::new(|| $body)
};
($func:expr) => {
$crate::defer::Defer::new($func)
};
}
#[cfg(test)]
mod tests {
#[test]
fn defer_test() {
let _d1 = defer!({ println!("This is defered") });
let _d2 = defer!(|| println!("Goodbye"));
fn funcptr() {
println!("Callback from a function pointer");
}
let _d3 = defer!(funcptr);
println!("Hey!");
}
}