Expand description
Simple RAII scope guard
§Usage:
§No argument guard
use scope_guard::scope_guard;
let mut is_run = false;
{
scope_guard!(|| {
is_run = true;
});
}
assert!(is_run);
§Single argument guard
use scope_guard::scope_guard;
fn do_stuff(val: &mut u32) {
let old_val = *val;
let mut val = scope_guard!(|val| {
*val = old_val;
}, val);
**val += 1; //Double * to deref &mut u32
let is_ok = false;//doing some computations
if is_ok {
val.forget();
}
}
let mut val = 0;
do_stuff(&mut val);
assert_eq!(val, 0);
let mut guard = scope_guard!(|val| {
*val = 1;
}, &mut val);
drop(guard);
assert_eq!(val, 1);
§Stacked destructor calls
use scope_guard::scope_guard;
fn do_stuff(val: &mut u32) {
let old_value = *val;
let val = scope_guard!(|val| {
assert_eq!(*val, old_value);
//Do nothing
}, val);
let mut val = val.stack(|val| {
**val = old_value;
});
**val += 1; //Double * to deref &mut u32
}
let mut val = 0;
do_stuff(&mut val);
assert_eq!(val, 0);
§Multiple argument guard
use scope_guard::scope_guard;
fn do_stuff(val: &mut u32, is_run: &mut bool) {
let old_val = *val;
let mut guard = scope_guard!(|(val, is_run)| {
*val = old_val;
*is_run = false;
}, val, is_run);
*guard.0 += 1;
*guard.1 = true;
let is_ok = false; //doing some computations
if is_ok {
let (_val, _is_run) = guard.into_inner(); //analogues to forget
}
}
let mut is_run = false;
let mut val = 0;
do_stuff(&mut val, &mut is_run);
assert_eq!(val, 0);
assert!(!is_run);
let mut guard = scope_guard!(|(val, is_run)| {
*val = 1;
*is_run = true;
}, &mut val, &mut is_run);
drop(guard);
assert_eq!(val, 1);
assert!(is_run);
Macros§
- Creates scope guard, allowing to supply plain function with arguments in addition to closures.
Structs§
- Wraps to propagate panic as error.
- RAII Scope, running closure in destructor.
Functions§
- Executes future, making sure to perform cleanup regardless of whether
fut
is successful or panics.