README.md
1# scopeguard
2
3Rust crate for a convenient RAII scope guard that will run a given closure when
4it goes out of scope, even if the code between panics (assuming unwinding panic).
5
6The `defer!` macro and `guard` are `no_std` compatible (require only `core`),
7but the on unwinding / not on unwinding strategies require linking to `std`.
8By default, the `use_std` crate feature is enabled. Disable the default features
9for `no_std` support.
10
11Please read the [API documentation here](https://docs.rs/scopeguard/).
12
13Minimum supported Rust version: 1.20
14
15[](https://github.com/bluss/scopeguard/actions/workflows/ci.yaml)
16[](https://crates.io/crates/scopeguard)
17
18## How to use
19
20```rs
21#[macro_use(defer)]
22extern crate scopeguard;
23
24use scopeguard::guard;
25
26fn f() {
27 defer! {
28 println!("Called at return or panic");
29 }
30 panic!();
31}
32
33use std::fs::File;
34use std::io::Write;
35
36fn g() {
37 let f = File::create("newfile.txt").unwrap();
38 let mut file = guard(f, |f| {
39 // write file at return or panic
40 let _ = f.sync_all();
41 });
42 // access the file through the scope guard itself
43 file.write_all(b"test me\n").unwrap();
44}
45```
46
47## Recent Changes
48
49- 1.2.0
50
51 - Use ManuallyDrop instead of mem::forget in into_inner. (by @willtunnels)
52 - Warn if the guard is not assigned to a variable and is dropped immediately
53 instead of at the scope's end. (by @sergey-v-galtsev)
54
55- 1.1.0
56
57 - Change macros (`defer!`, `defer_on_success!` and `defer_on_unwind!`)
58 to accept statements. (by @konsumlamm)
59
60- 1.0.0
61
62 - Change the closure type from `FnMut(&mut T)` to `FnOnce(T)`:
63 Passing the inner value by value instead of a mutable reference is a
64 breaking change, but allows the guard closure to consume it. (by @tormol)
65
66 - Add `defer_on_success!`, `guard_on_success()` and `OnSuccess`
67 strategy, which triggers when scope is exited *without* panic. It's the
68 opposite to `defer_on_unwind!` / `guard_on_unwind()` / `OnUnwind`.
69
70 - Add `ScopeGuard::into_inner()`, which "defuses" the guard and returns the
71 guarded value. (by @tormol)
72
73 - Implement `Sync` for guards with non-`Sync` closures.
74
75 - Require Rust 1.20
76
77- 0.3.3
78
79 - Use `#[inline]` on a few more functions by @stjepang (#14)
80 - Add examples to crate documentation
81
82- 0.3.2
83
84 - Add crate categories
85
86- 0.3.1
87
88 - Add `defer_on_unwind!`, `Strategy` trait
89 - Rename `Guard` → `ScopeGuard`
90 - Add `ScopeGuard::with_strategy`.
91 - `ScopeGuard` now implements `Debug`.
92 - Require Rust 1.11
93
94- 0.2.0
95
96 - Require Rust 1.6
97 - Use `no_std` unconditionally
98 - No other changes
99
100- 0.1.2
101
102 - Add macro `defer!`
103