1#![allow(clippy::type_complexity)]
155
156use core::{marker::PhantomData, mem::MaybeUninit};
157
158use crate::{
159 Check, Emitter, Lexed, Lexer, Source, Token,
160 emitter::{Fatal, FromEmitterError},
161 error::{UnexpectedEot, token::UnexpectedToken},
162 lexer::{Input, InputRef, Peeked, PunctuatorToken},
163 punct::Comma,
164 utils::{
165 Expected, Located, Sliced, Spanned,
166 marker::{PhantomLocated, PhantomSliced, PhantomSpan},
167 },
168};
169
170use derive_more::{IsVariant, TryUnwrap, Unwrap};
171use generic_arraydeque::{ArrayLength, GenericArrayDeque, array::GenericArray, typenum};
172
173pub use any::*;
174pub use choice::*;
175pub use collect::Collect;
176pub use ctx::{FatalContext, ParseContext, ParserContext};
177pub use delim::*;
178pub use delim_seq::*;
179pub use empty::*;
180pub use expect::*;
181pub use filter::*;
182pub use filter_map::*;
183pub use ignore::*;
184pub use map::*;
185pub use or_not::*;
186pub use padded::*;
187pub use peek_then::*;
188pub use peek_then_choice::*;
189pub use recover::*;
190pub use repeated::*;
191pub use sep::{SepFixSpec, SeparatedBy, SeparatedByOptions};
192pub use then::*;
193pub use todo::*;
194pub use validate::*;
195
196mod any;
201mod choice;
202mod collect;
203mod ctx;
204mod delim;
205mod delim_seq;
206mod empty;
207mod expect;
208mod filter;
209mod filter_map;
210mod ignore;
211mod map;
212mod or_not;
213mod padded;
214mod peek_then;
215mod peek_then_choice;
216mod recover;
217mod repeated;
218mod sep;
219mod then;
220mod todo;
221mod validate;
222
223#[cfg(any(feature = "std", feature = "alloc"))]
224mod recursive;
225
226mod sealed {
227 pub trait Sealed {}
228}
229
230pub trait Window: sealed::Sealed {
232 type CAPACITY: ArrayLength;
234
235 #[cfg_attr(not(tarpaulin), inline(always))]
237 fn array<T>() -> GenericArray<MaybeUninit<T>, Self::CAPACITY> {
238 GenericArray::uninit()
239 }
240
241 #[cfg_attr(not(tarpaulin), inline(always))]
243 fn deque<T>() -> GenericArrayDeque<MaybeUninit<T>, Self::CAPACITY> {
244 GenericArrayDeque::new()
245 }
246}
247
248macro_rules! peek_buf_capacity_impl_for_typenum {
249 ($($size:literal), + $(,)?) => {
250 paste::paste! {
251 $(
252 impl sealed::Sealed for typenum::[< U $size >] {}
253
254 impl Window for typenum::[< U $size >] {
255 type CAPACITY = typenum::[< U $size >];
256 }
257 )*
258 }
259 };
260}
261
262seq_macro::seq!(N in 1..=32 {
263 peek_buf_capacity_impl_for_typenum! {
264 #(N,)*
265 }
266});
267
268pub trait Decision<'inp, L, E, W, Lang: ?Sized = ()> {
270 fn decide(&mut self, toks: Peeked<'_, 'inp, L, W>, emitter: &mut E) -> Result<Action, E::Error>
272 where
273 L: Lexer<'inp>,
274 E: Emitter<'inp, L, Lang>,
275 W: Window;
276}
277
278impl<'inp, F, L, E, W, Lang: ?Sized> Decision<'inp, L, E, W, Lang> for F
279where
280 F: FnMut(Peeked<'_, 'inp, L, W>, &mut E) -> Result<Action, E::Error>,
281 L: Lexer<'inp>,
282 E: Emitter<'inp, L, Lang>,
283 W: Window,
284{
285 #[cfg_attr(not(tarpaulin), inline(always))]
286 fn decide(&mut self, toks: Peeked<'_, 'inp, L, W>, emitter: &mut E) -> Result<Action, E::Error>
287 where
288 W: Window,
289 {
290 (self)(toks, emitter)
291 }
292}
293
294pub trait ParseInput<'inp, L, O, Ctx, Lang: ?Sized = ()> {
300 fn parse_input(
302 &mut self,
303 input: &mut InputRef<'inp, '_, L, Ctx, Lang>,
304 ) -> Result<O, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>
305 where
306 L: Lexer<'inp>,
307 Ctx: ParseContext<'inp, L, Lang>;
308
309 #[cfg_attr(not(tarpaulin), inline(always))]
311 fn spanned(self) -> With<PhantomSpan, Self>
312 where
313 Self: Sized,
314 {
315 With::new(PhantomSpan::phantom(), self)
316 }
317
318 #[cfg_attr(not(tarpaulin), inline(always))]
320 fn sourced(self) -> With<PhantomSliced, Self>
321 where
322 Self: Sized,
323 {
324 With::new(PhantomSliced::phantom(), self)
325 }
326
327 #[cfg_attr(not(tarpaulin), inline(always))]
329 fn located(self) -> With<PhantomLocated, Self>
330 where
331 Self: Sized,
332 {
333 With::new(PhantomLocated::phantom(), self)
334 }
335
336 #[cfg_attr(not(tarpaulin), inline(always))]
338 fn ignored(self) -> Ignore<Self, O>
339 where
340 Self: Sized,
341 {
342 Ignore::new(self)
343 }
344
345 #[cfg_attr(not(tarpaulin), inline(always))]
348 fn repeated<Condition, W>(self, condition: Condition) -> Repeated<Self, Condition, O, W>
349 where
350 Self: Sized,
351 L: Lexer<'inp>,
352 Ctx: ParseContext<'inp, L, Lang>,
353 Condition: Decision<'inp, L, Ctx::Emitter, W::CAPACITY>,
354 W: Window,
355 {
356 Repeated::new(self, condition)
357 }
358
359 #[cfg_attr(not(tarpaulin), inline(always))]
361 fn separated_by<SepClassifier, Condition, W>(
362 self,
363 sep_classifier: SepClassifier,
364 condition: Condition,
365 ) -> SeparatedBy<Self, SepClassifier, Condition, O, W, L, Ctx>
366 where
367 Self: Sized,
368 L: Lexer<'inp>,
369 Ctx: ParseContext<'inp, L, Lang>,
370 Condition: Decision<'inp, L, Ctx::Emitter, W, Lang>,
371 SepClassifier: Check<L::Token>,
372 W: Window,
373 {
374 SeparatedBy::new(self, sep_classifier, condition)
375 }
376
377 #[cfg_attr(not(tarpaulin), inline(always))]
379 fn separated_by_comma<Condition, W>(
380 self,
381 condition: Condition,
382 ) -> SeparatedBy<Self, Comma, Condition, O, W, L, Ctx>
383 where
384 Self: Sized,
385 L: Lexer<'inp>,
386 L::Token: PunctuatorToken<'inp>,
387 Ctx: ParseContext<'inp, L, Lang>,
388 Condition: Decision<'inp, L, Ctx::Emitter, W, Lang>,
389 W: Window,
390 {
391 SeparatedBy::new(self, Comma::PHANTOM, condition)
392 }
393
394 fn peek_then<C, W>(self, condition: C) -> PeekThen<Self, C, L::Token, W>
399 where
400 Self: Sized,
401 L: Lexer<'inp>,
402 Ctx: ParseContext<'inp, L, Lang>,
403 C: FnMut(
404 Peeked<'_, 'inp, L, W>,
405 &mut Ctx::Emitter,
406 ) -> Result<(), <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>,
407 W: Window,
408 PeekThen<Self, C, L::Token, W>: ParseInput<'inp, L, O, Ctx, Lang>,
409 {
410 PeekThen::of(self, condition)
411 }
412
413 #[doc(alias = "or_not")]
418 fn peek_then_or_not<C, W>(self, condition: C) -> OrNot<PeekThen<Self, C, L::Token, W>>
419 where
420 Self: Sized,
421 L: Lexer<'inp>,
422 Ctx: ParseContext<'inp, L, Lang>,
423 C: Decision<'inp, L, Ctx::Emitter, W, Lang>,
424 W: Window,
425 OrNot<PeekThen<Self, C, L::Token, W>>: ParseInput<'inp, L, Option<O>, Ctx, Lang>,
426 {
427 PeekThen::or_not_of(self, condition)
428 }
429
430 #[cfg_attr(not(tarpaulin), inline(always))]
432 fn map<U, F>(self, f: F) -> Map<Self, F, L, Ctx, O, U, Lang>
433 where
434 Self: Sized,
435 F: FnMut(O) -> U,
436 {
437 Map::new(self, f)
438 }
439
440 #[cfg_attr(not(tarpaulin), inline(always))]
445 fn filter<F>(self, validator: F) -> Filter<Self, F>
446 where
447 Self: Sized,
448 L: Lexer<'inp>,
449 F: FnMut(&O) -> Result<(), <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>,
450 Ctx: ParseContext<'inp, L, Lang>,
451 {
452 Filter::of(self, validator)
453 }
454
455 #[cfg_attr(not(tarpaulin), inline(always))]
460 fn filter_map<U, F>(self, mapper: F) -> FilterMap<Self, F, O>
461 where
462 Self: Sized,
463 L: Lexer<'inp>,
464 F: FnMut(O) -> Result<U, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>,
465 Ctx: ParseContext<'inp, L, Lang>,
466 {
467 FilterMap::of(self, mapper)
468 }
469
470 #[cfg_attr(not(tarpaulin), inline(always))]
475 fn validate<F>(self, validator: F) -> Validate<Self, F>
476 where
477 Self: Sized,
478 L: Lexer<'inp>,
479 F: FnMut(&O) -> Result<(), <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>,
480 Ctx: ParseContext<'inp, L, Lang>,
481 {
482 Validate::of(self, validator)
483 }
484
485 #[cfg_attr(not(tarpaulin), inline(always))]
487 fn then_ignore<G, U>(self, second: G) -> ThenIgnore<Self, G, U>
488 where
489 Self: Sized,
490 G: ParseInput<'inp, L, U, Ctx, Lang>,
491 Ctx: ParseContext<'inp, L, Lang>,
492 {
493 ThenIgnore::new(self, second)
494 }
495
496 #[cfg_attr(not(tarpaulin), inline(always))]
498 fn then<T, U>(self, then: T) -> Then<Self, T>
499 where
500 Self: Sized,
501 T: ParseInput<'inp, L, U, Ctx, Lang>,
502 Ctx: ParseContext<'inp, L, Lang>,
503 {
504 Then::new(self, then)
505 }
506
507 #[cfg_attr(not(tarpaulin), inline(always))]
509 fn ignore_then<G, U>(self, second: G) -> IgnoreThen<Self, G, O>
510 where
511 Self: Sized,
512 G: ParseInput<'inp, L, U, Ctx, Lang>,
513 {
514 IgnoreThen::new(self, second)
515 }
516
517 #[cfg_attr(not(tarpaulin), inline(always))]
519 fn recover<R>(self, recovery: R) -> Recover<Self, R>
520 where
521 Self: Sized,
522 R: ParseInput<'inp, L, O, Ctx, Lang>,
523 Ctx: ParseContext<'inp, L, Lang>,
524 {
525 Recover::new(self, recovery)
526 }
527
528 #[cfg_attr(not(tarpaulin), inline(always))]
530 fn inplace_recover<R>(self, recovery: R) -> InplaceRecover<Self, R>
531 where
532 Self: Sized,
533 R: ParseInput<'inp, L, O, Ctx, Lang>,
534 Ctx: ParseContext<'inp, L, Lang>,
535 {
536 InplaceRecover::new(self, recovery)
537 }
538
539 #[cfg_attr(not(tarpaulin), inline(always))]
541 fn padded(self) -> Padded<Self>
542 where
543 Self: Sized,
544 {
545 Padded::new(self)
546 }
547}
548
549impl<'inp, F, L, O, Ctx, Lang: ?Sized> ParseInput<'inp, L, O, Ctx, Lang> for F
550where
551 F: FnMut(
552 &mut InputRef<'inp, '_, L, Ctx, Lang>,
553 ) -> Result<O, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>,
554 L: Lexer<'inp>,
555 Ctx: ParseContext<'inp, L, Lang>,
556{
557 #[cfg_attr(not(tarpaulin), inline(always))]
558 fn parse_input(
559 &mut self,
560 input: &mut InputRef<'inp, '_, L, Ctx, Lang>,
561 ) -> Result<O, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error> {
562 (self)(input)
563 }
564}
565
566impl<'inp, L, O, Ctx, P, Lang: ?Sized> ParseInput<'inp, L, Spanned<O, L::Span>, Ctx, Lang>
567 for With<PhantomSpan, P>
568where
569 P: ParseInput<'inp, L, O, Ctx, Lang>,
570 L: Lexer<'inp>,
571 Ctx: ParseContext<'inp, L, Lang>,
572{
573 #[cfg_attr(not(tarpaulin), inline(always))]
574 fn parse_input(
575 &mut self,
576 inp: &mut InputRef<'inp, '_, L, Ctx, Lang>,
577 ) -> Result<Spanned<O, L::Span>, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error> {
578 let cursor = inp.cursor().clone();
579 self
580 .secondary
581 .parse_input(inp)
582 .map(|output| Spanned::new(inp.span_since(&cursor), output))
583 }
584}
585
586impl<'inp, L, O, Ctx, P, Lang: ?Sized>
587 ParseInput<'inp, L, Sliced<O, <L::Source as Source<L::Offset>>::Slice<'inp>>, Ctx, Lang>
588 for With<PhantomSliced, P>
589where
590 P: ParseInput<'inp, L, O, Ctx, Lang>,
591 L: Lexer<'inp>,
592 Ctx: ParseContext<'inp, L, Lang>,
593{
594 #[cfg_attr(not(tarpaulin), inline(always))]
595 fn parse_input(
596 &mut self,
597 inp: &mut InputRef<'inp, '_, L, Ctx, Lang>,
598 ) -> Result<
599 Sliced<O, <L::Source as Source<L::Offset>>::Slice<'inp>>,
600 <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error,
601 > {
602 let cursor = inp.cursor().clone();
603 self.secondary.parse_input(inp).map(|output| {
604 Sliced::new(
605 inp
606 .slice_since(&cursor)
607 .expect("parser should guarantee slice"),
608 output,
609 )
610 })
611 }
612}
613
614impl<'inp, L, O, Ctx, P, Lang: ?Sized>
615 ParseInput<'inp, L, Located<O, L::Span, <L::Source as Source<L::Offset>>::Slice<'inp>>, Ctx, Lang>
616 for With<PhantomLocated, P>
617where
618 P: ParseInput<'inp, L, O, Ctx, Lang>,
619 L: Lexer<'inp>,
620 Ctx: ParseContext<'inp, L, Lang>,
621{
622 #[cfg_attr(not(tarpaulin), inline(always))]
623 fn parse_input(
624 &mut self,
625 inp: &mut InputRef<'inp, '_, L, Ctx, Lang>,
626 ) -> Result<
627 Located<O, L::Span, <L::Source as Source<L::Offset>>::Slice<'inp>>,
628 <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error,
629 > {
630 let cursor = inp.cursor().clone();
631 self.secondary.parse_input(inp).map(|output| {
632 Located::new(
633 inp
634 .slice_since(&cursor)
635 .expect("parser should guarantee slice"),
636 inp.span_since(&cursor),
637 output,
638 )
639 })
640 }
641}
642
643#[repr(transparent)]
648pub struct WithCache<'inp, L, C> {
649 cache: C,
650 _marker: PhantomData<&'inp L>,
651}
652
653#[repr(transparent)]
658pub struct WithEmitter<E: ?Sized>(E);
659
660pub struct Parser<F, L, O, Error, Context> {
681 f: F,
682 ctx: Context,
683 _marker: PhantomData<(L, O, Error)>,
684}
685
686impl<F, L, O, Error, Context> core::ops::Deref for Parser<F, L, O, Error, Context> {
687 type Target = F;
688
689 #[cfg_attr(not(tarpaulin), inline(always))]
690 fn deref(&self) -> &Self::Target {
691 &self.f
692 }
693}
694
695impl<F, L, O, Error, Context> core::ops::DerefMut for Parser<F, L, O, Error, Context> {
696 #[cfg_attr(not(tarpaulin), inline(always))]
697 fn deref_mut(&mut self) -> &mut Self::Target {
698 &mut self.f
699 }
700}
701
702impl<'inp, L, O, Error> Default for Parser<(), L, O, Error, FatalContext<'inp, L, Error>>
703where
704 L: Lexer<'inp>,
705 Error: FromEmitterError<'inp, L>,
706{
707 #[cfg_attr(not(tarpaulin), inline(always))]
708 fn default() -> Self {
709 Parser::new()
710 }
711}
712
713impl Parser<(), (), (), (), ()> {
714 #[cfg_attr(not(tarpaulin), inline(always))]
716 pub const fn new<'inp, L, O, Error>() -> Parser<(), L, O, Error, FatalContext<'inp, L, Error>>
717 where
718 L: Lexer<'inp>,
719 Error: FromEmitterError<'inp, L>,
720 {
721 Self::of()
722 }
723
724 #[cfg_attr(not(tarpaulin), inline(always))]
726 pub const fn with_context<'inp, L, O, Error, Ctx>(ctx: Ctx) -> Parser<(), L, O, Error, Ctx>
727 where
728 L: Lexer<'inp>,
729 Error: FromEmitterError<'inp, L>,
730 Ctx: ParseContext<'inp, L>,
731 Ctx::Emitter: Emitter<'inp, L, Error = Error>,
732 {
733 Self::with_context_of(ctx)
734 }
735
736 #[cfg_attr(not(tarpaulin), inline(always))]
738 pub const fn of<'inp, L, O, Error, Lang>()
739 -> Parser<(), L, O, Error, FatalContext<'inp, L, Error, Lang>>
740 where
741 L: Lexer<'inp>,
742 Error: FromEmitterError<'inp, L, Lang>,
743 Lang: ?Sized,
744 {
745 Self::with_context_of(FatalContext::of(Fatal::of()))
746 }
747
748 #[cfg_attr(not(tarpaulin), inline(always))]
750 pub const fn with_context_of<'inp, L, O, Error, Ctx, Lang>(
751 ctx: Ctx,
752 ) -> Parser<(), L, O, Error, Ctx>
753 where
754 L: Lexer<'inp>,
755 Error: FromEmitterError<'inp, L, Lang>,
756 Ctx: ParseContext<'inp, L, Lang>,
757 Ctx::Emitter: Emitter<'inp, L, Lang, Error = Error>,
758 Lang: ?Sized,
759 {
760 Parser {
761 f: (),
762 ctx,
763 _marker: PhantomData,
764 }
765 }
766
767 #[cfg_attr(not(tarpaulin), inline(always))]
769 pub const fn with_parser<'inp, L, O, Error, F>(
770 f: F,
771 ) -> Parser<F, L, O, Error, FatalContext<'inp, L, Error>>
772 where
773 L: Lexer<'inp>,
774 F: ParseInput<'inp, L, O, FatalContext<'inp, L, Error>>,
775 Error: FromEmitterError<'inp, L>,
776 {
777 Self::with_parser_of(f)
778 }
779
780 #[cfg_attr(not(tarpaulin), inline(always))]
782 pub const fn with_parser_of<'inp, L, O, Error, F, Lang>(
783 f: F,
784 ) -> Parser<F, L, O, Error, FatalContext<'inp, L, Error, Lang>>
785 where
786 L: Lexer<'inp>,
787 F: ParseInput<'inp, L, O, FatalContext<'inp, L, Error, Lang>>,
788 Error: FromEmitterError<'inp, L, Lang>,
789 Lang: ?Sized,
790 {
791 Self::with_parser_and_context_of(f, FatalContext::of(Fatal::of()))
792 }
793
794 #[cfg_attr(not(tarpaulin), inline(always))]
796 pub const fn with_parser_and_context<'inp, L, O, Error, Ctx, F>(
797 f: F,
798 ctx: Ctx,
799 ) -> Parser<F, L, O, Error, Ctx>
800 where
801 L: Lexer<'inp>,
802 F: ParseInput<'inp, L, O, Ctx>,
803 Ctx: ParseContext<'inp, L>,
804 Error: FromEmitterError<'inp, L>,
805 {
806 Self::with_parser_and_context_of(f, ctx)
807 }
808
809 #[cfg_attr(not(tarpaulin), inline(always))]
811 pub const fn with_parser_and_context_of<'inp, L, O, Error, Ctx, F, Lang>(
812 f: F,
813 ctx: Ctx,
814 ) -> Parser<F, L, O, Error, Ctx>
815 where
816 L: Lexer<'inp>,
817 F: ParseInput<'inp, L, O, Ctx>,
818 Ctx: ParseContext<'inp, L, Lang>,
819 Error: FromEmitterError<'inp, L, Lang>,
820 Lang: ?Sized,
821 {
822 Parser {
823 f,
824 ctx,
825 _marker: PhantomData,
826 }
827 }
828}
829
830impl<'inp, L, O, Error, Ctx> Parser<(), L, O, Error, Ctx>
831where
832 L: Lexer<'inp>,
833{
834 #[cfg_attr(not(tarpaulin), inline(always))]
836 pub fn apply<F>(self, f: F) -> Parser<F, L, O, Error, Ctx>
837 where
838 Ctx: ParseContext<'inp, L>,
839 F: ParseInput<'inp, L, O, Ctx>,
840 {
841 self.apply_of(f)
842 }
843
844 #[cfg_attr(not(tarpaulin), inline(always))]
846 pub fn apply_of<F, Lang>(self, f: F) -> Parser<F, L, O, Error, Ctx>
847 where
848 Ctx: ParseContext<'inp, L, Lang>,
849 F: ParseInput<'inp, L, O, Ctx>,
850 {
851 Parser {
852 f,
853 ctx: self.ctx,
854 _marker: PhantomData,
855 }
856 }
857}
858
859pub trait Parse<'inp, L, O, Error, Lang: ?Sized = ()>: Sized {
865 #[cfg_attr(not(tarpaulin), inline(always))]
867 fn parse(self, src: &'inp L::Source) -> Result<O, Error>
868 where
869 L: Lexer<'inp>,
870 L::State: Default,
871 {
872 self.parse_with_state(src, L::State::default())
873 }
874
875 fn parse_with_state(self, src: &'inp L::Source, state: L::State) -> Result<O, Error>
877 where
878 L: Lexer<'inp>;
879}
880
881impl<'inp, F, L, O, Error, Ctx, Lang: ?Sized> Parse<'inp, L, O, Error, Lang>
882 for Parser<F, L, O, Error, Ctx>
883where
884 F: ParseInput<'inp, L, O, Ctx, Lang>,
885 L: Lexer<'inp>,
886 Ctx: ParseContext<'inp, L, Lang>,
887 Ctx::Emitter: Emitter<'inp, L, Lang, Error = Error>,
888{
889 #[cfg_attr(not(tarpaulin), inline(always))]
890 fn parse_with_state(self, src: &'inp L::Source, state: L::State) -> Result<O, Error> {
891 let Parser { mut f, ctx, .. } = self;
892
893 let (mut emitter, cache) = ctx.provide().into_components();
894 let mut input = Input::with_state_and_cache(src, state, cache);
895 let mut input_ref = input.as_ref(&mut emitter);
896 f.parse_input(&mut input_ref)
897 }
898}
899
900pub trait Apply<State> {
910 type Options;
912
913 fn apply(self, options: Self::Options) -> State;
915}
916
917#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
930pub struct With<P, S> {
931 primary: P,
932 secondary: S,
933}
934
935impl<P, S> With<P, S> {
936 #[cfg_attr(not(tarpaulin), inline(always))]
938 pub const fn new(primary: P, secondary: S) -> Self {
939 Self { primary, secondary }
940 }
941
942 #[cfg_attr(not(tarpaulin), inline(always))]
944 pub const fn primary(&self) -> &P {
945 &self.primary
946 }
947
948 #[cfg_attr(not(tarpaulin), inline(always))]
950 pub const fn secondary(&self) -> &S {
951 &self.secondary
952 }
953
954 #[cfg_attr(not(tarpaulin), inline(always))]
956 pub const fn primary_mut(&mut self) -> &mut P {
957 &mut self.primary
958 }
959
960 #[cfg_attr(not(tarpaulin), inline(always))]
962 pub const fn secondary_mut(&mut self) -> &mut S {
963 &mut self.secondary
964 }
965
966 #[cfg_attr(not(tarpaulin), inline(always))]
968 pub fn map_primary<U, F>(self, f: F) -> With<U, S>
969 where
970 F: FnOnce(P) -> U,
971 {
972 With {
973 primary: f(self.primary),
974 secondary: self.secondary,
975 }
976 }
977
978 #[cfg_attr(not(tarpaulin), inline(always))]
980 pub fn map_secondary<U, F>(self, f: F) -> With<P, U>
981 where
982 F: FnOnce(S) -> U,
983 {
984 With {
985 primary: self.primary,
986 secondary: f(self.secondary),
987 }
988 }
989}
990
991#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, IsVariant, Unwrap, TryUnwrap)]
993#[unwrap(ref, ref_mut)]
994#[try_unwrap(ref, ref_mut)]
995pub enum Action {
996 #[unwrap(ignore)]
998 #[try_unwrap(ignore)]
999 Stop,
1000 #[unwrap(ignore)]
1002 #[try_unwrap(ignore)]
1003 Continue,
1004}
1005
1006impl Apply<Maximum> for () {
1007 type Options = usize;
1008
1009 #[cfg_attr(not(tarpaulin), inline(always))]
1010 fn apply(self, options: Self::Options) -> Maximum {
1011 Maximum(options)
1012 }
1013}
1014
1015impl Apply<Minimum> for () {
1016 type Options = usize;
1017
1018 #[cfg_attr(not(tarpaulin), inline(always))]
1019 fn apply(self, options: Self::Options) -> Minimum {
1020 Minimum(options)
1021 }
1022}
1023
1024impl Apply<Maximum> for Maximum {
1025 type Options = usize;
1026
1027 #[cfg_attr(not(tarpaulin), inline(always))]
1028 fn apply(self, options: Self::Options) -> Maximum {
1029 Maximum(options)
1030 }
1031}
1032
1033impl Apply<Minimum> for Minimum {
1034 type Options = usize;
1035
1036 #[cfg_attr(not(tarpaulin), inline(always))]
1037 fn apply(self, options: Self::Options) -> Minimum {
1038 Minimum(options)
1039 }
1040}
1041
1042#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1044pub struct Maximum(pub usize);
1045
1046impl Maximum {
1047 pub const MAX: Self = Self::new(usize::MAX);
1049
1050 #[cfg_attr(not(tarpaulin), inline(always))]
1052 pub const fn new(n: usize) -> Self {
1053 Self(n)
1054 }
1055
1056 #[cfg_attr(not(tarpaulin), inline(always))]
1058 pub const fn get(&self) -> usize {
1059 self.0
1060 }
1061}
1062
1063#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1065pub struct Minimum(usize);
1066
1067impl Minimum {
1068 pub const MIN: Self = Self::new(0);
1070
1071 #[cfg_attr(not(tarpaulin), inline(always))]
1073 pub const fn new(n: usize) -> Self {
1074 Self(n)
1075 }
1076
1077 #[cfg_attr(not(tarpaulin), inline(always))]
1079 pub const fn get(&self) -> usize {
1080 self.0
1081 }
1082}
1083
1084trait MinSpec {
1085 fn minimum(&self) -> usize;
1086}
1087
1088impl<T: MinSpec> MinSpec for &mut T {
1089 #[cfg_attr(not(tarpaulin), inline(always))]
1090 fn minimum(&self) -> usize {
1091 (**self).minimum()
1092 }
1093}
1094
1095impl MinSpec for Minimum {
1096 #[cfg_attr(not(tarpaulin), inline(always))]
1097 fn minimum(&self) -> usize {
1098 self.0
1099 }
1100}
1101
1102impl MinSpec for () {
1103 #[cfg_attr(not(tarpaulin), inline(always))]
1104 fn minimum(&self) -> usize {
1105 0
1106 }
1107}
1108
1109trait MaxSpec {
1110 fn maximum(&self) -> usize;
1111}
1112
1113impl<T: MaxSpec> MaxSpec for &mut T {
1114 #[cfg_attr(not(tarpaulin), inline(always))]
1115 fn maximum(&self) -> usize {
1116 (**self).maximum()
1117 }
1118}
1119
1120impl MaxSpec for Maximum {
1121 #[cfg_attr(not(tarpaulin), inline(always))]
1122 fn maximum(&self) -> usize {
1123 self.0
1124 }
1125}
1126
1127impl MaxSpec for () {
1128 #[cfg_attr(not(tarpaulin), inline(always))]
1129 fn maximum(&self) -> usize {
1130 usize::MAX
1131 }
1132}
1133
1134pub enum ParseResult<O, E> {
1136 Rewind,
1138 Ok(O),
1140 Err(E),
1142}