p1689 0.0.0

Data structures for representing p1689 C++ modules dependency files
Documentation
use alloc::borrow::Cow;

use winnow::{error::ParserError, prelude::*, BStr};

pub(crate) mod json;
pub(crate) mod util;

#[derive(Debug)]
pub(crate) struct Finders {
    #[cfg(target_feature = "avx2")]
    quotes_or_backslash: memchr::arch::x86_64::avx2::memchr::Two,
    #[cfg(all(not(target_feature = "avx2"), target_feature = "sse2"))]
    quotes_or_backslash: memchr::arch::x86_64::sse2::memchr::Two,
    #[cfg(all(not(target_feature = "avx2"), not(target_feature = "sse2")))]
    quotes_or_backslash: memchr::arch::all::memchr::Two,

    #[cfg(all(target_feature = "bmi2", target_feature = "avx2"))]
    curly_close: memchr::arch::x86_64::avx2::memchr::One,
    #[cfg(all(target_feature = "bmi2", not(target_feature = "avx2"), target_feature = "sse2"))]
    curly_close: memchr::arch::x86_64::sse2::memchr::One,
    #[cfg(all(target_feature = "bmi2", not(target_feature = "avx2"), not(target_feature = "sse2")))]
    curly_close: memchr::arch::all::memchr::One,
}
impl Default for Finders {
    fn default() -> Self {
        #[cfg(target_feature = "avx2")]
        let quotes_or_backslash = memchr::arch::x86_64::avx2::memchr::Two::new(b'"', b'\\').unwrap();
        #[cfg(all(not(target_feature = "avx2"), target_feature = "sse2"))]
        let quotes_or_backslash = memchr::arch::x86_64::sse2::memchr::Two::new(b'"', b'\\').unwrap();
        #[cfg(all(not(target_feature = "avx2"), not(target_feature = "sse2")))]
        let quotes_or_backslash = memchr::arch::all::memchr::Two::new(b'"', b'\\');

        #[cfg(all(target_feature = "bmi2", target_feature = "avx2"))]
        let curly_close = memchr::arch::x86_64::avx2::memchr::One::new(b'}').unwrap();
        #[cfg(all(target_feature = "bmi2", not(target_feature = "avx2"), target_feature = "sse2"))]
        let curly_close = memchr::arch::x86_64::sse2::memchr::One::new(b'}').unwrap();
        #[cfg(all(target_feature = "bmi2", not(target_feature = "avx2"), not(target_feature = "sse2")))]
        let curly_close = memchr::arch::all::memchr::One::new(b'}');

        Self {
            quotes_or_backslash,
            #[cfg(target_feature = "bmi2")]
            curly_close,
        }
    }
}

#[derive(Debug)]
pub struct State {
    finders: Finders,
    utf8_encode_buffer: [u8; 4],
}
impl State {
    fn encode_utf8<'i>(&mut self, dst: &mut Cow<'i, BStr>, src: &'i [u8], esc: char) {
        let cow = self::util::cow_to_mut_with_reserve(dst, src.len() + esc.len_utf8());
        let esc = esc.encode_utf8(self.utf8_encode_buffer.as_mut()).as_bytes();
        cow.extend_from_slice(src);
        cow.extend_from_slice(esc);
        self.utf8_encode_buffer = [0u8; 4];
    }

    #[cfg(target_feature = "bmi2")]
    pub fn hex_to_u32<'i, E>(&self, input: &StateStream<'i>) -> PResult<(u32, usize), E>
    where
        E: ParserError<StateStream<'i>>,
    {
        let needle = self.finders.curly_close.find(input).ok_or_else(|| {
            let message = "failed to UCS sequence closing delimiter";
            winnow::error::ErrMode::assert(input, message)
        })?;
        debug_assert!(needle < 8);
        let input = &input[0 .. needle];
        let (lo, hi) = self::util::atoi::u32::split_into_words(input);
        let lo = self::util::atoi::u32::u32_from_u8x4(lo);
        let hi = self::util::atoi::u32::u32_from_u8x4(hi);
        let word = lo + (hi << 16);
        Ok((word, needle))
    }

    #[cfg(not(target_feature = "bmi2"))]
    pub fn hex_to_u32<'i, E>(&self, input: &StateStream<'i>) -> PResult<(u32, usize), E>
    where
        E: ParserError<StateStream<'i>>,
    {
        let mut index = 0;
        let mut number = 0u32;
        while index != input.len() {
            if let Some(digit) = crate::vendor::atoi::u32::ascii_to_hexdigit(input[index]) {
                number *= 16;
                number += digit;
                index += 1;
            } else {
                break;
            }
        }
        Ok((number, index))
    }
}
impl Default for State {
    fn default() -> Self {
        let finders = Finders::default();
        let utf8_encode_buffer = <[u8; 4]>::default();
        Self {
            finders,
            utf8_encode_buffer,
        }
    }
}

pub(crate) type StateStream<'i> = winnow::Stateful<&'i BStr, State>;