pipecircuit 0.0.22

Correct. Robust. Fast. Portable. Pick four.
Documentation
use core::num::NonZeroUsize;

use super::{ByteLease, BytePool, BytePoolInconsistency};

#[must_use = "byte-pool reservations must be materialized or released"]
pub struct ByteLeaseReservation<'pool> {
    pub(super) pool: &'pool mut BytePool,
    pub(super) slot: usize,
    pub(super) extent_index: usize,
    pub(super) reserved_maximum: NonZeroUsize,
}

impl<'pool> ByteLeaseReservation<'pool> {
    pub const fn reserved_maximum(&self) -> NonZeroUsize {
        self.reserved_maximum
    }

    pub fn materialize(self, requested: NonZeroUsize) -> BytePoolMaterializeOutcome<'pool> {
        if requested > self.reserved_maximum {
            return BytePoolMaterializeOutcome::ReservationExceeded {
                requested,
                reserved_maximum: self.reserved_maximum,
            };
        }
        match self
            .pool
            .materialize(self.slot, self.extent_index, requested)
        {
            Ok(lease) => BytePoolMaterializeOutcome::Leased(lease),
            Err(reason) => BytePoolMaterializeOutcome::Inconsistent { requested, reason },
        }
    }
}

#[must_use = "byte-pool reserve outcomes must be handled"]
pub enum BytePoolReserveOutcome<'pool> {
    Reserved(ByteLeaseReservation<'pool>),
    Exhausted {
        requested_maximum: NonZeroUsize,
    },
    LeaseCapacityReached {
        requested_maximum: NonZeroUsize,
    },
    LeaseIdentitiesExhausted {
        requested_maximum: NonZeroUsize,
    },
    Inconsistent {
        requested_maximum: NonZeroUsize,
        reason: BytePoolInconsistency,
    },
}

#[must_use = "byte-pool materialization outcomes must be handled"]
pub enum BytePoolMaterializeOutcome<'pool> {
    Leased(ByteLease<'pool>),
    ReservationExceeded {
        requested: NonZeroUsize,
        reserved_maximum: NonZeroUsize,
    },
    Inconsistent {
        requested: NonZeroUsize,
        reason: BytePoolInconsistency,
    },
}