#![no_std]
use core::mem::ManuallyDrop;
pub fn defer<F>(f: F) -> impl Drop
where
F: FnOnce(),
{
struct Defer<F: FnOnce()>(ManuallyDrop<F>);
impl<F: FnOnce()> Drop for Defer<F> {
fn drop(&mut self) {
let f: F = unsafe { ManuallyDrop::take(&mut self.0) };
f();
}
}
Defer(ManuallyDrop::new(f))
}
#[macro_export]
macro_rules! defer {
($e:expr) => {
let _defer = $crate::defer(|| $e);
};
}
#[test]
fn test() {
use core::cell::RefCell;
let i = RefCell::new(0);
{
let _d = defer(|| *i.borrow_mut() += 1);
assert_eq!(*i.borrow(), 0);
}
assert_eq!(*i.borrow(), 1);
}
#[test]
fn test_macro() {
use core::cell::RefCell;
let i = RefCell::new(0);
let k = RefCell::new(0);
{
defer!(*i.borrow_mut() += 1);
defer!(*k.borrow_mut() += 1);
assert_eq!(*i.borrow(), 0);
assert_eq!(*k.borrow(), 0);
}
assert_eq!(*i.borrow(), 1);
assert_eq!(*k.borrow(), 1);
}