Skip to main content

chumsky/
primitive.rs

1//! Parser primitives that accept specific token patterns.
2//!
3//! *“These creatures you call mice, you see, they are not quite as they appear. They are merely the protrusion into
4//! our dimension of vastly hyperintelligent pandimensional beings.”*
5//!
6//! Chumsky parsers are created by combining together smaller parsers. Right at the bottom of the pile are the parser
7//! primitives, a parser developer's bread & butter. Each of these primitives are very easy to understand in isolation,
8//! usually only doing one thing.
9//!
10//! ## The Important Ones
11//!
12//! - [`just`]: parses a specific input or sequence of inputs
13//! - [`any`]: parses any single input
14//! - [`one_of`]: parses any one of a sequence of inputs
15//! - [`none_of`]: parses any input that does not appear in a sequence of inputs
16//! - [`end`]: parses the end of input (i.e: if there any more inputs, this parse fails)
17
18use super::*;
19
20/// See [`end`].
21pub struct End<I, E>(EmptyPhantom<(E, I)>);
22
23/// A parser that accepts only the end of input.
24///
25/// The output type of this parser is `()`.
26pub const fn end<'src, I: Input<'src>, E: ParserExtra<'src, I>>() -> End<I, E> {
27    End(EmptyPhantom::new())
28}
29
30impl<I, E> Copy for End<I, E> {}
31impl<I, E> Clone for End<I, E> {
32    fn clone(&self) -> Self {
33        *self
34    }
35}
36
37impl<'src, I, E> Parser<'src, I, (), E> for End<I, E>
38where
39    I: Input<'src>,
40    E: ParserExtra<'src, I>,
41{
42    #[inline]
43    fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, ()> {
44        let before = inp.save();
45        match inp.next_maybe_inner() {
46            None => Ok(M::bind(|| ())),
47            Some(tok) => {
48                let span = inp.span_since(before.cursor());
49                inp.rewind(before);
50                inp.add_alt([DefaultExpected::EndOfInput], Some(tok.into()), span);
51                Err(())
52            }
53        }
54    }
55
56    go_extra!(());
57}
58
59/// See [`empty`].
60pub struct Empty<I, E>(EmptyPhantom<(E, I)>);
61
62/// A parser that parses no inputs.
63///
64/// The output type of this parser is `()`.
65pub const fn empty<I, E>() -> Empty<I, E> {
66    Empty(EmptyPhantom::new())
67}
68
69impl<I, E> Copy for Empty<I, E> {}
70impl<I, E> Clone for Empty<I, E> {
71    fn clone(&self) -> Self {
72        *self
73    }
74}
75
76impl<'src, I, E> Parser<'src, I, (), E> for Empty<I, E>
77where
78    I: Input<'src>,
79    E: ParserExtra<'src, I>,
80{
81    #[inline]
82    fn go<M: Mode>(&self, _: &mut InputRef<'src, '_, I, E>) -> PResult<M, ()> {
83        Ok(M::bind(|| ()))
84    }
85
86    go_extra!(());
87}
88
89/// Configuration for [`just`], used in [`ConfigParser::configure`]
90pub struct JustCfg<T> {
91    seq: Option<T>,
92}
93
94impl<T> JustCfg<T> {
95    /// Set the sequence to be used while parsing
96    #[inline]
97    pub fn seq(mut self, new_seq: T) -> Self {
98        self.seq = Some(new_seq);
99        self
100    }
101}
102
103impl<T> Default for JustCfg<T> {
104    #[inline]
105    fn default() -> Self {
106        JustCfg { seq: None }
107    }
108}
109
110/// See [`just`].
111pub struct Just<T, I, E = EmptyErr> {
112    seq: T,
113    #[allow(dead_code)]
114    phantom: EmptyPhantom<(E, I)>,
115}
116
117impl<T: Copy, I, E> Copy for Just<T, I, E> {}
118impl<T: Clone, I, E> Clone for Just<T, I, E> {
119    fn clone(&self) -> Self {
120        Self {
121            seq: self.seq.clone(),
122            phantom: EmptyPhantom::new(),
123        }
124    }
125}
126
127/// A parser that accepts only the given input.
128///
129/// The output type of this parser is `T`, the input or sequence that was provided.
130///
131/// # Examples
132///
133/// ```
134/// # use chumsky::{prelude::*, error::Simple};
135/// let question = just::<_, _, extra::Err<Simple<char>>>('?');
136///
137/// assert_eq!(question.parse("?").into_result(), Ok('?'));
138/// // This fails because '?' was not found
139/// assert!(question.parse("!").has_errors());
140/// // This fails because the parser expects an end to the input after the '?'
141/// assert!(question.parse("?!").has_errors());
142/// ```
143pub const fn just<'src, T, I, E>(seq: T) -> Just<T, I, E>
144where
145    I: Input<'src>,
146    E: ParserExtra<'src, I>,
147    I::Token: PartialEq,
148    T: OrderedSeq<'src, I::Token> + Clone,
149{
150    Just {
151        seq,
152        phantom: EmptyPhantom::new(),
153    }
154}
155
156impl<'src, I, E, T> Parser<'src, I, T, E> for Just<T, I, E>
157where
158    I: Input<'src>,
159    E: ParserExtra<'src, I>,
160    I::Token: PartialEq,
161    T: OrderedSeq<'src, I::Token> + Clone,
162{
163    #[doc(hidden)]
164    #[cfg(feature = "debug")]
165    fn node_info(&self, scope: &mut debug::NodeScope) -> debug::NodeInfo {
166        debug::NodeInfo::Just(self.seq.seq_info(scope))
167    }
168
169    #[inline]
170    fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, T> {
171        Self::go_cfg::<M>(self, inp, JustCfg::default())
172    }
173
174    go_extra!(T);
175}
176
177impl<'src, I, E, T> ConfigParser<'src, I, T, E> for Just<T, I, E>
178where
179    I: Input<'src>,
180    E: ParserExtra<'src, I>,
181    I::Token: PartialEq,
182    T: OrderedSeq<'src, I::Token> + Clone,
183{
184    type Config = JustCfg<T>;
185
186    #[inline]
187    fn go_cfg<M: Mode>(
188        &self,
189        inp: &mut InputRef<'src, '_, I, E>,
190        cfg: Self::Config,
191    ) -> PResult<M, T> {
192        let seq = cfg.seq.as_ref().unwrap_or(&self.seq);
193        for next in seq.seq_iter() {
194            let before = inp.save();
195            match inp.next_maybe_inner() {
196                Some(tok) if next.borrow() == tok.borrow() => {}
197                found => {
198                    let span = inp.span_since(before.cursor());
199                    inp.rewind(before);
200                    inp.add_alt(
201                        [DefaultExpected::Token(T::to_maybe_ref(next))],
202                        found.map(|f| f.into()),
203                        span,
204                    );
205                    return Err(());
206                }
207            }
208        }
209
210        Ok(M::bind(|| seq.clone()))
211    }
212}
213
214/// Configuration for [`one_of`], used in [`ConfigParser::configure`]
215pub struct OneOfCfg<T> {
216    seq: Option<T>,
217}
218
219impl<T> OneOfCfg<T> {
220    /// Set the sequence to be used while parsing
221    #[inline]
222    pub fn seq(mut self, new_seq: T) -> Self {
223        self.seq = Some(new_seq);
224        self
225    }
226}
227
228impl<T> Default for OneOfCfg<T> {
229    #[inline]
230    fn default() -> Self {
231        OneOfCfg { seq: None }
232    }
233}
234
235/// See [`one_of`].
236pub struct OneOf<T, I, E> {
237    seq: T,
238    #[allow(dead_code)]
239    phantom: EmptyPhantom<(E, I)>,
240}
241
242impl<T: Copy, I, E> Copy for OneOf<T, I, E> {}
243impl<T: Clone, I, E> Clone for OneOf<T, I, E> {
244    fn clone(&self) -> Self {
245        Self {
246            seq: self.seq.clone(),
247            phantom: EmptyPhantom::new(),
248        }
249    }
250}
251
252/// A parser that accepts one of a sequence of specific inputs.
253///
254/// The output type of this parser is `I`, the input that was found.
255///
256/// # Examples
257///
258/// ```
259/// # use chumsky::{prelude::*, error::Simple};
260/// let digits = one_of::<_, _, extra::Err<Simple<char>>>("0123456789")
261///     .repeated()
262///     .at_least(1)
263///     .collect::<String>();
264///
265/// assert_eq!(digits.parse("48791").into_result(), Ok("48791".to_string()));
266/// assert!(digits.parse("421!53").has_errors());
267/// ```
268pub const fn one_of<'src, T, I, E>(seq: T) -> OneOf<T, I, E>
269where
270    I: ValueInput<'src>,
271    E: ParserExtra<'src, I>,
272    I::Token: PartialEq,
273    T: Seq<'src, I::Token>,
274{
275    OneOf {
276        seq,
277        phantom: EmptyPhantom::new(),
278    }
279}
280
281impl<'src, I, E, T> Parser<'src, I, I::Token, E> for OneOf<T, I, E>
282where
283    I: ValueInput<'src>,
284    E: ParserExtra<'src, I>,
285    I::Token: PartialEq,
286    T: Seq<'src, I::Token>,
287{
288    #[doc(hidden)]
289    #[cfg(feature = "debug")]
290    fn node_info(&self, scope: &mut debug::NodeScope) -> debug::NodeInfo {
291        debug::NodeInfo::OneOf(self.seq.seq_info(scope))
292    }
293
294    #[inline]
295    fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, I::Token> {
296        Self::go_cfg::<M>(self, inp, OneOfCfg::default())
297    }
298
299    go_extra!(I::Token);
300}
301
302impl<'src, I, E, T> ConfigParser<'src, I, I::Token, E> for OneOf<T, I, E>
303where
304    I: ValueInput<'src>,
305    E: ParserExtra<'src, I>,
306    I::Token: PartialEq,
307    T: Seq<'src, I::Token>,
308{
309    type Config = OneOfCfg<T>;
310
311    #[inline]
312    fn go_cfg<M: Mode>(
313        &self,
314        inp: &mut InputRef<'src, '_, I, E>,
315        cfg: Self::Config,
316    ) -> PResult<M, I::Token> {
317        let seq = cfg.seq.as_ref().unwrap_or(&self.seq);
318        let before = inp.save();
319        match inp.next_inner() {
320            #[allow(suspicious_double_ref_op)] // Is this a clippy bug?
321            Some(tok) if seq.contains(tok.borrow()) => Ok(M::bind(|| tok)),
322            found => {
323                let err_span = inp.span_since(before.cursor());
324                inp.rewind(before);
325                inp.add_alt(
326                    seq.seq_iter()
327                        .map(|e| DefaultExpected::Token(T::to_maybe_ref(e))),
328                    found.map(|f| f.into()),
329                    err_span,
330                );
331                Err(())
332            }
333        }
334    }
335}
336
337/// See [`none_of`].
338pub struct NoneOf<T, I, E> {
339    seq: T,
340    #[allow(dead_code)]
341    phantom: EmptyPhantom<(E, I)>,
342}
343
344impl<T: Copy, I, E> Copy for NoneOf<T, I, E> {}
345impl<T: Clone, I, E> Clone for NoneOf<T, I, E> {
346    fn clone(&self) -> Self {
347        Self {
348            seq: self.seq.clone(),
349            phantom: EmptyPhantom::new(),
350        }
351    }
352}
353
354/// A parser that accepts any input that is *not* in a sequence of specific inputs.
355///
356/// The output type of this parser is `I`, the input that was found.
357///
358/// # Examples
359///
360/// ```
361/// # use chumsky::{prelude::*, error::Simple};
362/// let string = one_of::<_, _, extra::Err<Simple<char>>>("\"'")
363///     .ignore_then(none_of("\"'").repeated().collect::<String>())
364///     .then_ignore(one_of("\"'"));
365///
366/// assert_eq!(string.parse("'hello'").into_result(), Ok("hello".to_string()));
367/// assert_eq!(string.parse("\"world\"").into_result(), Ok("world".to_string()));
368/// assert!(string.parse("\"421!53").has_errors());
369/// ```
370pub const fn none_of<'src, T, I, E>(seq: T) -> NoneOf<T, I, E>
371where
372    I: ValueInput<'src>,
373    E: ParserExtra<'src, I>,
374    I::Token: PartialEq,
375    T: Seq<'src, I::Token>,
376{
377    NoneOf {
378        seq,
379        phantom: EmptyPhantom::new(),
380    }
381}
382
383impl<'src, I, E, T> Parser<'src, I, I::Token, E> for NoneOf<T, I, E>
384where
385    I: ValueInput<'src>,
386    E: ParserExtra<'src, I>,
387    I::Token: PartialEq,
388    T: Seq<'src, I::Token>,
389{
390    #[doc(hidden)]
391    #[cfg(feature = "debug")]
392    fn node_info(&self, scope: &mut debug::NodeScope) -> debug::NodeInfo {
393        debug::NodeInfo::NoneOf(self.seq.seq_info(scope))
394    }
395
396    #[inline]
397    fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, I::Token> {
398        let before = inp.save();
399        match inp.next_inner() {
400            // #[allow(suspicious_double_ref_op)] // Is this a clippy bug?
401            Some(tok) if !self.seq.contains(tok.borrow()) => Ok(M::bind(|| tok)),
402            found => {
403                let err_span = inp.span_since(before.cursor());
404                inp.rewind(before);
405                inp.add_alt(
406                    [DefaultExpected::SomethingElse],
407                    found.map(|f| f.into()),
408                    err_span,
409                );
410                Err(())
411            }
412        }
413    }
414
415    go_extra!(I::Token);
416}
417
418/// See [`custom`].
419pub struct Custom<F, I, O, E> {
420    f: F,
421    #[allow(dead_code)]
422    phantom: EmptyPhantom<(E, O, I)>,
423}
424
425impl<F: Copy, I, O, E> Copy for Custom<F, I, O, E> {}
426impl<F: Clone, I, O, E> Clone for Custom<F, I, O, E> {
427    fn clone(&self) -> Self {
428        Self {
429            f: self.f.clone(),
430            phantom: EmptyPhantom::new(),
431        }
432    }
433}
434
435/// Declare a parser that uses custom imperative parsing logic.
436///
437/// This is useful when a particular parser is difficult or impossible to express with chumsky's built-in combinators
438/// alone. For example, custom context-sensitive logic can often be implemented using a custom parser and then
439/// integrated seamlessly into a more 'vanilla' chumsky parser.
440///
441/// See the [`InputRef`] docs for information about what operations custom parsers can perform.
442///
443/// If you are building a library of custom parsers, it is recommended to make use of the [`extension`] API.
444///
445/// # Example
446///
447/// ```
448/// # use chumsky::{prelude::*, error::{Simple, LabelError}};
449///
450/// let question = custom::<_, &str, _, extra::Err<Simple<char>>>(|inp| {
451///     let before = inp.cursor();
452///     match inp.next() {
453///         Some('?') => Ok(()),
454///         found => Err(Simple::new(found.map(Into::into), inp.span_since(&before))),
455///     }
456/// });
457///
458/// assert_eq!(question.parse("?").into_result(), Ok(()));
459/// assert!(question.parse("!").has_errors());
460/// ```
461pub const fn custom<'src, F, I, O, E>(f: F) -> Custom<F, I, O, E>
462where
463    I: Input<'src>,
464    E: ParserExtra<'src, I>,
465    F: Fn(&mut InputRef<'src, '_, I, E>) -> Result<O, E::Error>,
466{
467    Custom {
468        f,
469        phantom: EmptyPhantom::new(),
470    }
471}
472
473impl<'src, I, O, E, F> Parser<'src, I, O, E> for Custom<F, I, O, E>
474where
475    I: Input<'src>,
476    E: ParserExtra<'src, I>,
477    F: Fn(&mut InputRef<'src, '_, I, E>) -> Result<O, E::Error>,
478{
479    #[inline]
480    fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
481        let before = inp.cursor();
482        match (self.f)(inp) {
483            Ok(out) => Ok(M::bind(|| out)),
484            Err(err) => {
485                inp.add_alt_err(&before.inner, err);
486                Err(())
487            }
488        }
489    }
490
491    go_extra!(O);
492}
493
494/// See [`select!`].
495pub struct Select<F, I, O, E> {
496    filter: F,
497    #[allow(dead_code)]
498    phantom: EmptyPhantom<(E, O, I)>,
499}
500
501impl<F: Copy, I, O, E> Copy for Select<F, I, O, E> {}
502impl<F: Clone, I, O, E> Clone for Select<F, I, O, E> {
503    fn clone(&self) -> Self {
504        Self {
505            filter: self.filter.clone(),
506            phantom: EmptyPhantom::new(),
507        }
508    }
509}
510
511/// See [`select!`].
512pub const fn select<'src, F, I, O, E>(filter: F) -> Select<F, I, O, E>
513where
514    I: Input<'src>,
515    I::Token: Clone + 'src,
516    E: ParserExtra<'src, I>,
517    F: Fn(I::Token, &mut MapExtra<'src, '_, I, E>) -> Option<O>,
518{
519    Select {
520        filter,
521        phantom: EmptyPhantom::new(),
522    }
523}
524
525impl<'src, I, O, E, F> Parser<'src, I, O, E> for Select<F, I, O, E>
526where
527    I: Input<'src>,
528    I::Token: Clone + 'src,
529    E: ParserExtra<'src, I>,
530    F: Fn(I::Token, &mut MapExtra<'src, '_, I, E>) -> Option<O>,
531{
532    #[doc(hidden)]
533    #[cfg(feature = "debug")]
534    fn node_info(&self, _scope: &mut debug::NodeScope) -> debug::NodeInfo {
535        debug::NodeInfo::Filter(Box::new(debug::NodeInfo::Any))
536    }
537
538    #[inline]
539    fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
540        let before = inp.save();
541        let next = inp.next_maybe_inner();
542        let found = match next {
543            Some(tok) => {
544                match (self.filter)(
545                    tok.borrow().clone(),
546                    &mut MapExtra::new(before.cursor(), inp),
547                ) {
548                    Some(out) => return Ok(M::bind(|| out)),
549                    None => Some(tok.into()),
550                }
551            }
552            found => found.map(|f| f.into()),
553        };
554        let err_span = inp.span_since(before.cursor());
555        inp.rewind(before);
556        inp.add_alt([DefaultExpected::SomethingElse], found, err_span);
557        Err(())
558    }
559
560    go_extra!(O);
561}
562
563/// See [`select_ref!`].
564pub struct SelectRef<F, I, O, E> {
565    filter: F,
566    #[allow(dead_code)]
567    phantom: EmptyPhantom<(E, O, I)>,
568}
569
570impl<F: Copy, I, O, E> Copy for SelectRef<F, I, O, E> {}
571impl<F: Clone, I, O, E> Clone for SelectRef<F, I, O, E> {
572    fn clone(&self) -> Self {
573        Self {
574            filter: self.filter.clone(),
575            phantom: EmptyPhantom::new(),
576        }
577    }
578}
579
580/// See [`select_ref!`].
581pub const fn select_ref<'src, F, I, O, E>(filter: F) -> SelectRef<F, I, O, E>
582where
583    I: BorrowInput<'src>,
584    I::Token: 'src,
585    E: ParserExtra<'src, I>,
586    F: Fn(&'src I::Token, &mut MapExtra<'src, '_, I, E>) -> Option<O>,
587{
588    SelectRef {
589        filter,
590        phantom: EmptyPhantom::new(),
591    }
592}
593
594impl<'src, I, O, E, F> Parser<'src, I, O, E> for SelectRef<F, I, O, E>
595where
596    I: BorrowInput<'src>,
597    I::Token: 'src,
598    E: ParserExtra<'src, I>,
599    F: Fn(&'src I::Token, &mut MapExtra<'src, '_, I, E>) -> Option<O>,
600{
601    #[inline]
602    fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
603        let before = inp.save();
604        let next = inp.next_ref_inner();
605        let found = match next {
606            Some(tok) => match (self.filter)(tok, &mut MapExtra::new(before.cursor(), inp)) {
607                Some(out) => return Ok(M::bind(|| out)),
608                None => Some(tok.into()),
609            },
610            found => found.map(|f| f.into()),
611        };
612        let err_span = inp.span_since(before.cursor());
613        inp.rewind(before);
614        inp.add_alt([DefaultExpected::SomethingElse], found, err_span);
615        Err(())
616    }
617
618    go_extra!(O);
619}
620
621/// See [`any`].
622pub struct Any<I, E> {
623    #[allow(dead_code)]
624    phantom: EmptyPhantom<(E, I)>,
625}
626
627impl<I, E> Copy for Any<I, E> {}
628impl<I, E> Clone for Any<I, E> {
629    fn clone(&self) -> Self {
630        *self
631    }
632}
633
634impl<'src, I, E> Parser<'src, I, I::Token, E> for Any<I, E>
635where
636    I: ValueInput<'src>,
637    E: ParserExtra<'src, I>,
638{
639    #[doc(hidden)]
640    #[cfg(feature = "debug")]
641    fn node_info(&self, _scope: &mut debug::NodeScope) -> debug::NodeInfo {
642        debug::NodeInfo::Any
643    }
644
645    #[inline]
646    fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, I::Token> {
647        let before = inp.save();
648        match inp.next_inner() {
649            Some(tok) => Ok(M::bind(|| tok)),
650            found => {
651                let err_span = inp.span_since(before.cursor());
652                inp.rewind(before);
653                inp.add_alt([DefaultExpected::Any], found.map(|f| f.into()), err_span);
654                Err(())
655            }
656        }
657    }
658
659    go_extra!(I::Token);
660}
661
662/// A parser that accepts any input (but not the end of input).
663///
664/// The output type of this parser is `I::Token`, the input that was found.
665///
666/// # Examples
667///
668/// ```
669/// # use chumsky::{prelude::*, error::Simple};
670/// let any = any::<_, extra::Err<Simple<char>>>();
671///
672/// assert_eq!(any.parse("a").into_result(), Ok('a'));
673/// assert_eq!(any.parse("7").into_result(), Ok('7'));
674/// assert_eq!(any.parse("\t").into_result(), Ok('\t'));
675/// assert!(any.parse("").has_errors());
676/// ```
677pub const fn any<'src, I: Input<'src>, E: ParserExtra<'src, I>>() -> Any<I, E> {
678    Any {
679        phantom: EmptyPhantom::new(),
680    }
681}
682
683/// See [`any_ref`].
684pub struct AnyRef<I, E> {
685    #[allow(dead_code)]
686    phantom: EmptyPhantom<(E, I)>,
687}
688
689impl<I, E> Copy for AnyRef<I, E> {}
690impl<I, E> Clone for AnyRef<I, E> {
691    fn clone(&self) -> Self {
692        *self
693    }
694}
695
696impl<'src, I, E> Parser<'src, I, &'src I::Token, E> for AnyRef<I, E>
697where
698    I: BorrowInput<'src>,
699    E: ParserExtra<'src, I>,
700{
701    #[inline]
702    fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, &'src I::Token> {
703        let before = inp.save();
704        match inp.next_ref_inner() {
705            Some(tok) => Ok(M::bind(|| tok)),
706            found => {
707                let err_span = inp.span_since(before.cursor());
708                inp.rewind(before);
709                inp.add_alt([DefaultExpected::Any], found.map(|f| f.into()), err_span);
710                Err(())
711            }
712        }
713    }
714
715    go_extra!(&'src I::Token);
716}
717
718/// A parser that accepts any input (but not the end of input).
719///
720/// The output type of this parser is `&'src I::Token`, the input that was found.
721///
722/// This function is the borrowing equivalent of [any]. Where possible, it's recommended to use [any] instead.
723///
724/// # Examples
725///
726/// ```
727/// # use chumsky::{prelude::*, error::Simple};
728/// let any_ref_0 = any_ref::<_, extra::Err<Simple<char>>>();
729/// let any_ref_1 = any_ref::<_, extra::Err<Simple<char>>>();
730///
731/// assert_eq!(any_ref_1.parse(&['a'; 1]).into_result(), Ok(&'a'));
732/// assert_eq!(any_ref_1.parse(&['7'; 1]).into_result(), Ok(&'7'));
733/// assert_eq!(any_ref_1.parse(&['\t'; 1]).into_result(), Ok(&'\t'));
734/// assert!(any_ref_0.parse(&[]).has_errors());
735/// ```
736pub const fn any_ref<'src, I: BorrowInput<'src>, E: ParserExtra<'src, I>>() -> AnyRef<I, E> {
737    AnyRef {
738        phantom: EmptyPhantom::new(),
739    }
740}
741
742/// See [`map_ctx`].
743pub struct MapCtx<A, AE, F, E> {
744    pub(crate) parser: A,
745    pub(crate) mapper: F,
746    #[allow(dead_code)]
747    pub(crate) phantom: EmptyPhantom<(AE, E)>,
748}
749
750impl<A: Copy, AE, F: Copy, E> Copy for MapCtx<A, AE, F, E> {}
751impl<A: Clone, AE, F: Clone, E> Clone for MapCtx<A, AE, F, E> {
752    fn clone(&self) -> Self {
753        MapCtx {
754            parser: self.parser.clone(),
755            mapper: self.mapper.clone(),
756            phantom: EmptyPhantom::new(),
757        }
758    }
759}
760
761impl<'src, I, O, E, EI, A, F> Parser<'src, I, O, E> for MapCtx<A, EI, F, E>
762where
763    I: Input<'src>,
764    E: ParserExtra<'src, I>,
765    EI: ParserExtra<'src, I, Error = E::Error, State = E::State>,
766    A: Parser<'src, I, O, EI>,
767    F: Fn(&E::Context) -> EI::Context,
768    EI::Context: 'src,
769{
770    #[inline]
771    fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
772        inp.with_ctx(&(self.mapper)(inp.ctx()), |inp| self.parser.go::<M>(inp))
773    }
774
775    go_extra!(O);
776}
777
778/// Apply a mapping function to the context of this parser.
779///
780/// Note that this combinator will behave differently from all other maps, in terms of which
781/// parsers it effects - while other maps apply to the output of the parser, and thus read left-to-right, this one
782/// applies to the _input_ of the parser, and as such applies right-to-left.
783///
784/// More technically, if all combinators form a 'tree' of parsers, where each node executes
785/// its children in turn, normal maps apply up the tree. This means a parent mapper gets the
786/// result of its children, applies the map, then passes the new result to its parent. This map,
787/// however, applies down the tree. Context is provided from the parent,
788/// such as [`Parser::ignore_with_ctx`] and [`Parser::then_with_ctx`],
789/// and gets altered before being provided to the children.
790///
791/// ```
792/// # use chumsky::{prelude::*, error::Simple};
793///
794/// let upper = just::<u8, &[u8], extra::Context<u8>>(b'0').configure(|cfg, ctx: &u8| cfg.seq(*ctx));
795///
796/// let inc = one_of::<_, _, extra::Default>(b'a'..=b'z')
797///     .ignore_with_ctx(map_ctx::<_, u8, &[u8], extra::Context<u8>, extra::Context<u8>, _>(|c: &u8| c.to_ascii_uppercase(), upper))
798///     .to_slice()
799///     .repeated()
800///     .at_least(1)
801///     .collect::<Vec<_>>();
802///
803/// assert_eq!(inc.parse(b"aAbB" as &[_]).into_result(), Ok(vec![b"aA" as &[_], b"bB"]));
804/// assert!(inc.parse(b"aB").has_errors());
805/// ```
806/// You can not only change the value of the context but also change the type entirely:
807/// ```
808/// # use chumsky::{
809///         extra,
810///         primitive::{just, map_ctx},
811///         ConfigParser, Parser,
812/// };
813///
814/// fn string_ctx<'src>() -> impl Parser<'src, &'src str, (), extra::Context<String>> {
815///     just("".to_owned())
816///         .configure(|cfg, s: &String| cfg.seq(s.clone()))
817///         .ignored()
818/// }
819///
820/// fn usize_ctx<'src>() -> impl Parser<'src, &'src str, (), extra::Context<usize>> {
821///     map_ctx::<_, _, _, extra::Context<usize>, extra::Context<String>, _>(
822///        |num: &usize| num.to_string(),
823///        string_ctx(),
824///     )
825/// }
826///
827/// fn specific_usize<'src>(num: usize) -> impl Parser<'src, &'src str, ()> {
828///     usize_ctx().with_ctx(num)
829/// }
830/// assert!(!specific_usize(10).parse("10").has_errors());
831/// ```
832pub const fn map_ctx<'src, P, OP, I, E, EP, F>(mapper: F, parser: P) -> MapCtx<P, EP, F, E>
833where
834    F: Fn(&E::Context) -> EP::Context,
835    I: Input<'src>,
836    P: Parser<'src, I, OP, EP>,
837    E: ParserExtra<'src, I>,
838    EP: ParserExtra<'src, I>,
839    EP::Context: 'src,
840{
841    MapCtx {
842        parser,
843        mapper,
844        phantom: EmptyPhantom::new(),
845    }
846}
847
848/// See [`fn@todo`].
849pub struct Todo<I, O, E> {
850    location: Location<'static>,
851    #[allow(dead_code)]
852    phantom: EmptyPhantom<(O, E, I)>,
853}
854
855impl<I, O, E> Copy for Todo<I, O, E> {}
856impl<I, O, E> Clone for Todo<I, O, E> {
857    fn clone(&self) -> Self {
858        *self
859    }
860}
861
862/// A parser that can be used wherever you need to implement a parser later.
863///
864/// This parser is analogous to the [`todo!`] and [`unimplemented!`] macros, but will produce a panic when used to
865/// parse input, not immediately when invoked.
866///
867/// This function is useful when developing your parser, allowing you to prototype and run parts of your parser without
868/// committing to implementing the entire thing immediately.
869///
870/// The output type of this parser is whatever you want it to be: it'll never produce output!
871///
872/// # Examples
873///
874/// ```should_panic
875/// # use chumsky::prelude::*;
876/// let int = just::<_, _, extra::Err<Simple<char>>>("0x").ignore_then(todo())
877///     .or(just("0b").ignore_then(text::digits(2).to_slice()))
878///     .or(text::int(10).to_slice());
879///
880/// // Decimal numbers are parsed
881/// assert_eq!(int.parse("12").into_result(), Ok("12"));
882/// // Binary numbers are parsed
883/// assert_eq!(int.parse("0b00101").into_result(), Ok("00101"));
884/// // Parsing hexidecimal numbers results in a panic because the parser is unimplemented
885/// int.parse("0xd4");
886/// ```
887#[track_caller]
888pub fn todo<'src, I: Input<'src>, O, E: ParserExtra<'src, I>>() -> Todo<I, O, E> {
889    Todo {
890        location: *Location::caller(),
891        phantom: EmptyPhantom::new(),
892    }
893}
894
895impl<'src, I, O, E> Parser<'src, I, O, E> for Todo<I, O, E>
896where
897    I: Input<'src>,
898    E: ParserExtra<'src, I>,
899{
900    #[inline]
901    fn go<M: Mode>(&self, _inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
902        todo!(
903            "Attempted to use an unimplemented parser at {}",
904            self.location
905        )
906    }
907
908    go_extra!(O);
909}
910
911/// See [`choice`].
912#[derive(Copy, Clone)]
913pub struct Choice<T> {
914    parsers: T,
915}
916
917/// Parse using a tuple of many parsers, producing the output of the first to successfully parse.
918///
919/// This primitive has a twofold improvement over a chain of [`Parser::or`] calls:
920///
921/// - Rust's trait solver seems to resolve the [`Parser`] impl for this type much faster, significantly reducing
922///   compilation times.
923///
924/// - Parsing is likely a little faster in some cases because the resulting parser is 'less careful' about error
925///   routing, and doesn't perform the same fine-grained error prioritization that [`Parser::or`] does.
926///
927/// These qualities make this parser ideal for lexers.
928///
929/// The output type of this parser is the output type of the inner parsers.
930///
931/// # Examples
932///
933/// ```
934/// # use chumsky::prelude::*;
935/// #[derive(Clone, Debug, PartialEq)]
936/// enum Token<'src> {
937///     If,
938///     For,
939///     While,
940///     Fn,
941///     Int(u64),
942///     Ident(&'src str),
943/// }
944///
945/// let tokens = choice((
946///     text::ascii::keyword::<_, _, extra::Err<Simple<char>>>("if").to(Token::If),
947///     text::ascii::keyword("for").to(Token::For),
948///     text::ascii::keyword("while").to(Token::While),
949///     text::ascii::keyword("fn").to(Token::Fn),
950///     text::int(10).from_str().unwrapped().map(Token::Int),
951///     text::ascii::ident().map(Token::Ident),
952/// ))
953///     .padded()
954///     .repeated()
955///     .collect::<Vec<_>>();
956///
957/// use Token::*;
958/// assert_eq!(
959///     tokens.parse("if 56 for foo while 42 fn bar").into_result(),
960///     Ok(vec![If, Int(56), For, Ident("foo"), While, Int(42), Fn, Ident("bar")]),
961/// );
962/// ```
963pub const fn choice<T>(parsers: T) -> Choice<T> {
964    Choice { parsers }
965}
966
967macro_rules! impl_choice_for_tuple {
968    () => {};
969    ($head:ident $($X:ident)*) => {
970        impl_choice_for_tuple!($($X)*);
971        impl_choice_for_tuple!(~ $head $($X)*);
972    };
973    (~ $Head:ident $($X:ident)+) => {
974        #[allow(unused_variables, non_snake_case)]
975        impl<'src, I, E, $Head, $($X),*, O> Parser<'src, I, O, E> for Choice<($Head, $($X,)*)>
976        where
977            I: Input<'src>,
978            E: ParserExtra<'src, I>,
979            $Head: Parser<'src, I, O, E>,
980            $($X: Parser<'src, I, O, E>),*
981        {
982            #[doc(hidden)]
983            #[cfg(feature = "debug")]
984            fn node_info(&self, scope: &mut debug::NodeScope) -> debug::NodeInfo {
985                let Choice { parsers: ($Head, $($X,)*), .. } = self;
986                debug::NodeInfo::Choice(vec![$Head.node_info(scope), $($X.node_info(scope)),*])
987            }
988
989            #[inline]
990            fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
991                let before = inp.save();
992
993                let Choice { parsers: ($Head, $($X,)*), .. } = self;
994
995                if let Ok(out) = $Head.go::<M>(inp) {
996                    return Ok(out);
997                }
998
999                $(
1000                    inp.rewind(before.clone());
1001                    if let Ok(out) = $X.go::<M>(inp) {
1002                        return Ok(out);
1003                    }
1004                )*
1005
1006                Err(())
1007            }
1008
1009            go_extra!(O);
1010        }
1011    };
1012    (~ $Head:ident) => {
1013        impl<'src, I, E, $Head, O> Parser<'src, I, O, E> for Choice<($Head,)>
1014        where
1015            I: Input<'src>,
1016            E: ParserExtra<'src, I>,
1017            $Head:  Parser<'src, I, O, E>,
1018        {
1019            #[inline]
1020            fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
1021                self.parsers.0.go::<M>(inp)
1022            }
1023
1024            go_extra!(O);
1025        }
1026    };
1027}
1028
1029impl_choice_for_tuple!(A_ B_ C_ D_ E_ F_ G_ H_ I_ J_ K_ L_ M_ N_ O_ P_ Q_ R_ S_ T_ U_ V_ W_ X_ Y_ Z_);
1030
1031impl<'src, A, I, O, E> Parser<'src, I, O, E> for Choice<&[A]>
1032where
1033    A: Parser<'src, I, O, E>,
1034    I: Input<'src>,
1035    E: ParserExtra<'src, I>,
1036{
1037    #[inline]
1038    fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
1039        if self.parsers.is_empty() {
1040            let offs = inp.cursor();
1041            let err_span = inp.span_since(&offs);
1042            inp.add_alt([], None, err_span);
1043            Err(())
1044        } else {
1045            let before = inp.save();
1046            for parser in self.parsers.iter() {
1047                inp.rewind(before.clone());
1048                if let Ok(out) = parser.go::<M>(inp) {
1049                    return Ok(out);
1050                }
1051            }
1052            Err(())
1053        }
1054    }
1055
1056    go_extra!(O);
1057}
1058
1059impl<'src, A, I, O, E> Parser<'src, I, O, E> for Choice<Vec<A>>
1060where
1061    A: Parser<'src, I, O, E>,
1062    I: Input<'src>,
1063    E: ParserExtra<'src, I>,
1064{
1065    #[inline]
1066    fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
1067        choice(&self.parsers[..]).go::<M>(inp)
1068    }
1069    go_extra!(O);
1070}
1071
1072impl<'src, A, I, O, E, const N: usize> Parser<'src, I, O, E> for Choice<[A; N]>
1073where
1074    A: Parser<'src, I, O, E>,
1075    I: Input<'src>,
1076    E: ParserExtra<'src, I>,
1077{
1078    #[inline]
1079    fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
1080        choice(&self.parsers[..]).go::<M>(inp)
1081    }
1082    go_extra!(O);
1083}
1084
1085/// See [`group`].
1086#[derive(Copy, Clone)]
1087pub struct Group<T> {
1088    parsers: T,
1089}
1090
1091/// Parse using a tuple of many parsers, producing a tuple of outputs if all successfully parse,
1092/// otherwise returning an error if any parsers fail.
1093///
1094/// This parser is to [`Parser::then`] as [`choice`] is to [`Parser::or`]
1095pub const fn group<T>(parsers: T) -> Group<T> {
1096    Group { parsers }
1097}
1098
1099impl<'src, I, O, E, P, const N: usize> Parser<'src, I, [O; N], E> for Group<[P; N]>
1100where
1101    I: Input<'src>,
1102    E: ParserExtra<'src, I>,
1103    P: Parser<'src, I, O, E>,
1104{
1105    #[inline]
1106    fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, [O; N]> {
1107        let mut arr: [MaybeUninit<_>; N] = MaybeUninitExt::uninit_array();
1108        self.parsers
1109            .iter()
1110            .zip(arr.iter_mut())
1111            .try_for_each(|(p, res)| {
1112                res.write(p.go::<M>(inp)?);
1113                Ok(())
1114            })?;
1115        // SAFETY: We guarantee that all parers succeeded and as such all items have been initialized
1116        //         if we reach this point
1117        Ok(M::array(unsafe { MaybeUninitExt::array_assume_init(arr) }))
1118    }
1119
1120    go_extra!([O; N]);
1121}
1122
1123macro_rules! flatten_map {
1124    // map a single element into a 1-tuple
1125    (<$M:ident> $head:ident) => {
1126        $M::map(
1127            $head,
1128            |$head| ($head,),
1129        )
1130    };
1131    // combine two elements into a 2-tuple
1132    (<$M:ident> $head1:ident $head2:ident) => {
1133        $M::combine(
1134            $head1,
1135            $head2,
1136            |$head1, $head2| ($head1, $head2),
1137        )
1138    };
1139    // combine and flatten n-tuples from recursion
1140    (<$M:ident> $head:ident $($X:ident)+) => {
1141        $M::combine(
1142            $head,
1143            flatten_map!(
1144                <$M>
1145                $($X)+
1146            ),
1147            |$head, ($($X),+)| ($head, $($X),+),
1148        )
1149    };
1150}
1151
1152macro_rules! impl_group_for_tuple {
1153    () => {};
1154    ($head:ident $ohead:ident $($X:ident $O:ident)*) => {
1155        impl_group_for_tuple!($($X $O)*);
1156        impl_group_for_tuple!(~ $head $ohead $($X $O)*);
1157    };
1158    (~ $($X:ident $O:ident)*) => {
1159        #[allow(unused_variables, non_snake_case)]
1160        impl<'src, I, E, $($X),*, $($O),*> Parser<'src, I, ($($O,)*), E> for Group<($($X,)*)>
1161        where
1162            I: Input<'src>,
1163            E: ParserExtra<'src, I>,
1164            $($X: Parser<'src, I, $O, E>),*
1165        {
1166            #[inline]
1167            fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, ($($O,)*)> {
1168                let Group { parsers: ($($X,)*) } = self;
1169
1170                $(
1171                    let $X = $X.go::<M>(inp)?;
1172                )*
1173
1174                Ok(flatten_map!(<M> $($X)*))
1175            }
1176
1177            go_extra!(($($O,)*));
1178        }
1179    };
1180}
1181
1182impl_group_for_tuple! {
1183    A_ OA
1184    B_ OB
1185    C_ OC
1186    D_ OD
1187    E_ OE
1188    F_ OF
1189    G_ OG
1190    H_ OH
1191    I_ OI
1192    J_ OJ
1193    K_ OK
1194    L_ OL
1195    M_ OM
1196    N_ ON
1197    O_ OO
1198    P_ OP
1199    Q_ OQ
1200    R_ OR
1201    S_ OS
1202    T_ OT
1203    U_ OU
1204    V_ OV
1205    W_ OW
1206    X_ OX
1207    Y_ OY
1208    Z_ OZ
1209}
1210
1211/// See [`set`].
1212#[derive(Copy, Clone)]
1213pub struct Set<T> {
1214    parsers: T,
1215}
1216
1217/// Parse using a tuple of parsers in any order, producing the output of the parser set in the provided order.
1218///
1219/// The output type of this parser is a tuple of the output types of the inner parsers.
1220///
1221/// All parsers must successfully parse.
1222///
1223/// Parsers are always tried in the provided order, which means that most specific parsers must be
1224/// provided first or they might never match. In other words, if two parsers match the same item,
1225/// the `set`'s input must containt this item twice for the `set` to be successful.
1226///
1227/// Be careful! This combinator is O(n^2), which means that in the worst case you could slow down parsing with
1228/// a lot of parser calls. The worst case happens when all items are present but in the reverse
1229/// order compared to the list of parsers. To mitigate this you should order your parsers in the
1230/// same order input usually happens. And you should avoid having too many parsers in the set.
1231///
1232/// Parsers that match without making progress (like `empty()` or `something.or_not()`) are applied
1233/// last to make sure they have no better alternative.
1234///
1235/// This means that you can make a parser optional by adding a call to `.or_not()` to it.
1236///
1237/// # Examples
1238///
1239/// ```
1240/// # use chumsky::prelude::*;
1241/// let options = set((
1242///     just::<_, _, extra::Err<Simple<char>>>("apple\n"),
1243///     just("banana\n"),
1244///     just("carrot\n").or_not(),
1245/// ));
1246///
1247/// assert_eq!(
1248///     options.parse("banana\napple\n").into_result(),
1249///     Ok(("apple\n", "banana\n", None)),
1250/// );
1251/// ```
1252pub const fn set<T>(parsers: T) -> Set<T> {
1253    Set { parsers }
1254}
1255
1256fn go_or_finish<'src, O, I, E, P, M>(
1257    item: &mut Option<M::Output<O>>,
1258    parser: &P,
1259    inp: &mut InputRef<'src, '_, I, E>,
1260) -> PResult<M, ()>
1261where
1262    I: Input<'src>,
1263    E: ParserExtra<'src, I>,
1264    P: Parser<'src, I, O, E>,
1265    M: Mode,
1266{
1267    if item.is_none() {
1268        match parser.go::<M>(inp) {
1269            Ok(out) => {
1270                *item = Some(out);
1271            }
1272            Err(()) => {
1273                return Err(());
1274            }
1275        }
1276    }
1277    Ok(M::bind(|| ()))
1278}
1279
1280fn go_or_rewind<'src, O, I, E, P, M>(
1281    item: &mut Option<M::Output<O>>,
1282    parser: &P,
1283    inp: &mut InputRef<'src, '_, I, E>,
1284) where
1285    I: Input<'src>,
1286    E: ParserExtra<'src, I>,
1287    P: Parser<'src, I, O, E>,
1288    M: Mode,
1289{
1290    if item.is_none() {
1291        let save_before = inp.save();
1292        let pos_before = inp.cursor();
1293        match parser.go::<M>(inp) {
1294            Ok(out) => {
1295                if pos_before == inp.cursor() {
1296                    inp.rewind(save_before.clone());
1297                } else {
1298                    *item = Some(out);
1299                }
1300            }
1301            Err(()) => inp.rewind(save_before.clone()),
1302        }
1303    }
1304}
1305
1306macro_rules! impl_set_for_tuple {
1307    () => {};
1308    ($head_1:ident $head_2:ident $head_3:ident $($X:ident)*) => {
1309        impl_set_for_tuple!($($X)*);
1310        impl_set_for_tuple!(~ $head_1 $head_2 $head_3 $($X)*);
1311    };
1312    (~ $($O:ident $P:ident $I:ident)+) => {
1313        #[allow(unused_variables, non_snake_case)]
1314        impl<'src, I, E, $($P),*, $($O,)*> Parser<'src, I, ($($O,)*), E> for Set<($($P,)*)>
1315        where
1316            I: Input<'src>,
1317            E: ParserExtra<'src, I>,
1318            $($P: Parser<'src, I, $O, E>),*
1319        {
1320            #[inline]
1321            fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, ($($O,)*)> {
1322                let Set { parsers: ($($P,)*), .. } = self;
1323                $( let mut $I: Option<M::Output<$O>> = None; )*
1324
1325                // first iterate until there are no progress
1326                loop {
1327                    let start = inp.cursor();
1328                    $( go_or_rewind::<_, _, _, _, M>(&mut $I, $P, inp); )*
1329                    // none matched during this loop
1330                    if start == inp.cursor() {
1331                        break;
1332                    }
1333                }
1334
1335                // Then a final iteration that matches remaining empty parsers
1336                $( go_or_finish::<_, _, _, _, M>(&mut $I, $P, inp)?; )*
1337
1338                // unwrap is ok since we matched all items in the set exactly once
1339                $( let $I = $I.unwrap(); )*
1340                Ok(flatten_map!(<M> $($I)*))
1341            }
1342
1343            go_extra!(($($O,)*));
1344        }
1345    };
1346}
1347
1348impl_set_for_tuple!(A1 A2 A3 B1 B2 B3 C1 C2 C3 D1 D2 D3 E1 E2 E3 F1 F2 F3 G1 G2 G3 H1 H2 H3 I1 I2 I3 J1 J2 J3 K1 K2 K3 L1 L2 L3 M1 M2 M3 N1 N2 N3 O1 O2 O3 P1 P2 P3 Q1 Q2 Q3 R1 R2 R3 S1 S2 S3 T1 T2 T3 U1 U2 U3 V1 V2 V3 W1 W2 W3 X1 X2 X3 Y1 Y2 Y3 Z1 Z2 Z3);
1349
1350impl<'src, P, I, O, E> Parser<'src, I, Vec<O>, E> for Set<Vec<P>>
1351where
1352    P: Parser<'src, I, O, E>,
1353    I: Input<'src>,
1354    E: ParserExtra<'src, I>,
1355{
1356    #[inline]
1357    fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, Vec<O>> {
1358        let mut tmp = self
1359            .parsers
1360            .iter()
1361            .map(|_| None)
1362            .collect::<Vec<Option<M::Output<O>>>>();
1363
1364        // first iterate until there are no progress
1365        loop {
1366            let start = inp.cursor();
1367            for (i, parser) in self.parsers.iter().enumerate() {
1368                go_or_rewind::<_, _, _, _, M>(&mut tmp[i], parser, inp);
1369            }
1370            // none matched during this loop
1371            if start == inp.cursor() {
1372                break;
1373            }
1374        }
1375
1376        // Then a final iteration that matches remaining empty parsers
1377        for (i, parser) in self.parsers.iter().enumerate() {
1378            go_or_finish::<_, _, _, _, M>(&mut tmp[i], parser, inp)?;
1379        }
1380
1381        // unwrap is ok since we matched all items in the se
1382        let mut result = M::bind(|| Vec::new());
1383        tmp.into_iter()
1384            .for_each(|x| M::combine_mut(&mut result, x.unwrap(), |result, x| result.push(x)));
1385        Ok(result)
1386    }
1387
1388    go_extra!(Vec<O>);
1389}
1390
1391impl<'src, P, I, O, E, const N: usize> Parser<'src, I, [O; N], E> for Set<[P; N]>
1392where
1393    P: Parser<'src, I, O, E>,
1394    I: Input<'src>,
1395    E: ParserExtra<'src, I>,
1396    // remove this requirement when MSRV > 1.80
1397    O: Copy,
1398{
1399    #[inline]
1400    fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, [O; N]> {
1401        // Replace this when MRSV > 1.80
1402        //let mut tmp: [Option<M::Output<O>>; N] = [ const { None }; N];
1403        let mut tmp: [Option<O>; N] = [None; N];
1404
1405        // first iterate until there are no progress
1406        loop {
1407            let start = inp.cursor();
1408            for (i, parser) in self.parsers.iter().enumerate() {
1409                // Replace this when MRSV > 1.80
1410                //go_or_rewind::<_, _, _, _, M>(&mut tmp[i], parser, inp);
1411                go_or_rewind::<_, _, _, _, Emit>(&mut tmp[i], parser, inp);
1412            }
1413            // none matched during this loop
1414            if start == inp.cursor() {
1415                break;
1416            }
1417        }
1418
1419        // Then a final iteration that matches remaining empty parsers
1420        for (i, parser) in self.parsers.iter().enumerate() {
1421            // Replace this when MRSV > 1.80
1422            //go_or_finish::<_, _, _, _, M>(&mut tmp[i], parser, inp)?;
1423            go_or_finish::<_, _, _, _, Emit>(&mut tmp[i], parser, inp)?;
1424        }
1425
1426        // unwrap is ok since we matched all items in the se
1427        // Replace this when MRSV > 1.80
1428        //Ok(M::array( tmp.map(|x| x.unwrap()) ))
1429        Ok(M::bind(|| tmp.map(|x| x.unwrap())))
1430    }
1431
1432    go_extra!([O; N]);
1433}
1434
1435#[cfg(test)]
1436mod tests {
1437    use super::*;
1438
1439    #[test]
1440    fn set_parser() {
1441        fn just(s: &str) -> Just<&str, &str, extra::Err<EmptyErr>> {
1442            super::just(s)
1443        }
1444
1445        // test ordering
1446        let parser = set((just("abc"), just("def"), just("ijk")));
1447        assert_eq!(
1448            parser.parse("ijkdefabc").into_result(),
1449            Ok(("abc", "def", "ijk")),
1450        );
1451        assert_eq!(
1452            parser.parse("abcdefijk").into_result(),
1453            Ok(("abc", "def", "ijk")),
1454        );
1455
1456        // test inclusion
1457        let parser = set((choice((just("abc"), just("def"))), just("abc")));
1458        assert_eq!(parser.parse("defabc").into_result(), Ok(("def", "abc")),);
1459        let parser = set((choice((just("abc"), just("def"))), just("abc")));
1460        assert!(parser.parse("abcdef").into_result().is_err());
1461
1462        // test optionals
1463        let parser = set((
1464            just("abc").or_not(),
1465            just("def").or_not(),
1466            just("ijk").or_not(),
1467        ));
1468        assert_eq!(
1469            parser.parse("ijkdefabc").into_result(),
1470            Ok((Some("abc"), Some("def"), Some("ijk"))),
1471        );
1472        assert_eq!(
1473            parser.parse("ijkabc").into_result(),
1474            Ok((Some("abc"), None, Some("ijk"))),
1475        );
1476        assert_eq!(parser.parse("").into_result(), Ok((None, None, None)),);
1477
1478        // test types
1479        let parser = set(vec![just("abc"), just("def"), just("ijk")]);
1480        assert_eq!(
1481            parser.parse("ijkdefabc").into_result(),
1482            Ok(vec!["abc", "def", "ijk"]),
1483        );
1484        let parser = set([just("abc"), just("def"), just("ijk")]);
1485        assert_eq!(
1486            parser.parse("ijkdefabc").into_result(),
1487            Ok(["abc", "def", "ijk"]),
1488        );
1489    }
1490}