use inspector::Inspector;
pub use crate::stream::{BoxedExactSizeStream, BoxedStream, IterInput, Stream};
use super::*;
use alloc::string::ToString;
#[cfg(feature = "std")]
use std::io::{BufReader, Read, Seek};
pub trait Input<'src>: 'src {
type Span: Span;
type Token: 'src;
type MaybeToken: IntoMaybe<'src, Self::Token>;
type Cursor: Clone;
type Cache;
fn begin(self) -> (Self::Cursor, Self::Cache);
fn cursor_location(cursor: &Self::Cursor) -> usize;
unsafe fn next_maybe(
cache: &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::MaybeToken>;
unsafe fn span(cache: &mut Self::Cache, range: Range<&Self::Cursor>) -> Self::Span;
fn with_context<S: Span>(self, context: S::Context) -> WithContext<S, Self>
where
Self: Sized,
{
WithContext {
input: self,
context,
phantom: EmptyPhantom::new(),
}
}
fn map<T, S, F>(self, eoi: S, f: F) -> MappedInput<'src, T, S, Self, F>
where
Self: Sized,
F: Fn(
Self::MaybeToken,
) -> (
<Self::MaybeToken as IntoMaybe<'src, Self::Token>>::Proj<T>,
<Self::MaybeToken as IntoMaybe<'src, Self::Token>>::Proj<S>,
) + 'src,
T: 'src,
S: Span + 'src,
{
MappedInput {
input: self,
eoi,
mapper: f,
phantom: EmptyPhantom::new(),
}
}
fn split_token_span<T, S>(self, eoi: S) -> MappedInput<'src, T, S, Self>
where
Self: Input<'src, Token = (T, S), MaybeToken = &'src (T, S)> + Sized,
T: 'src,
S: Span + 'src,
{
self.map(eoi, |(t, s)| (t, s))
}
fn split_spanned<T, S>(self, eoi: S) -> MappedInput<'src, T, S, Self>
where
Self: Input<'src, Token = S::Spanned, MaybeToken = &'src S::Spanned> + Sized,
T: 'src,
S: WrappingSpan<T> + 'src,
{
self.map(eoi, |spanned| (S::inner_of(spanned), S::span_of(spanned)))
}
fn map_span<S: Span, F>(self, map_fn: F) -> MappedSpan<S, Self, F>
where
Self: Input<'src> + Sized,
F: Fn(Self::Span) -> S,
{
MappedSpan {
input: self,
map_fn,
phantom: PhantomData,
}
}
}
pub trait ExactSizeInput<'src>: Input<'src> {
unsafe fn span_from(cache: &mut Self::Cache, range: RangeFrom<&Self::Cursor>) -> Self::Span;
}
pub trait SliceInput<'src>: ExactSizeInput<'src> {
type Slice: Clone;
fn full_slice(cache: &mut Self::Cache) -> Self::Slice;
unsafe fn slice(cache: &mut Self::Cache, range: Range<&Self::Cursor>) -> Self::Slice;
unsafe fn slice_from(cache: &mut Self::Cache, from: RangeFrom<&Self::Cursor>) -> Self::Slice;
}
pub trait StrInput<'src>: Sealed + ValueInput<'src, Cursor = usize> + SliceInput<'src>
where
Self::Token: Char,
{
#[doc(hidden)]
fn stringify(slice: Self::Slice) -> String;
}
pub trait ValueInput<'src>: Input<'src> {
unsafe fn next(cache: &mut Self::Cache, cursor: &mut Self::Cursor) -> Option<Self::Token>;
}
pub trait BorrowInput<'src>: Input<'src> {
unsafe fn next_ref(
cache: &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<&'src Self::Token>;
}
impl<'src> Input<'src> for &'src str {
type Cursor = usize;
type Span = SimpleSpan<usize>;
type Token = char;
type MaybeToken = char;
type Cache = Self;
#[inline]
fn begin(self) -> (Self::Cursor, Self::Cache) {
(0, self)
}
#[inline]
fn cursor_location(cursor: &Self::Cursor) -> usize {
*cursor
}
#[inline(always)]
unsafe fn next_maybe(
this: &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::MaybeToken> {
if *cursor < this.len() {
let c = this
.get_unchecked(*cursor..)
.chars()
.next()
.unwrap_unchecked();
*cursor += c.len_utf8();
Some(c)
} else {
None
}
}
#[inline(always)]
unsafe fn span(_this: &mut Self::Cache, range: Range<&Self::Cursor>) -> Self::Span {
(*range.start..*range.end).into()
}
}
impl<'src> ExactSizeInput<'src> for &'src str {
#[inline(always)]
unsafe fn span_from(this: &mut Self::Cache, range: RangeFrom<&Self::Cursor>) -> Self::Span {
(*range.start..this.len()).into()
}
}
impl<'src> ValueInput<'src> for &'src str {
#[inline(always)]
unsafe fn next(this: &mut Self::Cache, cursor: &mut Self::Cursor) -> Option<Self::Token> {
Self::next_maybe(this, cursor)
}
}
impl Sealed for &str {}
impl<'src> StrInput<'src> for &'src str {
#[doc(hidden)]
fn stringify(slice: Self::Slice) -> String {
slice.to_string()
}
}
impl<'src> SliceInput<'src> for &'src str {
type Slice = &'src str;
#[inline(always)]
fn full_slice(this: &mut Self::Cache) -> Self::Slice {
*this
}
#[inline(always)]
unsafe fn slice(this: &mut Self::Cache, range: Range<&Self::Cursor>) -> Self::Slice {
&this[*range.start..*range.end]
}
#[inline(always)]
unsafe fn slice_from(this: &mut Self::Cache, from: RangeFrom<&Self::Cursor>) -> Self::Slice {
&this[*from.start..]
}
}
impl<'src, T> Input<'src> for &'src [T] {
type Cursor = usize;
type Span = SimpleSpan<usize>;
type Token = T;
type MaybeToken = &'src T;
type Cache = Self;
#[inline]
fn begin(self) -> (Self::Cursor, Self::Cache) {
(0, self)
}
#[inline]
fn cursor_location(cursor: &Self::Cursor) -> usize {
*cursor
}
#[inline(always)]
unsafe fn next_maybe(
this: &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::MaybeToken> {
if let Some(tok) = this.get(*cursor) {
*cursor += 1;
Some(tok)
} else {
None
}
}
#[inline(always)]
unsafe fn span(_this: &mut Self::Cache, range: Range<&Self::Cursor>) -> Self::Span {
(*range.start..*range.end).into()
}
}
impl<'src, T> ExactSizeInput<'src> for &'src [T] {
#[inline(always)]
unsafe fn span_from(this: &mut Self::Cache, range: RangeFrom<&Self::Cursor>) -> Self::Span {
(*range.start..this.len()).into()
}
}
impl Sealed for &[u8] {}
impl<'src> StrInput<'src> for &'src [u8] {
#[doc(hidden)]
fn stringify(slice: Self::Slice) -> String {
slice
.iter()
.map(|e| char::from(*e))
.collect()
}
}
impl<'src, T> SliceInput<'src> for &'src [T] {
type Slice = &'src [T];
#[inline(always)]
fn full_slice(this: &mut Self::Cache) -> Self::Slice {
*this
}
#[inline(always)]
unsafe fn slice(this: &mut Self::Cache, range: Range<&Self::Cursor>) -> Self::Slice {
&this[*range.start..*range.end]
}
#[inline(always)]
unsafe fn slice_from(this: &mut Self::Cache, from: RangeFrom<&Self::Cursor>) -> Self::Slice {
&this[*from.start..]
}
}
impl<'src, T: Clone> ValueInput<'src> for &'src [T] {
#[inline(always)]
unsafe fn next(this: &mut Self::Cache, cursor: &mut Self::Cursor) -> Option<Self::Token> {
Self::next_maybe(this, cursor).cloned()
}
}
impl<'src, T> BorrowInput<'src> for &'src [T] {
#[inline(always)]
unsafe fn next_ref(
this: &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<&'src Self::Token> {
Self::next_maybe(this, cursor)
}
}
impl<'src, T: 'src, const N: usize> Input<'src> for &'src [T; N] {
type Cursor = usize;
type Span = SimpleSpan<usize>;
type Token = T;
type MaybeToken = &'src T;
type Cache = Self;
#[inline]
fn begin(self) -> (Self::Cursor, Self::Cache) {
(0, self)
}
#[inline]
fn cursor_location(cursor: &Self::Cursor) -> usize {
*cursor
}
#[inline(always)]
unsafe fn next_maybe(
this: &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::MaybeToken> {
if let Some(tok) = this.get(*cursor) {
*cursor += 1;
Some(tok)
} else {
None
}
}
#[inline(always)]
unsafe fn span(_this: &mut Self::Cache, range: Range<&Self::Cursor>) -> Self::Span {
(*range.start..*range.end).into()
}
}
impl<'src, T: 'src, const N: usize> ExactSizeInput<'src> for &'src [T; N] {
#[inline(always)]
unsafe fn span_from(this: &mut Self::Cache, range: RangeFrom<&Self::Cursor>) -> Self::Span {
(*range.start..this.len()).into()
}
}
impl<const N: usize> Sealed for &[u8; N] {}
impl<'src, const N: usize> StrInput<'src> for &'src [u8; N] {
#[doc(hidden)]
fn stringify(slice: Self::Slice) -> String {
<&[u8]>::stringify(slice)
}
}
impl<'src, T: 'src, const N: usize> SliceInput<'src> for &'src [T; N] {
type Slice = &'src [T];
#[inline(always)]
fn full_slice(this: &mut Self::Cache) -> Self::Slice {
*this
}
#[inline(always)]
unsafe fn slice(this: &mut Self::Cache, range: Range<&Self::Cursor>) -> Self::Slice {
&this[*range.start..*range.end]
}
#[inline(always)]
unsafe fn slice_from(this: &mut Self::Cache, from: RangeFrom<&Self::Cursor>) -> Self::Slice {
&this[*from.start..]
}
}
impl<'src, T: Clone + 'src, const N: usize> ValueInput<'src> for &'src [T; N] {
#[inline(always)]
unsafe fn next(this: &mut Self::Cache, cursor: &mut Self::Cursor) -> Option<Self::Token> {
Self::next_maybe(this, cursor).cloned()
}
}
impl<'src, T: 'src, const N: usize> BorrowInput<'src> for &'src [T; N] {
#[inline(always)]
unsafe fn next_ref(
this: &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<&'src Self::Token> {
Self::next_maybe(this, cursor)
}
}
#[derive(Copy, Clone)]
pub struct MappedInput<
'src,
T,
S,
I,
F = fn(
<I as Input<'src>>::MaybeToken,
) -> (
<<I as Input<'src>>::MaybeToken as IntoMaybe<'src, <I as Input<'src>>::Token>>::Proj<T>,
<<I as Input<'src>>::MaybeToken as IntoMaybe<'src, <I as Input<'src>>::Token>>::Proj<S>,
),
> {
input: I,
eoi: S,
mapper: F,
#[allow(dead_code)]
phantom: EmptyPhantom<&'src T>,
}
impl<'src, T, S, I, F> Input<'src> for MappedInput<'src, T, S, I, F>
where
I: Input<'src>,
T: 'src,
S: Span + Clone + 'src,
F: Fn(
I::MaybeToken,
) -> (
<I::MaybeToken as IntoMaybe<'src, I::Token>>::Proj<T>,
<I::MaybeToken as IntoMaybe<'src, I::Token>>::Proj<S>,
) + 'src,
{
type Cursor = (I::Cursor, Option<S::Offset>);
type Span = S;
type Token = T;
type MaybeToken = <I::MaybeToken as IntoMaybe<'src, I::Token>>::Proj<Self::Token>;
type Cache = (I::Cache, F, S);
#[inline]
fn begin(self) -> (Self::Cursor, Self::Cache) {
let (cursor, cache) = self.input.begin();
((cursor, None), (cache, self.mapper, self.eoi))
}
#[inline]
fn cursor_location(cursor: &Self::Cursor) -> usize {
I::cursor_location(&cursor.0)
}
#[inline(always)]
unsafe fn next_maybe(
(cache, mapper, _): &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::MaybeToken> {
I::next_maybe(cache, &mut cursor.0).map(|tok| {
let (tok, span) = mapper(tok);
cursor.1 = Some(span.borrow().end());
tok
})
}
#[inline]
unsafe fn span(
(cache, mapper, eoi): &mut Self::Cache,
range: Range<&Self::Cursor>,
) -> Self::Span {
match I::next_maybe(cache, &mut range.start.0.clone()) {
Some(tok) => {
let start = mapper(tok).1.borrow().start();
let end = range.end.1.clone().unwrap_or_else(|| eoi.end());
S::new(eoi.context(), start..end)
}
None => S::new(eoi.context(), eoi.end()..eoi.end()),
}
}
}
impl<'src, T, S, I, F> ExactSizeInput<'src> for MappedInput<'src, T, S, I, F>
where
I: ExactSizeInput<'src>,
T: 'src,
S: Span + Clone + 'src,
F: Fn(
I::MaybeToken,
) -> (
<I::MaybeToken as IntoMaybe<'src, I::Token>>::Proj<T>,
<I::MaybeToken as IntoMaybe<'src, I::Token>>::Proj<S>,
) + 'src,
{
#[inline(always)]
unsafe fn span_from(
(cache, mapper, eoi): &mut Self::Cache,
range: RangeFrom<&Self::Cursor>,
) -> Self::Span {
let start = I::next_maybe(cache, &mut range.start.0.clone())
.map(|tok| mapper(tok).1.borrow().start())
.unwrap_or_else(|| eoi.end());
S::new(eoi.context(), start..eoi.end())
}
}
impl<'src, T, S, I, F> ValueInput<'src> for MappedInput<'src, T, S, I, F>
where
I: ValueInput<'src>,
T: Clone + 'src,
S: Span + Clone + 'src,
F: Fn(
I::MaybeToken,
) -> (
<I::MaybeToken as IntoMaybe<'src, I::Token>>::Proj<T>,
<I::MaybeToken as IntoMaybe<'src, I::Token>>::Proj<S>,
) + 'src,
{
#[inline(always)]
unsafe fn next(
(cache, mapper, _): &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::Token> {
I::next_maybe(cache, &mut cursor.0).map(|tok| {
let (tok, span) = mapper(tok);
cursor.1 = Some(span.borrow().end());
tok.borrow().clone()
})
}
}
impl<'src, T, S, I, F> BorrowInput<'src> for MappedInput<'src, T, S, I, F>
where
I: Input<'src> + BorrowInput<'src>,
I::MaybeToken: From<&'src I::Token>,
Self::MaybeToken: Into<&'src Self::Token>,
T: 'src,
S: Span + Clone + 'src,
F: Fn(
I::MaybeToken,
) -> (
<I::MaybeToken as IntoMaybe<'src, I::Token>>::Proj<T>,
<I::MaybeToken as IntoMaybe<'src, I::Token>>::Proj<S>,
) + 'src,
{
#[inline(always)]
unsafe fn next_ref(
(cache, mapper, _): &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<&'src Self::Token> {
I::next_ref(cache, &mut cursor.0).map(|tok| {
let (tok, span) = mapper(tok.into());
cursor.1 = Some(span.borrow().end());
tok.into()
})
}
}
impl<'src, T, S, I, F> SliceInput<'src> for MappedInput<'src, T, S, I, F>
where
I: Input<'src> + SliceInput<'src, Token = (T, S)>,
T: 'src,
S: Span + Clone + 'src,
F: Fn(
I::MaybeToken,
) -> (
<I::MaybeToken as IntoMaybe<'src, I::Token>>::Proj<T>,
<I::MaybeToken as IntoMaybe<'src, I::Token>>::Proj<S>,
) + 'src,
{
type Slice = I::Slice;
#[inline(always)]
fn full_slice((cache, _, _): &mut Self::Cache) -> Self::Slice {
I::full_slice(cache)
}
#[inline(always)]
unsafe fn slice((cache, _, _): &mut Self::Cache, range: Range<&Self::Cursor>) -> Self::Slice {
I::slice(cache, &range.start.0..&range.end.0)
}
#[inline(always)]
unsafe fn slice_from(
(cache, _, _): &mut Self::Cache,
from: RangeFrom<&Self::Cursor>,
) -> Self::Slice {
I::slice_from(cache, &from.start.0..)
}
}
#[derive(Copy, Clone)]
pub struct MappedSpan<S: Span, I, F> {
input: I,
map_fn: F,
phantom: PhantomData<S>,
}
impl<'src, S, I: Input<'src>, F: 'src> Input<'src> for MappedSpan<S, I, F>
where
S: Span + Clone + 'src,
S::Context: Clone + 'src,
S::Offset: From<<I::Span as Span>::Offset>,
F: Fn(I::Span) -> S,
{
type Cursor = I::Cursor;
type Span = S;
type Token = I::Token;
type MaybeToken = I::MaybeToken;
type Cache = (I::Cache, F);
#[inline(always)]
fn begin(self) -> (Self::Cursor, Self::Cache) {
let (cursor, cache) = self.input.begin();
(cursor, (cache, self.map_fn))
}
#[inline]
fn cursor_location(cursor: &Self::Cursor) -> usize {
I::cursor_location(cursor)
}
#[inline(always)]
unsafe fn next_maybe(
(cache, _): &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::MaybeToken> {
I::next_maybe(cache, cursor)
}
#[inline]
unsafe fn span((cache, mapper): &mut Self::Cache, range: Range<&Self::Cursor>) -> Self::Span {
let inner_span = I::span(cache, range);
(mapper)(inner_span)
}
}
impl<'src, S, I: Input<'src>, F: 'src> ExactSizeInput<'src> for MappedSpan<S, I, F>
where
I: ExactSizeInput<'src>,
S: Span + Clone + 'src,
S::Context: Clone + 'src,
S::Offset: From<<I::Span as Span>::Offset>,
F: Fn(I::Span) -> S,
{
#[inline(always)]
unsafe fn span_from(
(cache, mapper): &mut Self::Cache,
range: RangeFrom<&Self::Cursor>,
) -> Self::Span {
let inner_span = I::span_from(cache, range);
(mapper)(inner_span)
}
}
impl<'src, S, I: ValueInput<'src>, F: 'src> ValueInput<'src> for MappedSpan<S, I, F>
where
S: Span + Clone + 'src,
S::Context: Clone + 'src,
S::Offset: From<<I::Span as Span>::Offset>,
F: Fn(I::Span) -> S,
{
#[inline(always)]
unsafe fn next((cache, _): &mut Self::Cache, cursor: &mut Self::Cursor) -> Option<Self::Token> {
I::next(cache, cursor)
}
}
impl<'src, S, I: BorrowInput<'src>, F: 'src> BorrowInput<'src> for MappedSpan<S, I, F>
where
S: Span + Clone + 'src,
S::Context: Clone + 'src,
S::Offset: From<<I::Span as Span>::Offset>,
F: Fn(I::Span) -> S,
{
#[inline(always)]
unsafe fn next_ref(
(cache, _): &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<&'src Self::Token> {
I::next_ref(cache, cursor)
}
}
impl<'src, S, I: SliceInput<'src>, F: 'src> SliceInput<'src> for MappedSpan<S, I, F>
where
S: Span + Clone + 'src,
S::Context: Clone + 'src,
S::Offset: From<<I::Span as Span>::Offset>,
F: Fn(I::Span) -> S,
{
type Slice = I::Slice;
#[inline(always)]
fn full_slice((cache, _): &mut Self::Cache) -> Self::Slice {
I::full_slice(cache)
}
#[inline(always)]
unsafe fn slice((cache, _): &mut Self::Cache, range: Range<&Self::Cursor>) -> Self::Slice {
I::slice(cache, range)
}
#[inline(always)]
unsafe fn slice_from(
(cache, _): &mut Self::Cache,
from: RangeFrom<&Self::Cursor>,
) -> Self::Slice {
I::slice_from(cache, from)
}
}
impl<'src, S, I, F: 'src> Sealed for MappedSpan<S, I, F>
where
I: Input<'src>,
S: Span + Clone + 'src,
S::Context: Clone + 'src,
S::Offset: From<<I::Span as Span>::Offset>,
F: Fn(I::Span) -> S,
{
}
impl<'src, S, I, F: 'src> StrInput<'src> for MappedSpan<S, I, F>
where
I: StrInput<'src>,
I::Token: Char,
S: Span + Clone + 'src,
S::Context: Clone + 'src,
S::Offset: From<<I::Span as Span>::Offset>,
F: Fn(I::Span) -> S,
{
#[doc(hidden)]
fn stringify(slice: Self::Slice) -> String {
I::stringify(slice)
}
}
#[derive(Copy, Clone)]
pub struct WithContext<S: Span, I> {
input: I,
context: S::Context,
#[allow(dead_code)]
phantom: EmptyPhantom<S>,
}
impl<'src, S, I: Input<'src>> Input<'src> for WithContext<S, I>
where
S: Span + Clone + 'src,
S::Context: Clone + 'src,
S::Offset: From<<I::Span as Span>::Offset>,
{
type Cursor = I::Cursor;
type Span = S;
type Token = I::Token;
type MaybeToken = I::MaybeToken;
type Cache = (I::Cache, S::Context);
#[inline(always)]
fn begin(self) -> (Self::Cursor, Self::Cache) {
let (cursor, cache) = self.input.begin();
(cursor, (cache, self.context))
}
#[inline]
fn cursor_location(cursor: &Self::Cursor) -> usize {
I::cursor_location(cursor)
}
#[inline(always)]
unsafe fn next_maybe(
(cache, _): &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::MaybeToken> {
I::next_maybe(cache, cursor)
}
#[inline]
unsafe fn span((cache, ctx): &mut Self::Cache, range: Range<&Self::Cursor>) -> Self::Span {
let inner_span = I::span(cache, range);
S::new(
ctx.clone(),
inner_span.start().into()..inner_span.end().into(),
)
}
}
impl<'src, S, I: Input<'src>> ExactSizeInput<'src> for WithContext<S, I>
where
I: ExactSizeInput<'src>,
S: Span + Clone + 'src,
S::Context: Clone + 'src,
S::Offset: From<<I::Span as Span>::Offset>,
{
#[inline]
unsafe fn span_from(
(cache, ctx): &mut Self::Cache,
range: RangeFrom<&Self::Cursor>,
) -> Self::Span {
let inner_span = I::span_from(cache, range);
S::new(
ctx.clone(),
inner_span.start().into()..inner_span.end().into(),
)
}
}
impl<'src, S, I: ValueInput<'src>> ValueInput<'src> for WithContext<S, I>
where
S: Span + Clone + 'src,
S::Context: Clone + 'src,
S::Offset: From<<I::Span as Span>::Offset>,
{
#[inline(always)]
unsafe fn next((cache, _): &mut Self::Cache, cursor: &mut Self::Cursor) -> Option<Self::Token> {
I::next(cache, cursor)
}
}
impl<'src, S, I: BorrowInput<'src>> BorrowInput<'src> for WithContext<S, I>
where
S: Span + Clone + 'src,
S::Context: Clone + 'src,
S::Offset: From<<I::Span as Span>::Offset>,
{
#[inline(always)]
unsafe fn next_ref(
(cache, _): &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<&'src Self::Token> {
I::next_ref(cache, cursor)
}
}
impl<'src, S, I: SliceInput<'src>> SliceInput<'src> for WithContext<S, I>
where
S: Span + Clone + 'src,
S::Context: Clone + 'src,
S::Offset: From<<I::Span as Span>::Offset>,
{
type Slice = I::Slice;
#[inline(always)]
fn full_slice((cache, _): &mut Self::Cache) -> Self::Slice {
I::full_slice(cache)
}
#[inline(always)]
unsafe fn slice((cache, _): &mut Self::Cache, range: Range<&Self::Cursor>) -> Self::Slice {
I::slice(cache, range)
}
#[inline(always)]
unsafe fn slice_from(
(cache, _): &mut Self::Cache,
from: RangeFrom<&Self::Cursor>,
) -> Self::Slice {
I::slice_from(cache, from)
}
}
impl<S: Span, I> Sealed for WithContext<S, I> {}
impl<'src, S, I> StrInput<'src> for WithContext<S, I>
where
I: StrInput<'src>,
I::Token: Char,
S: Span + Clone + 'src,
S::Context: Clone + 'src,
S::Offset: From<<I::Span as Span>::Offset>,
{
#[doc(hidden)]
fn stringify(slice: Self::Slice) -> String {
I::stringify(slice)
}
}
#[cfg(feature = "std")]
pub struct IoInput<R> {
reader: BufReader<R>,
last_cursor: usize,
}
#[cfg(feature = "std")]
impl<R: Read + Seek> IoInput<R> {
pub fn new(reader: R) -> IoInput<R> {
IoInput {
reader: BufReader::new(reader),
last_cursor: 0,
}
}
}
#[cfg(feature = "std")]
impl<'src, R: Read + Seek + 'src> Input<'src> for IoInput<R> {
type Cursor = usize;
type Span = SimpleSpan;
type Token = u8;
type MaybeToken = u8;
type Cache = Self;
fn begin(self) -> (Self::Cursor, Self::Cache) {
(0, self)
}
#[inline(always)]
fn cursor_location(cursor: &Self::Cursor) -> usize {
*cursor
}
#[inline(always)]
unsafe fn next_maybe(
this: &mut Self::Cache,
cursor: &mut Self::Cursor,
) -> Option<Self::MaybeToken> {
Self::next(this, cursor)
}
#[inline]
unsafe fn span(_this: &mut Self::Cache, range: Range<&Self::Cursor>) -> Self::Span {
(*range.start..*range.end).into()
}
}
#[cfg(feature = "std")]
impl<'src, R: Read + Seek + 'src> ValueInput<'src> for IoInput<R> {
unsafe fn next(this: &mut Self::Cache, cursor: &mut Self::Cursor) -> Option<Self::Token> {
if *cursor != this.last_cursor {
let seek = *cursor as i64 - this.last_cursor as i64;
this.reader.seek_relative(seek).unwrap();
this.last_cursor = *cursor;
}
let mut out = 0;
let r = this.reader.read_exact(std::slice::from_mut(&mut out));
match r {
Ok(()) => {
this.last_cursor += 1;
*cursor += 1;
Some(out)
}
Err(_) => None,
}
}
}
pub struct Checkpoint<'src, 'parse, I: Input<'src>, C> {
cursor: Cursor<'src, 'parse, I>,
pub(crate) err_count: usize,
pub(crate) inspector: C,
phantom: PhantomData<fn(&'parse ()) -> &'parse ()>, }
impl<'src, 'parse, I: Input<'src>, C> Checkpoint<'src, 'parse, I, C> {
pub fn cursor(&self) -> &Cursor<'src, 'parse, I> {
&self.cursor
}
pub fn inspector(&self) -> &C {
&self.inspector
}
}
impl<'src, I: Input<'src>, C: Clone> Clone for Checkpoint<'src, '_, I, C> {
#[inline(always)]
fn clone(&self) -> Self {
Self {
cursor: self.cursor.clone(),
err_count: self.err_count,
inspector: self.inspector.clone(),
phantom: PhantomData,
}
}
}
#[repr(transparent)]
pub struct Cursor<'src, 'parse, I: Input<'src>> {
pub(crate) inner: I::Cursor,
phantom: PhantomData<fn(&'parse ()) -> &'parse ()>, }
impl<'src, I: Input<'src>> Cursor<'src, '_, I> {
pub fn inner(&self) -> &I::Cursor {
&self.inner
}
}
impl<'src, I: Input<'src>> Clone for Cursor<'src, '_, I> {
#[inline(always)]
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
phantom: PhantomData,
}
}
}
impl<'src, I: Input<'src>> Eq for Cursor<'src, '_, I> {}
impl<'src, I: Input<'src>> PartialEq for Cursor<'src, '_, I> {
fn eq(&self, other: &Self) -> bool {
I::cursor_location(&self.inner)
.cmp(&I::cursor_location(&other.inner))
.is_eq()
}
}
impl<'src, I: Input<'src>> PartialOrd for Cursor<'src, '_, I> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<'src, I: Input<'src>> Ord for Cursor<'src, '_, I> {
fn cmp(&self, other: &Self) -> Ordering {
I::cursor_location(&self.inner).cmp(&I::cursor_location(&other.inner))
}
}
pub(crate) struct Errors<T, E> {
pub(crate) alt: Option<Located<T, E>>,
pub(crate) secondary: Vec<Located<T, E>>,
}
impl<T, E> Errors<T, E> {
#[inline]
pub(crate) fn secondary_errors_since(&mut self, err_count: usize) -> &mut [Located<T, E>] {
self.secondary.get_mut(err_count..).unwrap_or(&mut [])
}
}
impl<T, E> Default for Errors<T, E> {
fn default() -> Self {
Self {
alt: None,
secondary: Vec::new(),
}
}
}
pub(crate) struct InputOwn<'src, 's, I: Input<'src>, E: ParserExtra<'src, I>> {
pub(crate) start: I::Cursor,
pub(crate) cache: I::Cache,
pub(crate) errors: Errors<I::Cursor, E::Error>,
pub(crate) state: MaybeMut<'s, E::State>,
pub(crate) ctx: E::Context,
#[cfg(feature = "memoization")]
pub(crate) memos: HashMap<(usize, usize), Option<Located<I::Cursor, E::Error>>>,
}
impl<'src, 's, I, E> InputOwn<'src, 's, I, E>
where
I: Input<'src>,
E: ParserExtra<'src, I>,
{
#[cfg_attr(not(test), allow(dead_code))]
pub(crate) fn new(input: I) -> InputOwn<'src, 's, I, E>
where
E::State: Default,
E::Context: Default,
{
let (start, cache) = input.begin();
InputOwn {
start,
cache,
errors: Errors::default(),
state: MaybeMut::Val(E::State::default()),
ctx: E::Context::default(),
#[cfg(feature = "memoization")]
memos: HashMap::default(),
}
}
pub(crate) fn new_state(input: I, state: &'s mut E::State) -> InputOwn<'src, 's, I, E>
where
E::Context: Default,
{
let (start, cache) = input.begin();
InputOwn {
start,
cache,
errors: Errors::default(),
state: MaybeMut::Ref(state),
ctx: E::Context::default(),
#[cfg(feature = "memoization")]
memos: HashMap::default(),
}
}
pub(crate) fn as_ref_start<'parse>(&'parse mut self) -> InputRef<'src, 'parse, I, E> {
InputRef {
cursor: self.start.clone(),
cache: &mut self.cache,
errors: &mut self.errors,
state: &mut self.state,
ctx: &self.ctx,
#[cfg(feature = "memoization")]
memos: &mut self.memos,
}
}
pub(crate) fn into_errs(self) -> Vec<E::Error> {
self.errors
.secondary
.into_iter()
.map(|err| err.err)
.collect()
}
}
pub struct InputRef<'src, 'parse, I: Input<'src>, E: ParserExtra<'src, I>> {
cursor: I::Cursor,
pub(crate) cache: &'parse mut I::Cache,
pub(crate) errors: &'parse mut Errors<I::Cursor, E::Error>,
pub(crate) state: &'parse mut E::State,
pub(crate) ctx: &'parse E::Context,
#[cfg(feature = "memoization")]
pub(crate) memos: &'parse mut HashMap<(usize, usize), Option<Located<I::Cursor, E::Error>>>,
}
impl<'src, 'parse, I: Input<'src>, E: ParserExtra<'src, I>> InputRef<'src, 'parse, I, E> {
#[inline]
pub(crate) fn with_ctx<'sub_parse, EM, O>(
&'sub_parse mut self,
new_ctx: &'sub_parse EM::Context,
f: impl FnOnce(&mut InputRef<'src, 'sub_parse, I, EM>) -> O,
) -> O
where
'parse: 'sub_parse,
EM: ParserExtra<'src, I, Error = E::Error, State = E::State>,
{
let mut new_inp = InputRef {
cursor: self.cursor.clone(),
cache: self.cache,
state: self.state,
ctx: new_ctx,
errors: self.errors,
#[cfg(feature = "memoization")]
memos: self.memos,
};
let res = f(&mut new_inp);
self.cursor = new_inp.cursor;
res
}
#[inline]
pub(crate) fn with_state<'sub_parse, S, O>(
&'sub_parse mut self,
new_state: &'sub_parse mut S,
f: impl FnOnce(&mut InputRef<'src, 'sub_parse, I, extra::Full<E::Error, S, E::Context>>) -> O,
) -> O
where
'parse: 'sub_parse,
S: Inspector<'src, I>,
{
let mut new_inp = InputRef {
cursor: self.cursor.clone(),
cache: self.cache,
state: new_state,
ctx: self.ctx,
errors: self.errors,
#[cfg(feature = "memoization")]
memos: self.memos,
};
let res = f(&mut new_inp);
self.cursor = new_inp.cursor;
res
}
#[inline]
pub(crate) fn with_input<'sub_parse, J, F, O>(
&'sub_parse mut self,
start: J::Cursor,
cache: &'sub_parse mut J::Cache,
new_errors: &'sub_parse mut Errors<J::Cursor, F::Error>,
f: impl FnOnce(&mut InputRef<'src, 'sub_parse, J, F>) -> O,
#[cfg(feature = "memoization")] memos: &'sub_parse mut HashMap<
(usize, usize),
Option<Located<J::Cursor, E::Error>>,
>,
) -> O
where
'parse: 'sub_parse,
J: Input<'src>,
F: ParserExtra<'src, J, State = E::State, Context = E::Context, Error = E::Error>,
{
let mut new_inp = InputRef {
cursor: start,
cache,
state: self.state,
ctx: self.ctx,
errors: new_errors,
#[cfg(feature = "memoization")]
memos,
};
let out = f(&mut new_inp);
self.errors.secondary.extend(
new_inp
.errors
.secondary
.drain(..)
.map(|err| Located::at(self.cursor.clone(), err.err)),
);
if let Some(alt) = new_inp.errors.alt.take() {
self.errors.alt = Some(Located::at(self.cursor.clone(), alt.err));
}
out
}
#[inline(always)]
pub fn cursor(&self) -> Cursor<'src, 'parse, I> {
Cursor {
inner: self.cursor.clone(),
phantom: PhantomData,
}
}
#[inline(always)]
pub fn save(
&self,
) -> Checkpoint<'src, 'parse, I, <E::State as Inspector<'src, I>>::Checkpoint> {
let cursor = self.cursor();
let inspector = self.state.on_save(&cursor);
Checkpoint {
cursor,
err_count: self.errors.secondary.len(),
inspector,
phantom: PhantomData,
}
}
#[inline(always)]
pub fn rewind(
&mut self,
checkpoint: Checkpoint<'src, 'parse, I, <E::State as Inspector<'src, I>>::Checkpoint>,
) {
self.errors.secondary.truncate(checkpoint.err_count);
self.state.on_rewind(&checkpoint);
self.cursor = checkpoint.cursor.inner;
}
#[inline(always)]
pub(crate) fn rewind_input(
&mut self,
checkpoint: Checkpoint<'src, 'parse, I, <E::State as Inspector<'src, I>>::Checkpoint>,
) {
self.cursor = checkpoint.cursor.inner;
}
#[inline(always)]
pub fn state(&mut self) -> &mut E::State {
self.state
}
#[inline(always)]
pub fn ctx(&self) -> &E::Context {
self.ctx
}
#[inline]
pub(crate) fn skip_while<F: FnMut(&I::Token) -> bool>(&mut self, mut f: F)
where
I: Input<'src>,
{
loop {
let mut cursor = self.cursor.clone();
let token = unsafe { I::next_maybe(self.cache, &mut cursor) };
if token.as_ref().filter(|tok| f((*tok).borrow())).is_none() {
break;
} else {
if let Some(t) = &token {
self.state.on_token(t.borrow());
}
self.cursor = cursor;
}
}
}
#[inline(always)]
pub(crate) fn next_inner(&mut self) -> Option<I::Token>
where
I: ValueInput<'src>,
{
let token = unsafe { I::next(self.cache, &mut self.cursor) };
if let Some(t) = &token {
self.state.on_token(t);
}
token
}
#[inline(always)]
pub(crate) fn next_maybe_inner(&mut self) -> Option<I::MaybeToken> {
let token = unsafe { I::next_maybe(self.cache, &mut self.cursor) };
if let Some(t) = &token {
self.state.on_token(t.borrow());
}
token
}
#[inline(always)]
pub(crate) fn next_ref_inner(&mut self) -> Option<&'src I::Token>
where
I: BorrowInput<'src>,
{
let token = unsafe { I::next_ref(self.cache, &mut self.cursor) };
if let Some(t) = &token {
self.state.on_token(t);
}
token
}
pub fn parse<O, P: Parser<'src, I, O, E>>(&mut self, parser: P) -> Result<O, E::Error> {
match parser.go::<Emit>(self) {
Ok(out) => Ok(out),
Err(()) => Err(self.take_alt().unwrap().err),
}
}
pub fn check<O, P: Parser<'src, I, O, E>>(&mut self, parser: P) -> Result<(), E::Error> {
match parser.go::<Check>(self) {
Ok(()) => Ok(()),
Err(()) => Err(self.take_alt().unwrap().err),
}
}
#[inline(always)]
pub fn next_maybe(&mut self) -> Option<MaybeRef<'src, I::Token>> {
self.next_maybe_inner().map(Into::into)
}
#[inline(always)]
pub fn next(&mut self) -> Option<I::Token>
where
I: ValueInput<'src>,
{
self.next_inner()
}
#[inline(always)]
pub fn next_ref(&mut self) -> Option<&'src I::Token>
where
I: BorrowInput<'src>,
{
self.next_ref_inner()
}
#[inline(always)]
pub fn peek_maybe(&mut self) -> Option<MaybeRef<'src, I::Token>> {
unsafe { I::next_maybe(self.cache, &mut self.cursor.clone()).map(Into::into) }
}
#[inline(always)]
pub fn peek(&mut self) -> Option<I::Token>
where
I: ValueInput<'src>,
{
unsafe { I::next(self.cache, &mut self.cursor.clone()) }
}
#[inline(always)]
pub fn peek_ref(&mut self) -> Option<&'src I::Token>
where
I: BorrowInput<'src>,
{
unsafe { I::next_ref(self.cache, &mut self.cursor.clone()) }
}
#[inline(always)]
pub fn skip(&mut self)
where
I: ValueInput<'src>,
{
let _ = self.next_inner();
}
#[cfg_attr(not(feature = "regex"), allow(dead_code))]
#[inline]
pub fn full_slice(&mut self) -> I::Slice
where
I: SliceInput<'src>,
{
I::full_slice(self.cache)
}
#[inline]
pub fn slice(&mut self, range: Range<&Cursor<'src, 'parse, I>>) -> I::Slice
where
I: SliceInput<'src>,
{
unsafe { I::slice(self.cache, &range.start.inner..&range.end.inner) }
}
#[inline]
pub fn slice_from(&mut self, range: RangeFrom<&Cursor<'src, 'parse, I>>) -> I::Slice
where
I: SliceInput<'src>,
{
unsafe { I::slice_from(self.cache, &range.start.inner..) }
}
#[inline]
pub fn slice_since(&mut self, range: RangeFrom<&Cursor<'src, 'parse, I>>) -> I::Slice
where
I: SliceInput<'src>,
{
unsafe { I::slice(self.cache, &range.start.inner..&self.cursor) }
}
#[cfg_attr(not(feature = "lexical-numbers"), allow(dead_code))]
#[inline(always)]
pub(crate) fn slice_trailing_inner(&mut self) -> I::Slice
where
I: SliceInput<'src>,
{
unsafe { I::slice_from(self.cache, &self.cursor..) }
}
#[inline(always)]
pub fn span_from(&mut self, range: RangeFrom<&Cursor<'src, 'parse, I>>) -> I::Span
where
I: ExactSizeInput<'src>,
{
unsafe { I::span_from(self.cache, &range.start.inner..) }
}
#[inline(always)]
pub fn span_since(&mut self, before: &Cursor<'src, 'parse, I>) -> I::Span {
unsafe { I::span(self.cache, &before.inner..&self.cursor) }
}
#[inline(always)]
#[cfg(any(feature = "regex", feature = "lexical-numbers"))]
pub(crate) unsafe fn skip_bytes(&mut self, skip: usize)
where
I: SliceInput<'src, Cursor = usize>,
{
self.cursor += skip;
}
#[inline]
pub fn emit(&mut self, error: E::Error) {
self.emit_inner(None, error);
}
#[inline]
pub fn emit_at(&mut self, cursor: Cursor<'src, 'parse, I>, error: E::Error) {
self.emit_inner(Some(cursor), error);
}
#[inline]
fn emit_inner(&mut self, cursor: impl Into<Option<Cursor<'src, 'parse, I>>>, error: E::Error) {
let cursor = cursor
.into()
.map(|c| c.inner)
.unwrap_or_else(|| self.cursor.clone());
self.errors.secondary.push(Located::at(cursor, error));
}
#[inline]
pub(crate) fn add_alt<Exp, L>(
&mut self,
expected: Exp,
found: Option<MaybeRef<'src, I::Token>>,
span: I::Span,
) where
Exp: IntoIterator<Item = L>,
E::Error: LabelError<'src, I, L>,
{
if core::mem::size_of::<E::Error>() == 0 {
self.errors.alt = Some(Located::at(
self.cursor.clone(),
LabelError::expected_found(expected, found, span),
));
return;
}
let at = &self.cursor;
self.errors.alt = Some(match self.errors.alt.take() {
Some(alt) => match I::cursor_location(&alt.pos).cmp(&I::cursor_location(at)) {
Ordering::Equal => {
Located::at(alt.pos, alt.err.merge_expected_found(expected, found, span))
}
Ordering::Greater => alt,
Ordering::Less => Located::at(
at.clone(),
alt.err.replace_expected_found(expected, found, span),
),
},
None => Located::at(
at.clone(),
LabelError::expected_found(expected, found, span),
),
});
}
#[inline]
pub(crate) fn add_alt_err(&mut self, at: &I::Cursor, err: E::Error) {
if core::mem::size_of::<E::Error>() == 0 {
self.errors.alt = Some(Located::at(self.cursor.clone(), err));
return;
}
self.errors.alt = Some(match self.errors.alt.take() {
Some(alt) => match I::cursor_location(&alt.pos).cmp(&I::cursor_location(at)) {
Ordering::Equal => Located::at(alt.pos, alt.err.merge(err)),
Ordering::Greater => alt,
Ordering::Less => Located::at(at.clone(), err),
},
None => Located::at(at.clone(), err),
});
}
pub(crate) fn take_alt(&mut self) -> Option<Located<I::Cursor, E::Error>> {
self.errors.alt.take()
}
}
pub struct Emitter<E> {
emitted: Vec<E>,
}
impl<E> Emitter<E> {
#[inline]
pub(crate) fn new() -> Emitter<E> {
Emitter {
emitted: Vec::new(),
}
}
#[inline]
pub(crate) fn errors(self) -> Vec<E> {
self.emitted
}
#[inline]
pub fn emit(&mut self, err: E) {
self.emitted.push(err)
}
}
pub struct MapExtra<'src, 'b, I: Input<'src>, E: ParserExtra<'src, I>> {
before: &'b I::Cursor,
after: &'b I::Cursor,
cache: &'b mut I::Cache,
state: &'b mut E::State,
ctx: &'b E::Context,
emitted: &'b mut Errors<I::Cursor, E::Error>,
}
impl<'src, 'b, I: Input<'src>, E: ParserExtra<'src, I>> MapExtra<'src, 'b, I, E> {
#[inline(always)]
pub(crate) fn new<'parse>(
before: &'b Cursor<'src, 'parse, I>,
inp: &'b mut InputRef<'src, 'parse, I, E>,
) -> Self {
Self {
before: &before.inner,
after: &inp.cursor,
cache: inp.cache,
ctx: inp.ctx,
state: inp.state,
emitted: &mut inp.errors,
}
}
#[inline(always)]
pub fn span(&mut self) -> I::Span {
unsafe { I::span(self.cache, self.before..self.after) }
}
#[inline(always)]
pub fn slice(&mut self) -> I::Slice
where
I: SliceInput<'src>,
{
unsafe { I::slice(self.cache, self.before..self.after) }
}
#[inline(always)]
pub fn state(&mut self) -> &mut E::State {
self.state
}
#[inline(always)]
pub fn ctx(&self) -> &E::Context {
self.ctx
}
pub fn emit(&mut self, err: E::Error) {
self.emitted
.secondary
.push(Located::at(self.before.clone(), err));
}
}