sark-h2 0.29.0

Fiber-free HTTP/2 protocol primitives and manifold server for sark
use o3::{
    alloc,
    buffer::{
        hold::{self, scope},
        pool::{self, owners, state},
        resident,
        segments::{self, queue},
    },
};
use sark_core::life::session;

use crate::conn::{self, event};

#[derive(Clone, Copy)]
pub(in crate::conn) struct Plan {
    pub(in crate::conn) permits: pool::Width<1>,
    pub(in crate::conn) segments: segments::Plan,
}

pub(super) struct Store<C: session::Storage> {
    permits: pool::Pool<state::Uninit, owners::Plain<pool::Width<1>>>,
    segments: segments::Pool<C>,
}

impl<C: session::Storage> Store<C> {
    pub(super) fn try_new(plan: Plan) -> Result<Self, alloc::Error> {
        Ok(Self {
            permits: pool::Pool::try_from(plan.permits)?,
            segments: segments::Pool::try_new(plan.segments)?,
        })
    }

    pub(super) fn try_retain(
        &self,
        bytes: queue::Slice<'_, C>,
        policy: &hold::Retention<C>,
    ) -> Result<event::DataPayload<C>, conn::Error> {
        let permit = self.try_permit()?;
        let segments = bytes.try_bound(&self.segments, policy, crate::INGRESS_RETENTION)?;
        Ok(event::DataPayload::new(segments, permit))
    }

    fn try_permit(
        &self,
    ) -> Result<pool::Span<owners::Plain<pool::Width<1>>, pool::Owned, pool::Frozen>, conn::Error>
    {
        let limit = self.permits.slots();
        let used = limit - self.permits.available();
        Ok(self
            .permits
            .acquire()
            .ok_or(conn::Error::PayloadFull { used, limit })?
            .freeze())
    }
}

impl<'d> Store<resident::Shared<'d>> {
    pub(super) fn try_scoped<R: hold::raw::Retain<'d>>(
        &self,
        source: scope::Bound<'_, 'd, R>,
    ) -> Result<event::DataPayload<resident::Shared<'d>>, conn::Error> {
        let permit = self.try_permit()?;
        let segments = self.segments.try_retain::<R, conn::Error>(source)?;
        Ok(event::DataPayload::new(segments, permit))
    }
}