use std::{marker, mem, ptr};
pub use rejected::Rejected;
pub mod credit;
pub mod lease;
pub mod quota;
pub mod raw;
pub mod rc;
mod rejected;
pub mod slice;
pub mod slot;
pub trait Return {
type Item;
fn return_item(self, item: Self::Item);
}
#[must_use = "dropping the lease returns its item"]
pub struct Lease<R: Return, M = lease::Sealed> {
sink: mem::ManuallyDrop<R>,
item: mem::ManuallyDrop<R::Item>,
mode: marker::PhantomData<M>,
}
impl<R: Return> Lease<R> {
pub const fn new(sink: R, item: R::Item) -> Self {
Self {
sink: mem::ManuallyDrop::new(sink),
item: mem::ManuallyDrop::new(item),
mode: marker::PhantomData,
}
}
}
impl<R: Return> Lease<R, lease::Open> {
pub const fn open(sink: R, item: R::Item) -> Self {
Self {
sink: mem::ManuallyDrop::new(sink),
item: mem::ManuallyDrop::new(item),
mode: marker::PhantomData,
}
}
pub fn item_mut(&mut self) -> &mut R::Item {
&mut self.item
}
pub fn parts_mut(&mut self) -> (&mut R, &mut R::Item) {
(&mut self.sink, &mut self.item)
}
pub fn into_parts(self) -> (R, R::Item) {
let mut this = mem::ManuallyDrop::new(self);
unsafe {
let sink = mem::ManuallyDrop::take(&mut this.sink);
let item = mem::ManuallyDrop::take(&mut this.item);
(sink, item)
}
}
}
impl<R: Return, M> Lease<R, M> {
pub fn sink(&self) -> &R {
&self.sink
}
pub const fn item(&self) -> &R::Item {
unsafe { &*ptr::from_ref(&self.item).cast::<R::Item>() }
}
}
impl<R: Return, M> Drop for Lease<R, M> {
fn drop(&mut self) {
unsafe {
let sink = mem::ManuallyDrop::take(&mut self.sink);
let item = mem::ManuallyDrop::take(&mut self.item);
sink.return_item(item);
}
}
}