defer-heavy 0.1.0

A versatile and easy to use defer statement for Rust. Similar to Go's or Zig's defer.
Documentation
A versatile and easy to use defer statement for Rust. Similar to Go's or Zig's defer.

Loosely based on and inspired by:
https://github.com/rodrigocfd/defer-lite

This crate is compatible uses `no_std`.
The default features use `alloc`.
To disable alloc set default-features to false in cargo.toml.

This crates provides 6 macros for different use cases of deferment:
1. `defer!` simple deferment. Will execute when current scope ends.
    - If this is all you need then use the `defer-lite` crate!

2. `defer_move!` same as `defer!` but moves local variables into the closure.

3. `defer_guard!` Returns a guard that causes execution when its scope ends.
    - Execution can be canceled or preempted.

4. `defer_move_guard!` Same as `defer_guard!` but moves local variables into the closure.

5. `defer_arc!` Returns a reference counted guard than can be shared with other threads.
    - Execution can be canceled or preempted.
    - Closure must be `Send`
    - Target must support Arc & AtomicBool.
    - Target must support alloc
    - can be disabled with `default-features=false` in Cargo.toml

6. `defer_move_arc!` Same as `defer_arc!` but moves local variables into the closure.
    - All used local variables must be `Send`.

# Usage

Add the dependency in your `Cargo.toml`:

```toml
[dependencies]
defer-heavy = "0.1.0"
```

## Examples

### Simple Defer
If this is all you need use the `defer-lite` crate instead!
```rust
use defer_heavy::defer;

fn main() {
    defer! { println!("Second"); }
    println!("First");
}
```

### Canceled Defer

```rust
use defer_heavy::defer_guard;

fn main() {
    let defer1 = defer_guard! { unreachable!("Wont be executed"); };
    let defer2 = defer_guard! { println!("Second"); };
    let defer3 = defer_guard! { println!("Fourth"); };

    println!("First");
    defer2.destroy(); //Same as drop(defer2);
    println!("Third");
    defer1.cancel();
}
```


### Reference Counted Defer
```rust
use std::thread;
use std::time::Duration;
use defer_heavy::defer_move_arc;

pub fn main() {
    let deferred = defer_arc! { println!("Executed in {:?}", thread::current().id());};
    println!("Main thread {:?}", thread::current().id());
    {
        let deferred = deferred.clone();
        thread::spawn(move ||{
            println!("Spawned thread {:?}", thread::current().id());
            let _deferred = deferred.own();
            thread::sleep(Duration::from_millis(2000)); //SIMULATE work
       });
   }
   thread::sleep(Duration::from_millis(2000)); //SIMULATE WORK
 }
```
Prints:
```text
Main thread Thread(1)
Spawned thread Thread(2)
"Executed in Thread(1)" or "Executed in Thread(2)"
```

# Order of execution
Rust guarantees that the order in which the closures are dropped
(and therefore executed) are in reverse order of creation.
This means the last `defer!` in the scope executes first.