pipecircuit 0.0.22

Correct. Robust. Fast. Portable. Pick four.
Documentation
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 {}