finally_block/
lib.rs

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}