4 releases
Uses new Rust 2024
| 0.1.3 | Apr 27, 2026 |
|---|---|
| 0.1.2 | Apr 27, 2026 |
| 0.1.1 | Apr 27, 2026 |
| 0.1.0 | Apr 27, 2026 |
#611 in Rust patterns
7,694 downloads per month
44KB
568 lines
guarden provides scoped guard macros for deferred cleanup and manual triggers.
The public API centers on three macros:
guarded!for binding a guard to a local variable that runs on Drop.guard!for creating a guard value that can be triggered manually.defer!as a convenience alias forguarded!.
The macros support synchronous and asynchronous bodies, explicit capture lists, and export controls for captured values.
⚠️ Critical Usage Note: Diverging Expressions
Do not use "naked" diverging expressions—such as panic!, todo!, or loop {}—as
the sole content of a sync guard closure. This prevents the compiler from
distinguishing between synchronous (ASYNC = false) and asynchronous
(ASYNC = true) implementations, leading to a type inference error (E0277).
Technical Context
The ! (Never Type) is a bottom type that can be coerced into any other type.
Because it satisfies both the () return type requirement for sync guards and the Future
trait requirement for async guards, the compiler encounters an inference deadlock.
Workaround
For macros like guard! or guarded!, force the closure to resolve to ()
by explicitly setting the guard to sync:
let val = "critical failure".to_string();
guarded! {
sync [val] {
panic!("{}", val);
}
}
guarden
guarden is the main library crate in the workspace. It re-exports the
public macros for scoped cleanup and deferred execution:
guarded!- bind a guard to a local variable and run its body when dropped.guard!- create a guard value that you can trigger manually.defer!- an alias forguarded!.
The crate supports both synchronous and asynchronous bodies, explicit capture lists, and export control for captured values.
Example
use guarden::guarded;
let sink = std::sync::Arc::new(std::sync::atomic::AtomicUsize::new(0));
{
guarded!([sink = sink.clone()] {
sink.store(7, std::sync::atomic::Ordering::SeqCst);
});
}
assert_eq!(sink.load(std::sync::atomic::Ordering::SeqCst), 7);
Notes
For more background and workspace-level usage, see the root README.md.
License
MIT
Dependencies
~2.3–3.5MB
~58K SLoC