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}