util_rs/
defer.rs

1use std::ops::{Deref, DerefMut};
2
3pub struct Defer<T, F: FnOnce(T)>(Option<T>, Option<F>);
4
5pub fn defer<T, F: FnOnce(T)>(x: T, f: F) -> Defer<T, F> {
6    Defer(Some(x), Some(f))
7}
8
9impl<T, F: FnOnce(T)> Deref for Defer<T, F> {
10    type Target = T;
11
12    fn deref(&self) -> &Self::Target {
13        self.0
14            .as_ref()
15            .expect("struct API does not allow this to be None (defer - deref - x)")
16    }
17}
18
19impl<T, F: FnOnce(T)> DerefMut for Defer<T, F> {
20    fn deref_mut(&mut self) -> &mut Self::Target {
21        self.0
22            .as_mut()
23            .expect("struct API does not allow this to be None (defer - derefmut - x)")
24    }
25}
26
27impl<T, F: FnOnce(T)> Drop for Defer<T, F> {
28    fn drop(&mut self) {
29        self.1
30            .take()
31            .expect("struct API does not allow this to be None (defer - fn)")(
32            self.0
33                .take()
34                .expect("struct API does not allow this to be None (defer - x)"),
35        )
36    }
37}