sark-http 0.22.0

HTTP wire types, semantics, codecs, and ownership invariants for Sark
Documentation
use crate::{
    field::metadata::map::record,
    payload::compress::dynamic::{hash, index, mode, table::View},
};

#[derive(Clone, Copy)]
pub struct Search<'a> {
    view: View<'a, mode::Direct>,
}

impl<'a> Search<'a> {
    pub(super) const fn new(view: View<'a, mode::Direct>) -> Self {
        Self { view }
    }

    pub fn get(self, name: &[u8], value: &[u8]) -> record::Match<usize> {
        let state = self.view.state();
        self.both(
            state.hash.probe(record::Entry::new(name, value)),
            state.entries.len(),
            Some,
        )
    }

    pub(super) fn both<I: Copy>(
        self,
        probe: hash::Probe<'_>,
        retained: usize,
        mut map: impl FnMut(usize) -> Option<I>,
    ) -> record::Match<I> {
        if let Some(exact) = self.find_exact(probe, retained, &mut map) {
            return record::Match {
                exact: Some(exact),
                name: Some(exact),
            };
        }
        let name = self.find_needle(probe.needle(), retained, &mut map);
        record::Match { exact: None, name }
    }

    pub(super) fn exact<I: Copy>(
        self,
        probe: hash::Probe<'_>,
        retained: usize,
        mut map: impl FnMut(usize) -> Option<I>,
    ) -> Option<I> {
        self.find_exact(probe, retained, &mut map)
    }

    pub(super) fn needle<I: Copy>(
        self,
        needle: hash::Needle<'_>,
        retained: usize,
        mut map: impl FnMut(usize) -> Option<I>,
    ) -> Option<I> {
        self.find_needle(needle, retained, &mut map)
    }

    fn find_exact<I: Copy>(
        self,
        probe: hash::Probe<'_>,
        retained: usize,
        map: &mut impl FnMut(usize) -> Option<I>,
    ) -> Option<I> {
        let field = probe.field();
        let digest = probe.digest();
        index::Search::new(self.view.lookup(index::Key::Exact)).find(
            digest.exact(),
            |(relative, entry)| {
                if relative < retained
                    && entry.name.is_equal(field.name)
                    && entry.value.is_equal(field.value)
                {
                    map(relative).map(|mapped| (relative, mapped))
                } else {
                    None
                }
            },
        )
    }

    fn find_needle<I: Copy>(
        self,
        needle: hash::Needle<'_>,
        retained: usize,
        map: &mut impl FnMut(usize) -> Option<I>,
    ) -> Option<I> {
        index::Search::new(self.view.lookup(index::Key::Name)).find(
            needle.hash(),
            |(relative, entry)| {
                if relative < retained && entry.name.is_equal(needle.name()) {
                    map(relative).map(|mapped| (relative, mapped))
                } else {
                    None
                }
            },
        )
    }
}