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");
        });
    }
}