rsonpath-lib 0.3.3

Blazing fast JSONPath query engine powered by SIMD. Core library of `rsonpath`.
Documentation
use super::*;
use aligners::alignment::Alignment;
use aligners::{AlignedBlockIterator, AlignedSlice};

pub(crate) struct SequentialQuoteClassifier<'a> {
    iter: AlignedBlockIterator<'a, alignment::Twice<BlockAlignment>>,
    escaped: bool,
    in_quotes: bool,
    offset: Option<usize>,
}

impl<'a> SequentialQuoteClassifier<'a> {
    #[inline(always)]
    pub(crate) fn new(bytes: &'a AlignedSlice<alignment::Twice<BlockAlignment>>) -> Self {
        Self {
            iter: bytes.iter_blocks(),
            escaped: false,
            in_quotes: false,
            offset: None,
        }
    }
}

impl<'a> Iterator for SequentialQuoteClassifier<'a> {
    type Item = QuoteClassifiedBlock<'a>;

    #[inline(always)]
    fn next(&mut self) -> Option<QuoteClassifiedBlock<'a>> {
        match self.iter.next() {
            Some(block) => {
                let mut mask = 0_u64;
                let mut idx_mask = 1;

                if let Some(offset) = self.offset {
                    self.offset = Some(offset + Self::block_size());
                } else {
                    self.offset = Some(0);
                }

                for character in block.iter().copied() {
                    if !self.escaped && character == b'"' {
                        self.in_quotes = !self.in_quotes;
                    }

                    if character == b'\\' {
                        self.escaped = !self.escaped;
                    } else {
                        self.escaped = false;
                    }

                    if self.in_quotes {
                        mask |= idx_mask;
                    }

                    idx_mask <<= 1;
                }

                Some(QuoteClassifiedBlock {
                    block,
                    within_quotes_mask: mask,
                })
            }
            None => None,
        }
    }
}

impl<'a> std::iter::FusedIterator for SequentialQuoteClassifier<'a> {}

impl<'a> QuoteClassifiedIterator<'a> for SequentialQuoteClassifier<'a> {
    fn block_size() -> usize {
        Twice::<BlockAlignment>::size()
    }

    fn is_empty(&self) -> bool {
        self.iter.len() == 0
    }

    fn get_offset(&self) -> usize {
        self.offset.unwrap_or(0)
    }

    fn offset(&mut self, count: isize) {
        if count == 0 {
            return;
        }

        self.iter.offset(count);
        self.offset = Some(match self.offset {
            None => (count as usize - 1) * Self::block_size(),
            Some(offset) => offset + (count as usize) * Self::block_size(),
        });
    }

    fn flip_quotes_bit(&mut self) {
        self.in_quotes = !self.in_quotes;
    }
}