sark-http 0.28.2

HTTP wire types, semantics, codecs, and ownership invariants for Sark
Documentation
use crate::{field::metadata::map::record, uri::Error};

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(u8)]
pub enum Scheme {
    None,
    Http,
    Https,
    Other,
}

impl Scheme {
    pub(crate) fn validate(value: &[u8]) -> Result<(), Error> {
        Self::check_span(record::Span::from_slice(value))
    }

    pub fn parse(value: &[u8]) -> Result<Self, Error> {
        Self::parse_span(record::Span::from_slice(value))
    }

    pub fn parse_span(value: record::Span<'_>) -> Result<Self, Error> {
        if value.eq_ascii(b"http") {
            Ok(Self::Http)
        } else if value.eq_ascii(b"https") {
            Ok(Self::Https)
        } else {
            Self::check_span(value)?;
            Ok(Self::Other)
        }
    }

    fn check_span(value: record::Span<'_>) -> Result<(), Error> {
        if !value.get(0).is_some_and(|byte| byte.is_ascii_alphabetic())
            || !value
                .iter()
                .skip(1)
                .all(|byte| byte.is_ascii_alphanumeric() || matches!(*byte, b'+' | b'-' | b'.'))
        {
            return Err(Error::InvalidScheme);
        }
        Ok(())
    }
}