sark-h2 0.23.0

Fiber-free HTTP/2 protocol primitives and manifold server for sark
Documentation
use decode::mode::Discard;
use sark_http::field::metadata::{
    lower,
    section::{rules, storage},
};

use crate::{
    conn::ingress::{Decode, header::sink, headers::Pending},
    hpack::decode::{self, limit::Budget, phase::Phase},
};

pub(super) struct Active<P: rules::Policy> {
    pub(super) pending: Pending,
    pub(super) source: Source<P>,
    pub(super) wire_len: usize,
}

pub(super) enum Source<P: rules::Policy> {
    Store {
        block: Phase<Decode>,
        budget: Budget,
        sink: sink::Header<P>,
    },
    Discard(Phase<Discard>, Budget, storage::Scratch),
}

impl<P: rules::Policy> Source<P> {
    fn decode<'a, A, I>(self, parts: I) -> Result<Self, decode::Failure<lower::Error>>
    where
        A: rules::Push,
        I: IntoIterator<Item = &'a [u8]>,
    {
        match self {
            Self::Store {
                block,
                mut budget,
                sink,
            } => match block.feed_all(&mut budget, parts, sink.hpack::<A>()) {
                Ok((block, sink)) => Ok(Self::Store {
                    block,
                    budget,
                    sink: sink.into_header(),
                }),
                Err((sink, cause)) => {
                    drop(sink.into_header().recycle());
                    Err(cause)
                }
            },
            Self::Discard(block, mut budget, scratch) => {
                match block.feed_all(&mut budget, parts, ()) {
                    Ok((block, ())) => Ok(Self::Discard(block, budget, scratch)),
                    Err(((), cause)) => {
                        drop(scratch);
                        Err(cause.into())
                    }
                }
            }
        }
    }
}

impl<P: rules::Policy> Active<P> {
    pub(super) fn decode<'a, A, I>(
        self,
        parts: I,
        wire_len: usize,
    ) -> Result<Self, decode::Failure<lower::Error>>
    where
        A: rules::Push,
        I: IntoIterator<Item = &'a [u8]>,
    {
        let pending = self.pending;
        let source = self.source.decode::<A, I>(parts)?;
        Ok(Self {
            pending,
            source,
            wire_len,
        })
    }
}