1#![no_std]
2
3use core::ops::{Drop, FnOnce};
4
5pub struct Finally<F>
6where
7 F: FnOnce(),
8{
9 f: Option<F>,
10}
11
12impl<F> Drop for Finally<F>
13where
14 F: FnOnce(),
15{
16 fn drop(&mut self) {
17 if let Some(f) = self.f.take() {
18 f()
19 }
20 }
21}
22
23pub fn finally<F>(f: F) -> Finally<F>
24where
25 F: FnOnce(),
26{
27 Finally { f: Some(f) }
28}
29
30#[cfg(test)]
31mod tests {
32 use super::finally;
33 use core::sync::atomic::{AtomicUsize, Ordering};
34
35 #[test]
36 fn executed_on_drop() {
37 let a = AtomicUsize::new(0);
38 {
39 let _f = finally(|| {
40 a.fetch_add(1, Ordering::SeqCst);
41 });
42 assert_eq!(0, a.load(Ordering::SeqCst));
43 }
44 assert_eq!(1, a.load(Ordering::SeqCst));
45 }
46}