sark-http 0.26.3

HTTP wire types, semantics, codecs, and ownership invariants for Sark
Documentation
use core::{num::NonZero, ops};

#[derive(Clone, Copy)]
pub(super) struct Authority(Option<Range>);

pub(super) enum Source {
    Absent,
    Retained(Range),
    Staged(Range),
}

pub(super) enum Stage {
    Absent,
    Retained,
    Staged(Range),
}

#[derive(Clone, Copy)]
pub(super) struct Range {
    first: u32,
    second: NonZero<u32>,
}

impl Authority {
    pub(super) const fn absent() -> Self {
        Self(None)
    }

    pub(super) fn retained(range: ops::Range<usize>) -> Option<Self> {
        Some(Self(Some(Range::retained(range)?)))
    }

    pub(super) fn staged(range: ops::Range<usize>) -> Option<Self> {
        Some(Self(Some(Range::staged(range)?)))
    }

    pub(super) fn source(self) -> Source {
        match self.0 {
            None => Source::Absent,
            Some(saved) => match saved.is_staged() {
                true => Source::Staged(saved),
                false => Source::Retained(saved),
            },
        }
    }

    pub(super) fn stage(self) -> Stage {
        match self.0 {
            None => Stage::Absent,
            Some(saved) => match saved.is_staged() {
                true => Stage::Staged(saved),
                false => Stage::Retained,
            },
        }
    }
}

impl Range {
    fn retained(range: ops::Range<usize>) -> Option<Self> {
        if range.start >= range.end || range.end > u32::MAX as usize {
            return None;
        }
        Some(Self {
            first: range.start as u32,
            second: NonZero::<u32>::new(range.end as u32)?,
        })
    }

    fn staged(range: ops::Range<usize>) -> Option<Self> {
        let retained = Self::retained(range)?;
        Some(Self {
            first: retained.second.get(),
            second: NonZero::<u32>::MIN.saturating_add(retained.first),
        })
    }

    pub(super) const fn is_staged(self) -> bool {
        self.first >= self.second.get()
    }

    pub(super) fn range(self) -> ops::Range<usize> {
        let second = self.second.get();
        if self.first < second {
            self.first as usize..second as usize
        } else {
            second as usize - 1..self.first as usize
        }
    }
}

const _: () = assert!(core::mem::size_of::<Authority>() == 2 * core::mem::size_of::<u32>());