use alloc::boxed::Box;
use core::{cell::Cell, ops::Range};
use super::LeaseStatus;
#[must_use = "byte leases recycle their extent when dropped unless explicitly retained"]
pub struct ByteLease<'pool> {
pub(super) pool_address: usize,
pub(super) identity: &'pool Cell<Box<[u8]>>,
pub(super) slot: usize,
pub(super) generation: u64,
pub(super) range: Range<usize>,
pub(super) status: &'pool Cell<LeaseStatus>,
pub(super) next: &'pool Cell<Option<usize>>,
pub(super) released_lease_head: &'pool Cell<Option<usize>>,
pub(super) storage: &'pool mut [u8],
pub(super) recycle_on_drop: bool,
}
impl ByteLease<'_> {
pub fn byte_capacity(&self) -> usize {
self.storage.len()
}
pub fn bytes(&self) -> &[u8] {
self.storage
}
pub fn bytes_mut(&mut self) -> &mut [u8] {
self.storage
}
pub fn retain(mut self) -> RetainedByteLease {
self.recycle_on_drop = false;
RetainedByteLease {
pool_address: self.pool_address,
identity: self.identity.take(),
slot: self.slot,
generation: self.generation,
range: self.range.clone(),
}
}
}
impl Drop for ByteLease<'_> {
fn drop(&mut self) {
if self.recycle_on_drop && self.status.get() == LeaseStatus::Leased {
self.next.set(self.released_lease_head.get());
self.status.set(LeaseStatus::Released);
self.released_lease_head.set(Some(self.slot));
}
}
}
#[derive(Debug)]
#[must_use = "retained byte leases must be resumed or recycled"]
pub struct RetainedByteLease {
pub(super) pool_address: usize,
pub(super) identity: Box<[u8]>,
pub(super) slot: usize,
pub(super) generation: u64,
pub(super) range: Range<usize>,
}
impl RetainedByteLease {
pub fn byte_capacity(&self) -> usize {
self.range.len()
}
}
impl PartialEq for RetainedByteLease {
fn eq(&self, other: &Self) -> bool {
self.pool_address == other.pool_address
&& self.identity.as_ptr() == other.identity.as_ptr()
&& self.slot == other.slot
&& self.generation == other.generation
&& self.range == other.range
}
}
impl Eq for RetainedByteLease {}