1#![cfg_attr(not(feature = "std"), no_std)]
13
14pub struct AfterDrop<F: FnOnce()>(Option<F>);
17
18pub fn defer<F: FnOnce()>(func: F) -> AfterDrop<F> {
19 AfterDrop::new(func)
20}
21
22impl<F: FnOnce()> AfterDrop<F> {
23 #[must_use]
24 pub fn new(func: F) -> Self {
25 Self(Some(func))
26 }
27}
28
29impl<F: FnOnce()> Drop for AfterDrop<F> {
30 fn drop(&mut self) {
31 self.0.take().unwrap()()
32 }
33}
34
35impl<F: FnOnce()> From<F> for AfterDrop<F> {
36 fn from(func: F) -> Self {
37 Self::new(func)
38 }
39}
40
41#[cfg(feature = "std")]
44pub struct AfterDropBoxed<'a>(Option<Box<dyn FnOnce() + 'a>>);
45
46#[cfg(feature = "std")]
47impl<'a> AfterDropBoxed<'a> {
48 #[must_use]
49 pub fn new<F: FnOnce() + 'a>(func: F) -> Self {
50 Self(Some(Box::new(func)))
51 }
52}
53
54#[cfg(feature = "std")]
55impl<'a> Drop for AfterDropBoxed<'a> {
56 fn drop(&mut self) {
57 self.0.take().unwrap()()
58 }
59}
60
61#[cfg(feature = "std")]
62impl<'a, F: FnOnce() + 'a> From<F> for AfterDropBoxed<'a> {
63 fn from(func: F) -> Self {
64 Self::new(func)
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 #[test]
71 fn defer() {
72 let mut droped = false;
73
74 let _defer = crate::defer(|| droped = true);
75 drop(_defer);
76
77 assert!(droped)
78 }
79
80 #[test]
81 fn drop_after_boxed() {
82 let mut droped = false;
83
84 let _boxed = crate::AfterDropBoxed::new(|| droped = true);
85 drop(_boxed);
86
87 assert!(droped);
88 }
89}