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:
-
defer!simple deferment. Will execute when current scope ends.- If this is all you need then use the
defer-litecrate!
- If this is all you need then use the
-
defer_move!same asdefer!but moves local variables into the closure. -
defer_guard!Returns a guard that causes execution when its scope ends.- Execution can be canceled or preempted.
-
defer_move_guard!Same asdefer_guard!but moves local variables into the closure. -
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=falsein Cargo.toml
-
defer_move_arc!Same asdefer_arc!but moves local variables into the closure.- All used local variables must be
Send.
- All used local variables must be
Usage
Add the dependency in your Cargo.toml:
[]
= "0.1.0"
Examples
Simple Defer
If this is all you need use the defer-lite crate instead!
use defer;
Canceled Defer
use defer_guard;
Reference Counted Defer
use thread;
use Duration;
use defer_move_arc;
Prints:
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.