use std::{mem, ptr};
pub trait Return {
type Item;
fn return_item(&self, item: Self::Item);
}
#[must_use]
pub struct Lease<R: Return> {
item: mem::ManuallyDrop<R::Item>,
sink: R,
}
impl<R: Return> Lease<R> {
pub fn new(sink: R, item: R::Item) -> Self {
Self {
item: mem::ManuallyDrop::new(item),
sink,
}
}
pub fn sink(&self) -> &R {
&self.sink
}
pub fn item(&self) -> &R::Item {
&self.item
}
pub fn into_parts(self) -> (R, R::Item) {
let mut this = mem::ManuallyDrop::new(self);
unsafe {
let sink = ptr::read(&this.sink);
let item = mem::ManuallyDrop::take(&mut this.item);
(sink, item)
}
}
}
impl<R: Return> Drop for Lease<R> {
fn drop(&mut self) {
let item = unsafe { mem::ManuallyDrop::take(&mut self.item) };
self.sink.return_item(item);
}
}