What's a way to have a panic-safe contruct similar to Java's try { ... } finally { ... } in Rust such that both the try block and the finally block mutably borrow the same thing?
That is, I'm looking for something where borrows made in the try block are considered to end when execution moves out of the try block either normally or due to a panic unwind, and the borrows in the finally block start only when execution moves there.
If I use scopeguard::defer!, I need to write a closure above what would be the analog of the try block, and the mutable borrow takes effect at the closure creation time, so the analog of the try block doesn't get to mutably borrow what the closure is already borrowing.
defer!() is not the tool in this case, you can wrap the value in a scopeguard::ScopeGuard uisng the guard function.
because ScopeGuard implements Deref and DerefMut, you can use the guard as if it were the inner value.
struct Value {}
// the value is **moved** into the destructor
// in practice, this is usually a closure
fn drop_value(value: Value) {
println!("dropping value");
}
fn main() {
// create the value and wrap it in a guard
let value: Value = get_value();
let mut value = guard(value, drop_value);
// alternatively, you can wrap a `&mut value` if you want
// let mut value = guard(&mut value, drop_value_by_mut);
// use the guard object as if it were the value
value.method();
use_value(&value);
use_value_mut(&mut value);
// calls the destructor on scope exit
// alternatively, disarm the guard,
// i.e.unwrap the value without running the destructor
// let value = ScopeGuard::into_inner(value);
}