use core::ops::{Deref, DerefMut};
pub struct RaiiWrapper<T, F>(Option<T>, F)
where
F: FnMut(T);
impl<T, F> RaiiWrapper<T, F>
where
F: FnMut(T),
{
pub fn new(obj: T, cleanup: F) -> Self {
Self(Some(obj), cleanup)
}
pub fn finalise(mut self) -> T {
self.0.take().unwrap()
}
}
impl<T, F> Drop for RaiiWrapper<T, F>
where
F: FnMut(T),
{
fn drop(&mut self) {
if let Some(val) = self.0.take() {
(self.1)(val);
}
}
}
impl<T, F> Deref for RaiiWrapper<T, F>
where
F: FnMut(T),
{
type Target = T;
fn deref(&self) -> &Self::Target {
self.0.as_ref().unwrap()
}
}
impl<T, F> DerefMut for RaiiWrapper<T, F>
where
F: FnMut(T),
{
fn deref_mut(&mut self) -> &mut Self::Target {
self.0.as_mut().unwrap()
}
}