1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
pub struct Guard<F: FnMut()>(pub Option<F>);
impl<F: FnMut()> Drop for Guard<F> {
fn drop(&mut self) {
if let Some(mut f) = (self.0).take() {
f()
}
}
}
/// Defers evaluation of a block of code until the end of the scope.
/// Sort of LIFO(last-in, first-out queue)
/// If you encounter references to resources that cannot mut more than 2 times, try nesting RefCell and then use.borrow() and.borrow_mut().
///
/// for example:
/// ```
/// use dark_std::defer;
/// //LIFO, so it will print: guard: 3 guard: 2 guard: 1
/// fn main(){
/// defer!({
/// println!("guard: 1");
/// });
/// defer!(||{
/// println!("guard: 2");
/// });
/// defer!{
/// println!("guard: 3");
/// }
/// }
/// ```
///
///
#[macro_export]
macro_rules! defer {
($func:block) => {
let _guard = $crate::defer::Guard(Some( ||$func));
};
($func:expr) => {
let _guard = $crate::defer::Guard(Some($func));
};
{ $($func:expr$(;)?)+ } => {
let _guard = $crate::defer::Guard(Some( ||{$($func;)+}));
}
}
#[cfg(test)]
mod test {
#[test]
fn test_defer() {
defer!(|| {
println!("defer");
});
}
}