sark-h2 0.23.0

Fiber-free HTTP/2 protocol primitives and manifold server for sark
Documentation
use o3::buffer::hold;
use sark_core::life::{self, exchange, owners};
use sark_http::owner::{self, cause};

use crate::stream;

pub(in crate::server) struct Proof {
    pub(super) stream: stream::Key,
    pub(super) charge: hold::Charge,
}

#[derive(Clone, Copy)]
pub(in crate::server) enum Progress {
    Blocked,
    Committed,
}

pub(in crate::server) trait Sink<R> {
    fn progress(&self) -> Progress;

    fn accept(&mut self, receipt: R);

    fn reject(&mut self, receipt: R);
}

pub(in crate::server) struct Track<F> {
    progress: Progress,
    accepted: F,
}

impl<F> Track<F> {
    pub(super) const fn new(accepted: F) -> Self {
        Self {
            progress: Progress::Blocked,
            accepted,
        }
    }
}

impl Sink<()> for Track<()> {
    fn progress(&self) -> Progress {
        self.progress
    }

    fn accept(&mut self, (): ()) {
        self.progress = Progress::Committed;
    }

    fn reject(&mut self, (): ()) {
        self.progress = Progress::Committed;
    }
}

impl<C: Copy, M: life::Mode<C, stream::Key>> Sink<Option<Proof>> for Track<(C, &mut M)> {
    fn progress(&self) -> Progress {
        self.progress
    }

    fn accept(&mut self, receipt: Option<Proof>) {
        self.progress = Progress::Committed;
        if let Some(receipt) = receipt {
            owners::Projection::new(&mut *self.accepted.1).apply(owner::Effect::new(
                exchange::Id::new(self.accepted.0, receipt.stream),
                receipt.charge,
                owner::Change::Handoff,
            ));
        }
    }

    fn reject(&mut self, receipt: Option<Proof>) {
        use cause::Staging;

        self.progress = Progress::Committed;
        if let Some(receipt) = receipt {
            owners::Projection::new(&mut *self.accepted.1).apply(owner::Effect::new(
                exchange::Id::new(self.accepted.0, receipt.stream),
                receipt.charge,
                owner::Change::StagingReleased(Staging::Closed),
            ));
        }
    }
}

const _: () = assert!(std::mem::size_of::<Track<()>>() == 1);