use std::{
mem::ManuallyDrop,
ops::{Deref, DerefMut},
};
pub(crate) struct HandleDrop<Content, Drop: FnOnce(Content)>(ManuallyDrop<(Content, Drop)>);
impl<Content, Drop: FnOnce(Content)> HandleDrop<Content, Drop> {
pub(crate) fn new(content: Content, drop: Drop) -> Self {
Self(ManuallyDrop::new((content, drop)))
}
pub(crate) fn release(mut self) -> Content {
let (content, _) = unsafe { ManuallyDrop::take(&mut self.0) };
std::mem::forget(self);
content
}
}
impl<Content, Drop: FnOnce(Content)> Deref for HandleDrop<Content, Drop> {
type Target = Content;
fn deref(&self) -> &Self::Target {
&self.0.0
}
}
impl<Content, Drop: FnOnce(Content)> DerefMut for HandleDrop<Content, Drop> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0.0
}
}
impl<Content, Drop: FnOnce(Content)> std::ops::Drop for HandleDrop<Content, Drop> {
fn drop(&mut self) {
let (content, drop) = unsafe { ManuallyDrop::take(&mut self.0) };
drop(content)
}
}