sark-http 0.26.2

HTTP wire types, semantics, codecs, and ownership invariants for Sark
Documentation
pub const CLIENT_PREFACE: &[u8] = b"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";

#[derive(Debug, Default)]
pub struct Prefix(u8);

#[derive(Debug)]
pub struct Complete(());

#[derive(Debug)]
pub enum Read {
    Pending(Prefix),
    Complete(Complete),
}

#[derive(Debug)]
pub struct Mismatch {
    prefix: Prefix,
    offset: u8,
    actual: u8,
}

impl AsRef<[u8]> for Prefix {
    fn as_ref(&self) -> &[u8] {
        &CLIENT_PREFACE[..self.0 as usize]
    }
}

impl Prefix {
    pub fn read(self, bytes: &[u8]) -> Result<(usize, Read), Mismatch> {
        let offset = self.0 as usize;
        let expected = &CLIENT_PREFACE[offset..];
        let count = expected.len().min(bytes.len());
        for (index, (&expected, &actual)) in expected.iter().zip(bytes).enumerate() {
            if actual != expected {
                return Err(Mismatch {
                    prefix: self,
                    offset: (offset + index) as u8,
                    actual,
                });
            }
        }
        let matched = offset + count;
        let read = if matched == CLIENT_PREFACE.len() {
            Read::Complete(Complete(()))
        } else {
            Read::Pending(Self(matched as u8))
        };
        Ok((count, read))
    }
}

impl Mismatch {
    pub fn into_parts(self) -> (Prefix, usize, u8, u8) {
        let offset = self.offset as usize;
        (self.prefix, offset, CLIENT_PREFACE[offset], self.actual)
    }
}