#![allow(clippy::type_complexity)]
use core::{marker::PhantomData, mem::MaybeUninit};
use crate::{
Check, Emitter, Lexed, Lexer, Source, Token,
emitter::{Fatal, FromEmitterError},
error::{UnexpectedEot, token::UnexpectedToken},
lexer::{Input, InputRef, Peeked, PunctuatorToken},
punct::Comma,
utils::{
Expected, Located, Sliced, Spanned,
marker::{PhantomLocated, PhantomSliced, PhantomSpan},
},
};
use derive_more::{IsVariant, TryUnwrap, Unwrap};
use generic_arraydeque::{ArrayLength, GenericArrayDeque, array::GenericArray, typenum};
pub use any::*;
pub use choice::*;
pub use collect::Collect;
pub use ctx::{FatalContext, ParseContext, ParserContext};
pub use delim::*;
pub use delim_seq::*;
pub use empty::*;
pub use expect::*;
pub use filter::*;
pub use filter_map::*;
pub use ignore::*;
pub use map::*;
pub use or_not::*;
pub use padded::*;
pub use peek_then::*;
pub use peek_then_choice::*;
pub use recover::*;
pub use repeated::*;
pub use sep::{SepFixSpec, SeparatedBy, SeparatedByOptions};
pub use then::*;
pub use todo::*;
pub use validate::*;
mod any;
mod choice;
mod collect;
mod ctx;
mod delim;
mod delim_seq;
mod empty;
mod expect;
mod filter;
mod filter_map;
mod ignore;
mod map;
mod or_not;
mod padded;
mod peek_then;
mod peek_then_choice;
mod recover;
mod repeated;
mod sep;
mod then;
mod todo;
mod validate;
#[cfg(any(feature = "std", feature = "alloc"))]
mod recursive;
mod sealed {
pub trait Sealed {}
}
pub trait Window: sealed::Sealed {
type CAPACITY: ArrayLength;
#[cfg_attr(not(tarpaulin), inline(always))]
fn array<T>() -> GenericArray<MaybeUninit<T>, Self::CAPACITY> {
GenericArray::uninit()
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn deque<T>() -> GenericArrayDeque<MaybeUninit<T>, Self::CAPACITY> {
GenericArrayDeque::new()
}
}
macro_rules! peek_buf_capacity_impl_for_typenum {
($($size:literal), + $(,)?) => {
paste::paste! {
$(
impl sealed::Sealed for typenum::[< U $size >] {}
impl Window for typenum::[< U $size >] {
type CAPACITY = typenum::[< U $size >];
}
)*
}
};
}
seq_macro::seq!(N in 1..=32 {
peek_buf_capacity_impl_for_typenum! {
#(N,)*
}
});
pub trait Decision<'inp, L, E, W, Lang: ?Sized = ()> {
fn decide(&mut self, toks: Peeked<'_, 'inp, L, W>, emitter: &mut E) -> Result<Action, E::Error>
where
L: Lexer<'inp>,
E: Emitter<'inp, L, Lang>,
W: Window;
}
impl<'inp, F, L, E, W, Lang: ?Sized> Decision<'inp, L, E, W, Lang> for F
where
F: FnMut(Peeked<'_, 'inp, L, W>, &mut E) -> Result<Action, E::Error>,
L: Lexer<'inp>,
E: Emitter<'inp, L, Lang>,
W: Window,
{
#[cfg_attr(not(tarpaulin), inline(always))]
fn decide(&mut self, toks: Peeked<'_, 'inp, L, W>, emitter: &mut E) -> Result<Action, E::Error>
where
W: Window,
{
(self)(toks, emitter)
}
}
pub trait ParseInput<'inp, L, O, Ctx, Lang: ?Sized = ()> {
fn parse_input(
&mut self,
input: &mut InputRef<'inp, '_, L, Ctx, Lang>,
) -> Result<O, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>
where
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>;
#[cfg_attr(not(tarpaulin), inline(always))]
fn spanned(self) -> With<PhantomSpan, Self>
where
Self: Sized,
{
With::new(PhantomSpan::phantom(), self)
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn sourced(self) -> With<PhantomSliced, Self>
where
Self: Sized,
{
With::new(PhantomSliced::phantom(), self)
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn located(self) -> With<PhantomLocated, Self>
where
Self: Sized,
{
With::new(PhantomLocated::phantom(), self)
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn ignored(self) -> Ignore<Self, O>
where
Self: Sized,
{
Ignore::new(self)
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn repeated<Condition, W>(self, condition: Condition) -> Repeated<Self, Condition, O, W>
where
Self: Sized,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
Condition: Decision<'inp, L, Ctx::Emitter, W::CAPACITY>,
W: Window,
{
Repeated::new(self, condition)
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn separated_by<SepClassifier, Condition, W>(
self,
sep_classifier: SepClassifier,
condition: Condition,
) -> SeparatedBy<Self, SepClassifier, Condition, O, W, L, Ctx>
where
Self: Sized,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
Condition: Decision<'inp, L, Ctx::Emitter, W, Lang>,
SepClassifier: Check<L::Token>,
W: Window,
{
SeparatedBy::new(self, sep_classifier, condition)
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn separated_by_comma<Condition, W>(
self,
condition: Condition,
) -> SeparatedBy<Self, Comma, Condition, O, W, L, Ctx>
where
Self: Sized,
L: Lexer<'inp>,
L::Token: PunctuatorToken<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
Condition: Decision<'inp, L, Ctx::Emitter, W, Lang>,
W: Window,
{
SeparatedBy::new(self, Comma::PHANTOM, condition)
}
fn peek_then<C, W>(self, condition: C) -> PeekThen<Self, C, L::Token, W>
where
Self: Sized,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
C: FnMut(
Peeked<'_, 'inp, L, W>,
&mut Ctx::Emitter,
) -> Result<(), <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>,
W: Window,
PeekThen<Self, C, L::Token, W>: ParseInput<'inp, L, O, Ctx, Lang>,
{
PeekThen::of(self, condition)
}
#[doc(alias = "or_not")]
fn peek_then_or_not<C, W>(self, condition: C) -> OrNot<PeekThen<Self, C, L::Token, W>>
where
Self: Sized,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
C: Decision<'inp, L, Ctx::Emitter, W, Lang>,
W: Window,
OrNot<PeekThen<Self, C, L::Token, W>>: ParseInput<'inp, L, Option<O>, Ctx, Lang>,
{
PeekThen::or_not_of(self, condition)
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn map<U, F>(self, f: F) -> Map<Self, F, L, Ctx, O, U, Lang>
where
Self: Sized,
F: FnMut(O) -> U,
{
Map::new(self, f)
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn filter<F>(self, validator: F) -> Filter<Self, F>
where
Self: Sized,
L: Lexer<'inp>,
F: FnMut(&O) -> Result<(), <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>,
Ctx: ParseContext<'inp, L, Lang>,
{
Filter::of(self, validator)
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn filter_map<U, F>(self, mapper: F) -> FilterMap<Self, F, O>
where
Self: Sized,
L: Lexer<'inp>,
F: FnMut(O) -> Result<U, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>,
Ctx: ParseContext<'inp, L, Lang>,
{
FilterMap::of(self, mapper)
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn validate<F>(self, validator: F) -> Validate<Self, F>
where
Self: Sized,
L: Lexer<'inp>,
F: FnMut(&O) -> Result<(), <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>,
Ctx: ParseContext<'inp, L, Lang>,
{
Validate::of(self, validator)
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn then_ignore<G, U>(self, second: G) -> ThenIgnore<Self, G, U>
where
Self: Sized,
G: ParseInput<'inp, L, U, Ctx, Lang>,
Ctx: ParseContext<'inp, L, Lang>,
{
ThenIgnore::new(self, second)
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn then<T, U>(self, then: T) -> Then<Self, T>
where
Self: Sized,
T: ParseInput<'inp, L, U, Ctx, Lang>,
Ctx: ParseContext<'inp, L, Lang>,
{
Then::new(self, then)
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn ignore_then<G, U>(self, second: G) -> IgnoreThen<Self, G, O>
where
Self: Sized,
G: ParseInput<'inp, L, U, Ctx, Lang>,
{
IgnoreThen::new(self, second)
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn recover<R>(self, recovery: R) -> Recover<Self, R>
where
Self: Sized,
R: ParseInput<'inp, L, O, Ctx, Lang>,
Ctx: ParseContext<'inp, L, Lang>,
{
Recover::new(self, recovery)
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn inplace_recover<R>(self, recovery: R) -> InplaceRecover<Self, R>
where
Self: Sized,
R: ParseInput<'inp, L, O, Ctx, Lang>,
Ctx: ParseContext<'inp, L, Lang>,
{
InplaceRecover::new(self, recovery)
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn padded(self) -> Padded<Self>
where
Self: Sized,
{
Padded::new(self)
}
}
impl<'inp, F, L, O, Ctx, Lang: ?Sized> ParseInput<'inp, L, O, Ctx, Lang> for F
where
F: FnMut(
&mut InputRef<'inp, '_, L, Ctx, Lang>,
) -> Result<O, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
{
#[cfg_attr(not(tarpaulin), inline(always))]
fn parse_input(
&mut self,
input: &mut InputRef<'inp, '_, L, Ctx, Lang>,
) -> Result<O, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error> {
(self)(input)
}
}
impl<'inp, L, O, Ctx, P, Lang: ?Sized> ParseInput<'inp, L, Spanned<O, L::Span>, Ctx, Lang>
for With<PhantomSpan, P>
where
P: ParseInput<'inp, L, O, Ctx, Lang>,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
{
#[cfg_attr(not(tarpaulin), inline(always))]
fn parse_input(
&mut self,
inp: &mut InputRef<'inp, '_, L, Ctx, Lang>,
) -> Result<Spanned<O, L::Span>, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error> {
let cursor = inp.cursor().clone();
self
.secondary
.parse_input(inp)
.map(|output| Spanned::new(inp.span_since(&cursor), output))
}
}
impl<'inp, L, O, Ctx, P, Lang: ?Sized>
ParseInput<'inp, L, Sliced<O, <L::Source as Source<L::Offset>>::Slice<'inp>>, Ctx, Lang>
for With<PhantomSliced, P>
where
P: ParseInput<'inp, L, O, Ctx, Lang>,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
{
#[cfg_attr(not(tarpaulin), inline(always))]
fn parse_input(
&mut self,
inp: &mut InputRef<'inp, '_, L, Ctx, Lang>,
) -> Result<
Sliced<O, <L::Source as Source<L::Offset>>::Slice<'inp>>,
<Ctx::Emitter as Emitter<'inp, L, Lang>>::Error,
> {
let cursor = inp.cursor().clone();
self.secondary.parse_input(inp).map(|output| {
Sliced::new(
inp
.slice_since(&cursor)
.expect("parser should guarantee slice"),
output,
)
})
}
}
impl<'inp, L, O, Ctx, P, Lang: ?Sized>
ParseInput<'inp, L, Located<O, L::Span, <L::Source as Source<L::Offset>>::Slice<'inp>>, Ctx, Lang>
for With<PhantomLocated, P>
where
P: ParseInput<'inp, L, O, Ctx, Lang>,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
{
#[cfg_attr(not(tarpaulin), inline(always))]
fn parse_input(
&mut self,
inp: &mut InputRef<'inp, '_, L, Ctx, Lang>,
) -> Result<
Located<O, L::Span, <L::Source as Source<L::Offset>>::Slice<'inp>>,
<Ctx::Emitter as Emitter<'inp, L, Lang>>::Error,
> {
let cursor = inp.cursor().clone();
self.secondary.parse_input(inp).map(|output| {
Located::new(
inp
.slice_since(&cursor)
.expect("parser should guarantee slice"),
inp.span_since(&cursor),
output,
)
})
}
}
#[repr(transparent)]
pub struct WithCache<'inp, L, C> {
cache: C,
_marker: PhantomData<&'inp L>,
}
#[repr(transparent)]
pub struct WithEmitter<E: ?Sized>(E);
pub struct Parser<F, L, O, Error, Context> {
f: F,
ctx: Context,
_marker: PhantomData<(L, O, Error)>,
}
impl<F, L, O, Error, Context> core::ops::Deref for Parser<F, L, O, Error, Context> {
type Target = F;
#[cfg_attr(not(tarpaulin), inline(always))]
fn deref(&self) -> &Self::Target {
&self.f
}
}
impl<F, L, O, Error, Context> core::ops::DerefMut for Parser<F, L, O, Error, Context> {
#[cfg_attr(not(tarpaulin), inline(always))]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.f
}
}
impl<'inp, L, O, Error> Default for Parser<(), L, O, Error, FatalContext<'inp, L, Error>>
where
L: Lexer<'inp>,
Error: FromEmitterError<'inp, L>,
{
#[cfg_attr(not(tarpaulin), inline(always))]
fn default() -> Self {
Parser::new()
}
}
impl Parser<(), (), (), (), ()> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new<'inp, L, O, Error>() -> Parser<(), L, O, Error, FatalContext<'inp, L, Error>>
where
L: Lexer<'inp>,
Error: FromEmitterError<'inp, L>,
{
Self::of()
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_context<'inp, L, O, Error, Ctx>(ctx: Ctx) -> Parser<(), L, O, Error, Ctx>
where
L: Lexer<'inp>,
Error: FromEmitterError<'inp, L>,
Ctx: ParseContext<'inp, L>,
Ctx::Emitter: Emitter<'inp, L, Error = Error>,
{
Self::with_context_of(ctx)
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn of<'inp, L, O, Error, Lang>()
-> Parser<(), L, O, Error, FatalContext<'inp, L, Error, Lang>>
where
L: Lexer<'inp>,
Error: FromEmitterError<'inp, L, Lang>,
Lang: ?Sized,
{
Self::with_context_of(FatalContext::of(Fatal::of()))
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_context_of<'inp, L, O, Error, Ctx, Lang>(
ctx: Ctx,
) -> Parser<(), L, O, Error, Ctx>
where
L: Lexer<'inp>,
Error: FromEmitterError<'inp, L, Lang>,
Ctx: ParseContext<'inp, L, Lang>,
Ctx::Emitter: Emitter<'inp, L, Lang, Error = Error>,
Lang: ?Sized,
{
Parser {
f: (),
ctx,
_marker: PhantomData,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_parser<'inp, L, O, Error, F>(
f: F,
) -> Parser<F, L, O, Error, FatalContext<'inp, L, Error>>
where
L: Lexer<'inp>,
F: ParseInput<'inp, L, O, FatalContext<'inp, L, Error>>,
Error: FromEmitterError<'inp, L>,
{
Self::with_parser_of(f)
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_parser_of<'inp, L, O, Error, F, Lang>(
f: F,
) -> Parser<F, L, O, Error, FatalContext<'inp, L, Error, Lang>>
where
L: Lexer<'inp>,
F: ParseInput<'inp, L, O, FatalContext<'inp, L, Error, Lang>>,
Error: FromEmitterError<'inp, L, Lang>,
Lang: ?Sized,
{
Self::with_parser_and_context_of(f, FatalContext::of(Fatal::of()))
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_parser_and_context<'inp, L, O, Error, Ctx, F>(
f: F,
ctx: Ctx,
) -> Parser<F, L, O, Error, Ctx>
where
L: Lexer<'inp>,
F: ParseInput<'inp, L, O, Ctx>,
Ctx: ParseContext<'inp, L>,
Error: FromEmitterError<'inp, L>,
{
Self::with_parser_and_context_of(f, ctx)
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_parser_and_context_of<'inp, L, O, Error, Ctx, F, Lang>(
f: F,
ctx: Ctx,
) -> Parser<F, L, O, Error, Ctx>
where
L: Lexer<'inp>,
F: ParseInput<'inp, L, O, Ctx>,
Ctx: ParseContext<'inp, L, Lang>,
Error: FromEmitterError<'inp, L, Lang>,
Lang: ?Sized,
{
Parser {
f,
ctx,
_marker: PhantomData,
}
}
}
impl<'inp, L, O, Error, Ctx> Parser<(), L, O, Error, Ctx>
where
L: Lexer<'inp>,
{
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn apply<F>(self, f: F) -> Parser<F, L, O, Error, Ctx>
where
Ctx: ParseContext<'inp, L>,
F: ParseInput<'inp, L, O, Ctx>,
{
self.apply_of(f)
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn apply_of<F, Lang>(self, f: F) -> Parser<F, L, O, Error, Ctx>
where
Ctx: ParseContext<'inp, L, Lang>,
F: ParseInput<'inp, L, O, Ctx>,
{
Parser {
f,
ctx: self.ctx,
_marker: PhantomData,
}
}
}
pub trait Parse<'inp, L, O, Error, Lang: ?Sized = ()>: Sized {
#[cfg_attr(not(tarpaulin), inline(always))]
fn parse(self, src: &'inp L::Source) -> Result<O, Error>
where
L: Lexer<'inp>,
L::State: Default,
{
self.parse_with_state(src, L::State::default())
}
fn parse_with_state(self, src: &'inp L::Source, state: L::State) -> Result<O, Error>
where
L: Lexer<'inp>;
}
impl<'inp, F, L, O, Error, Ctx, Lang: ?Sized> Parse<'inp, L, O, Error, Lang>
for Parser<F, L, O, Error, Ctx>
where
F: ParseInput<'inp, L, O, Ctx, Lang>,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
Ctx::Emitter: Emitter<'inp, L, Lang, Error = Error>,
{
#[cfg_attr(not(tarpaulin), inline(always))]
fn parse_with_state(self, src: &'inp L::Source, state: L::State) -> Result<O, Error> {
let Parser { mut f, ctx, .. } = self;
let (mut emitter, cache) = ctx.provide().into_components();
let mut input = Input::with_state_and_cache(src, state, cache);
let mut input_ref = input.as_ref(&mut emitter);
f.parse_input(&mut input_ref)
}
}
pub trait Apply<State> {
type Options;
fn apply(self, options: Self::Options) -> State;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct With<P, S> {
primary: P,
secondary: S,
}
impl<P, S> With<P, S> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(primary: P, secondary: S) -> Self {
Self { primary, secondary }
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn primary(&self) -> &P {
&self.primary
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn secondary(&self) -> &S {
&self.secondary
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn primary_mut(&mut self) -> &mut P {
&mut self.primary
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn secondary_mut(&mut self) -> &mut S {
&mut self.secondary
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn map_primary<U, F>(self, f: F) -> With<U, S>
where
F: FnOnce(P) -> U,
{
With {
primary: f(self.primary),
secondary: self.secondary,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn map_secondary<U, F>(self, f: F) -> With<P, U>
where
F: FnOnce(S) -> U,
{
With {
primary: self.primary,
secondary: f(self.secondary),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, IsVariant, Unwrap, TryUnwrap)]
#[unwrap(ref, ref_mut)]
#[try_unwrap(ref, ref_mut)]
pub enum Action {
#[unwrap(ignore)]
#[try_unwrap(ignore)]
Stop,
#[unwrap(ignore)]
#[try_unwrap(ignore)]
Continue,
}
impl Apply<Maximum> for () {
type Options = usize;
#[cfg_attr(not(tarpaulin), inline(always))]
fn apply(self, options: Self::Options) -> Maximum {
Maximum(options)
}
}
impl Apply<Minimum> for () {
type Options = usize;
#[cfg_attr(not(tarpaulin), inline(always))]
fn apply(self, options: Self::Options) -> Minimum {
Minimum(options)
}
}
impl Apply<Maximum> for Maximum {
type Options = usize;
#[cfg_attr(not(tarpaulin), inline(always))]
fn apply(self, options: Self::Options) -> Maximum {
Maximum(options)
}
}
impl Apply<Minimum> for Minimum {
type Options = usize;
#[cfg_attr(not(tarpaulin), inline(always))]
fn apply(self, options: Self::Options) -> Minimum {
Minimum(options)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Maximum(pub usize);
impl Maximum {
pub const MAX: Self = Self::new(usize::MAX);
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(n: usize) -> Self {
Self(n)
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn get(&self) -> usize {
self.0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Minimum(usize);
impl Minimum {
pub const MIN: Self = Self::new(0);
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(n: usize) -> Self {
Self(n)
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn get(&self) -> usize {
self.0
}
}
trait MinSpec {
fn minimum(&self) -> usize;
}
impl<T: MinSpec> MinSpec for &mut T {
#[cfg_attr(not(tarpaulin), inline(always))]
fn minimum(&self) -> usize {
(**self).minimum()
}
}
impl MinSpec for Minimum {
#[cfg_attr(not(tarpaulin), inline(always))]
fn minimum(&self) -> usize {
self.0
}
}
impl MinSpec for () {
#[cfg_attr(not(tarpaulin), inline(always))]
fn minimum(&self) -> usize {
0
}
}
trait MaxSpec {
fn maximum(&self) -> usize;
}
impl<T: MaxSpec> MaxSpec for &mut T {
#[cfg_attr(not(tarpaulin), inline(always))]
fn maximum(&self) -> usize {
(**self).maximum()
}
}
impl MaxSpec for Maximum {
#[cfg_attr(not(tarpaulin), inline(always))]
fn maximum(&self) -> usize {
self.0
}
}
impl MaxSpec for () {
#[cfg_attr(not(tarpaulin), inline(always))]
fn maximum(&self) -> usize {
usize::MAX
}
}
pub enum ParseResult<O, E> {
Rewind,
Ok(O),
Err(E),
}