use crate::{
results::StopBecause,
ParseResult,
ParseResult::{Pending, Stop},
};
use alloc::vec::Vec;
use core::{
fmt::Debug,
ops::Range,
slice::SliceIndex,
str::pattern::{Pattern, Searcher},
};
#[cfg(feature = "regex")]
use regex::Match;
#[cfg(feature = "regex-automata")]
use regex_automata::MultiMatch;
#[cfg(feature = "ucd-trie")]
use ucd_trie::TrieSetSlice;
pub mod advance;
mod builtin;
pub mod choice;
mod concat;
pub type Parsed<'i, T> = (ParseState<'i>, T);
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct ParseState<'i> {
pub residual: &'i str,
pub start_offset: usize,
pub stop_reason: Option<StopBecause>,
}
impl<'i> ParseState<'i> {
#[inline(always)]
pub const fn new(input: &'i str) -> Self {
Self { residual: input, start_offset: 0, stop_reason: None }
}
#[inline(always)]
pub const fn with_start_offset(mut self, offset: usize) -> Self {
self.start_offset = offset;
self
}
#[inline(always)]
pub const fn end_offset(&self) -> usize {
self.start_offset + self.residual.len()
}
#[inline(always)]
pub const fn finish<T>(self, value: T) -> ParseResult<'i, T> {
Pending(self, value)
}
#[inline(always)]
pub const fn is_empty(&self) -> bool {
self.residual.is_empty()
}
#[inline(always)]
pub const fn get_error(self) -> StopBecause {
match self.stop_reason {
Some(s) => s,
None => StopBecause::Uninitialized,
}
}
#[inline(always)]
pub const fn set_error(&mut self, error: StopBecause) {
self.stop_reason = Some(error);
}
#[inline(always)]
pub fn get_string<R>(&self, range: R) -> Option<&R::Output>
where
R: SliceIndex<str>,
{
self.residual.get(range)
}
#[inline(always)]
pub fn get_character(&self, nth: usize) -> Option<char> {
self.residual.chars().nth(nth)
}
#[inline(always)]
pub const fn away_from(&self, start: ParseState) -> Range<usize> {
start.start_offset..self.start_offset
}
}