pcomb/
parse.rs

1//! Generic static-dispatch-based parser combinators over slice types.
2//!
3//! For now, see the documentation for the [Parse] trait, which is the main trait of this module.
4// todo: add descriptive module documentation: introduce the idea of the remainder and output
5
6#[cfg(feature = "std")]
7use std::error::Error;
8
9use core::convert::Infallible;
10use core::fmt::{self, Display, Formatter};
11use core::iter::{self, Extend};
12use core::marker::PhantomData;
13use core::mem::{self, MaybeUninit};
14use core::ptr;
15
16use crate::slice::Slice;
17
18
19/// A non-descriptive failure to parse a given input
20#[derive(Debug, PartialEq, Eq, Clone, Hash)]
21pub enum ParseError {
22  /// General rejection: an invalid input has been rejected for an unspecified reason
23  Reject,
24  /// The input is insufficiently short to conclusively determine if it matches
25  Indeterminate,  // todo: this is not respected in certain cases
26}
27
28impl Display for ParseError {
29  fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
30    match self {
31      ParseError::Reject => write!(f, "Input rejected"),
32      ParseError::Indeterminate => {
33        write!(f, "Insufficent input to conclusively determine validity")
34      },
35    }
36  }
37}
38
39#[cfg(feature = "std")]
40impl Error for ParseError {}
41
42
43/// Tries to parse part of a slice into another form, returning the unparsed
44/// __remainder__ of the slice and the __output__ value, or an error.
45///
46/// This trait is also implemented for all `Fn(T) -> Result<(T, Output), Err>`,
47/// so it's possible to use a function to implement a parser.
48///
49/// # Examples
50/// ```
51/// use pcomb::parse::{Parse, ParseError};
52/// use pcomb::slice::Slice;
53///
54/// fn alpha(input: &str) -> Result<(&str, &str), ParseError> {
55///   let (char, rest) = Slice::split_at(&input, 1).ok_or(ParseError::Reject)?;
56///
57///   if "a" <= char && char <= "z" || "A" <= char && char <= "Z" {
58///     Ok((rest, char))
59///   } else {
60///     Err(ParseError::Reject)
61///   }
62/// }
63///
64/// assert_eq!(alpha.parse("asdf"), Ok(("sdf", "a")));
65/// assert_eq!(alpha.parse("1234"), Err(ParseError::Reject));
66/// ```
67#[must_use = "parsers are lazy and do not do anything until consumed"]
68pub trait Parse<T> {
69  type Output;
70  type Err;
71
72  /// Try to parse part of a slice, returning a tuple of the remainder (the
73  /// unparsed slice) and the output value.
74  fn parse(self, input: T) -> Result<(T, Self::Output), Self::Err>;
75
76
77  /// Maps the output of a parser with a function to produce a new output.
78  ///
79  /// # Examples
80  /// ```
81  /// use pcomb::parse::{Parse, Match, ParseError};
82  /// use pcomb::parsers::str::{alpha, integer};
83  ///
84  /// #[derive(Debug, Clone, PartialEq, Eq)]
85  /// enum Op { Add, Sub, Mul, Div, Int(u32) }
86  /// use Op::*;
87  ///
88  /// let parser = Match("+").map(|_| Add)
89  ///   .or(Match("-").map(|_| Sub))
90  ///   .or(Match("*").map(|_| Mul))
91  ///   .or(Match("/").map(|_| Div))
92  ///   .or(integer.map(|num| Int(num)));
93  ///
94  /// assert_eq!(parser.clone().parse("-"), Ok(("", Sub)));
95  /// assert_eq!(parser.clone().parse("24"), Ok(("", Int(24u32))));
96  /// assert_eq!(parser.clone().parse("/"), Ok(("", Div)));
97  /// assert_eq!(parser.clone().parse("*"), Ok(("", Mul)));
98  /// assert_eq!(parser.parse("^"), Err(ParseError::Reject));
99  /// ```
100  fn map<F, O>(self, func: F) -> Map<T, Self, F, O>
101  where F: Fn(Self::Output) -> O, Self: Sized {
102    Map { parser: self, func, _t: PhantomData }
103  }
104
105  // todo: doctest
106  /// Maps the error of a parser with a function to produce a new error.
107  fn map_err<F, E>(self, func: F) -> MapErr<T, Self, F, E>
108  where F: Fn(Self::Err) -> E, Self: Sized {
109    MapErr { parser: self, func, _t: PhantomData }
110  }
111
112  /// Executes the parser if possible, wrapping up the output in an Option.
113  ///
114  /// If you want to provide a default value for None results, see
115  /// [Maybe::unwrap_or].
116  ///
117  /// # Examples
118  /// ```
119  /// use pcomb::parse::{Parse, Match, ParseError};
120  ///
121  /// let parser = Match("http://example.com/index")
122  ///   .fuse(Match(".html").maybe());
123  ///
124  /// assert_eq!(
125  ///   parser.clone().parse("http://example.com/index"),
126  ///   Ok(("", ("http://example.com/index", None)))
127  /// );
128  /// assert_eq!(
129  ///   parser.clone().parse("http://example.com/index.html"),
130  ///   Ok(("", ("http://example.com/index", Some(".html"))))
131  /// );
132  /// ```
133  fn maybe(self) -> Maybe<T, Self>
134  where T: Clone, Self: Sized {
135    Maybe { parser: self, _t: PhantomData }
136  }
137
138  // todo: doctest
139  /// Parses the output of this parser with an inner parser, and passes the
140  /// output through.
141  fn chain<I>(self, inner: I) -> Chain<T, Self, I>
142  where I: Parse<Self::Output, Err = Self::Err>, Self: Sized {
143    Chain { parser: self, inner_parser: inner, _t: PhantomData }
144  }
145
146  /// Takes the union of both combinators, accepting input which passes either
147  /// parser. Both parsers must output the same type.
148  ///
149  /// This is evaluated lazily: if the input would pass both combinators, the
150  /// first from `self` is used.
151  ///
152  /// # Examples
153  /// ```
154  /// use pcomb::parse::{Parse, Match, ParseError};
155  /// use pcomb::parsers::str::{alpha, integer};
156  ///
157  /// let parser = integer
158  ///   .fuse(
159  ///     Match("+")
160  ///       .or(Match("-"))
161  ///       .or(Match("*"))
162  ///       .or(Match("/"))
163  ///   )  // Output = (u32, &str)
164  ///   .fuse(integer);  // Output = ((u32, &str), u32)
165  ///
166  /// assert_eq!(parser.clone().parse("54+3"), Ok(("", ((54, "+"), 3))));
167  /// assert_eq!(parser.clone().parse("19/0"), Ok(("", ((19, "/"), 0))));
168  /// assert_eq!(parser.parse("-2"), Err(ParseError::Reject));
169  /// ```
170  fn or<O>(self, other: O) -> Or<T, Self, O>
171  where T: Clone, O: Parse<T, Output = Self::Output, Err = Self::Err>, Self: Sized {
172    Or { left: self, right: other, _t: PhantomData }
173  }
174
175  // todo: doctest
176  /// Takes the conjunction of both combinators, accepting input which passes
177  /// both parsers. The remainders of both combinators must be equal, otherwise
178  /// the specified length error is yielded.
179  ///
180  /// This is evaluated lazily: if the first input does not pass, the other is
181  /// not ran. If you want to ignore the output of one of the parsers, see
182  /// [And::first] or [And::second].
183  fn and<O>(self, length_err: Self::Err, other: O) -> And<T, Self, O>
184  where T: Clone + Eq, O: Parse<T, Err = Self::Err>, Self: Sized {
185    And { left: self, right: other, length_err: length_err, _t: PhantomData }
186  }
187
188  /// Accepts input which passes this parser first and then `other`, packing the
189  /// output as a tuple. The remainder of the input is passed to `other`.
190  ///
191  /// If you want to concatenate the output of both parsers, see
192  /// [Parse::fuse_extend]. If you want to ignore the output of one of the
193  /// parsers, see [Fuse::first] or [Fuse::second].
194  ///
195  /// # Examples
196  /// ```
197  /// use pcomb::parse::{Parse, Match, ParseError};
198  /// use pcomb::parsers::str::{alpha, integer};
199  ///
200  /// let parser = alpha
201  ///   .fuse(Match(" = ")) // Fuse's Output = ("x", " = ")
202  ///   .first()  // now the Output = "x"
203  ///   .fuse(integer);  // Output = ("x", 2u32)
204  ///
205  /// assert_eq!(parser.parse("x = 2;"), Ok((";", ("x", 2u32))));
206  /// ```
207  fn fuse<O>(self, other: O) -> Fuse<T, Self, O>
208  where O: Parse<T, Err = Self::Err>, Self: Sized, {
209    Fuse { left: self, right: other, _t: PhantomData }
210  }
211
212  /// Accepts input which passes this parser first and then `other`, extending
213  /// this output with `other`'s output. The remainder of the input is passed
214  /// to `other`.
215  ///
216  ///
217  /// # Examples
218  /// ```
219  /// use pcomb::parse::{Parse, Match};
220  ///
221  /// // we want to verify it is an integer but ignore the output
222  /// let parser = Match("hello")
223  ///   .map(|out| out.to_owned())  // map to a type that supports Extend
224  ///   .fuse_extend(Match(" "))
225  ///   .fuse_extend(Match("world"));
226  ///
227  /// assert_eq!(parser.parse("hello world!"), Ok(("!", "hello world".to_owned())));
228  /// ```
229  fn fuse_extend<O>(self, other: O) -> FuseExtend<T, Self, Self::Output, O>
230  where O: Parse<T, Err = Self::Err>, Self::Output: Extend<O::Output>, Self: Sized {
231    FuseExtend { left: self, right: other, _t: PhantomData }
232  }
233
234  /// Accepts exactly a constant amount of repetitions of this parser, packing
235  /// the output as a constant array.
236  ///
237  /// # Examples
238  /// ```
239  /// use pcomb::parse::{Parse, Match, ParseError};
240  /// use pcomb::parsers::str::alpha;
241  ///
242  /// let parser = alpha.repeat_const::<5>();
243  ///
244  /// assert_eq!(
245  ///   parser.clone().parse("hello world!"),
246  ///   Ok((" world!", ["h", "e", "l", "l", "o"]))
247  /// );
248  /// assert_eq!(parser.clone().parse("hi world"), Err(ParseError::Reject));
249  /// ```
250  fn repeat_const<const N: usize>(self) -> RepeatConst<T, Self, N>
251  where Self: Clone + Sized {
252    RepeatConst { parser: self, _t: PhantomData }
253  }
254
255  /// Accepts any amount of repetitions of this parser, extending the output
256  /// into the given collection.
257  ///
258  /// Default is the default value of the collection, and is what is yielded
259  /// when no repetitions occur.
260  ///
261  /// # Examples
262  /// ```
263  /// use pcomb::parse::{Parse, Match};
264  /// use pcomb::parsers::str::alpha;
265  ///
266  /// let word = alpha.repeat_greedy(String::new());  // a String of consecutive letters
267  /// let words_by_spaces = word.clone()  // a Vec of words separated by spaces
268  ///   .fuse(Match(" "))
269  ///   .first()
270  ///   .repeat_greedy(Vec::new());
271  ///
272  /// assert_eq!(
273  ///   word.clone().parse("hello world"),
274  ///   Ok((" world", "hello".to_owned()))
275  /// );
276  /// assert_eq!(
277  ///   words_by_spaces.clone().parse("hello world "),
278  ///   Ok(("", vec!["hello".to_owned(), "world".to_owned()]))
279  /// );
280  /// ```
281  fn repeat_greedy<O>(self, default: O) -> RepeatGreedy<T, Self, O>
282  where T: Clone, O: Extend<Self::Output>, Self: Clone + Sized {
283    RepeatGreedy { parser: self, output: default, _t: PhantomData }
284  }
285}
286
287impl<T, F, R, E> Parse<T> for F
288where F: Fn(T) -> Result<(T, R), E> {
289  type Err = E;
290  type Output = R;
291
292  fn parse(self, input: T) -> Result<(T, Self::Output), Self::Err> { self(input) }
293}
294
295
296// todo: doctest
297/// Accepts no input, and produce an empty output.
298///
299/// Empty is infallible: use [Parse::map_err] to specify an error type.
300#[derive(Debug, PartialEq, Eq, Clone, Hash, Default)]
301#[must_use = "parsers are lazy and do not do anything until consumed"]
302pub struct Empty;
303
304impl<T: Slice<Output = T>> Parse<T> for Empty {
305  type Err = Infallible;  // convert to never type (!) when stable
306  type Output = T;
307
308  fn parse(self, input: T) -> Result<(T, Self::Output), Self::Err> {
309    Ok(input.split_at(input.len()).expect("slicing from [i..i] from to [..] must never fail"))
310  }
311}
312
313
314// todo: doctest
315/// Accept the entire remainder for any input.
316///
317/// Identity is infallible: use [Parse::map_err] to specify an error type.
318#[derive(Debug, PartialEq, Eq, Clone, Hash, Default)]
319#[must_use = "parsers are lazy and do not do anything until consumed"]
320pub struct Identity;
321
322impl<T: Slice<Output = T>> Parse<T> for Identity {
323  type Err = Infallible;  // convert to never type (!) when stable
324  type Output = T;
325
326  fn parse(self, input: T) -> Result<(T, Self::Output), Self::Err> {
327    Ok(input.split_at(0).expect("slicing from [i..i] or from [..] must never fail"))
328  }
329}
330
331
332// todo: doctest
333/// Accepts the slice if the input matches the specified sliced.
334#[derive(Debug, PartialEq, Eq, Clone, Hash)]
335#[must_use = "parsers are lazy and do not do anything until consumed"]
336pub struct Match<T: Slice + Eq>(pub T);
337
338impl<T: Slice<Output = T> + Eq> Parse<T> for Match<T> {
339  type Err = ParseError;
340  type Output = T::Output;
341
342  fn parse(self, input: T) -> Result<(T, Self::Output), Self::Err> {
343    if self.0.len() > input.len() {
344      Err(ParseError::Indeterminate)
345    } else {
346      input
347        .split_at(self.0.len())
348        .filter(|(matched, _)| *matched == self.0)
349        .map(|(matched, rest)| (rest, matched))
350        .ok_or(ParseError::Reject)
351    }
352  }
353}
354
355
356/// The parser for [Parse::map], see method for documentation.
357#[derive(Debug, PartialEq, Eq, Clone, Hash)]
358#[must_use = "parsers are lazy and do not do anything until consumed"]
359pub struct Map<T, P, F, O>
360where P: Parse<T>, F: Fn(P::Output) -> O {
361  parser: P,
362  func: F,
363  _t: PhantomData<T>,
364}
365
366impl<T, P, F, O> Parse<T> for Map<T, P, F, O>
367where P: Parse<T>, F: Fn(P::Output) -> O {
368  type Err = P::Err;
369  type Output = O;
370
371  fn parse(self, input: T) -> Result<(T, Self::Output), Self::Err> {
372    self.parser.parse(input).map(|(rest, output)| {
373      (rest, (self.func)(output))
374    })
375  }
376}
377
378
379/// The parser for [Parse::map_err], see method for documentation.
380#[derive(Debug, PartialEq, Eq, Clone, Hash)]
381#[must_use = "parsers are lazy and do not do anything until consumed"]
382pub struct MapErr<T, P, F, E>
383where P: Parse<T>, F: Fn(P::Err) -> E {
384  parser: P,
385  func: F,
386  _t: PhantomData<T>,
387}
388
389impl<T, P, F, E> Parse<T> for MapErr<T, P, F, E>
390where P: Parse<T>, F: Fn(P::Err) -> E {
391  type Err = E;
392  type Output = P::Output;
393
394  fn parse(self, input: T) -> Result<(T, Self::Output), Self::Err> {
395    self.parser.parse(input).map_err(|err| { (self.func)(err) })
396  }
397}
398
399
400/// The parser for [Parse::maybe], see method for documentation.
401#[derive(Debug, PartialEq, Eq, Clone, Hash)]
402#[must_use = "parsers are lazy and do not do anything until consumed"]
403pub struct Maybe<T, P>
404where T: Clone, P: Parse<T> {
405  parser: P,
406  _t: PhantomData<T>,
407}
408
409impl<T, P> Maybe<T, P>
410where T: Clone, P: Parse<T> {
411  /// Unwraps the inner option if possible, or otherwise the provided default
412  /// value is used.
413  ///
414  /// # Examples
415  /// ```
416  /// use pcomb::parse::{Parse, Match, ParseError};
417  ///
418  /// let parser = Match("http://example.com/index").map(|str| str.to_owned())
419  ///   .fuse_extend(Match(".html").maybe().unwrap_or(""));
420  ///
421  /// assert_eq!(
422  ///   parser.clone().parse("http://example.com/index"),
423  ///   Ok(("", "http://example.com/index".to_owned()))
424  /// );
425  /// assert_eq!(
426  ///   parser.parse("http://example.com/index.html"),
427  ///   Ok(("", "http://example.com/index.html".to_owned()))
428  /// );
429  /// ```
430  // note: the generic bounds on the impl Fn cannot include Copy + Send + Sync with specialization
431  pub fn unwrap_or(self, default: P::Output) ->
432  Map<T, Self, impl Clone + Fn(Option<P::Output>) -> P::Output, P::Output>
433  where P::Output: Clone {
434    self.map(move |option| option.unwrap_or(default.clone()))
435  }
436}
437
438impl<T, P> Parse<T> for Maybe<T, P>
439where T: Clone, P: Parse<T> {
440  type Err = P::Err;
441  type Output = Option<P::Output>;
442
443  fn parse(self, input: T) -> Result<(T, Self::Output), Self::Err> {
444    match self.parser.parse(input.clone()) {
445      Ok((rest, output)) => Ok((rest, Some(output))),
446      Err(_) => Ok((input, None)),
447    }
448  }
449}
450
451
452/// The parser for [Parse::chain], see method for documentation.
453#[derive(Debug, PartialEq, Eq, Clone, Hash)]
454#[must_use = "parsers are lazy and do not do anything until consumed"]
455pub struct Chain<T, P, I>
456where P: Parse<T>, I: Parse<P::Output, Err = P::Err> {
457  parser: P,
458  inner_parser: I,
459  _t: PhantomData<T>,
460}
461
462impl<T, P, I> Parse<T> for Chain<T, P, I>
463where P: Parse<T>, I: Parse<P::Output, Err = P::Err> + Clone {
464  type Err = P::Err;
465  type Output = I::Output;
466
467  fn parse(self, input: T) -> Result<(T, Self::Output), Self::Err> {
468    let (rest, res) = self.parser
469      .map(|output| self.inner_parser.clone().parse(output))
470      .parse(input)?;
471
472    let (_, output) = res?;
473    Ok((rest, output))
474  }
475}
476
477
478/// The parser for [Parse::or], see method for documentation.
479#[derive(Debug, PartialEq, Eq, Clone, Hash)]
480#[must_use = "parsers are lazy and do not do anything until consumed"]
481pub struct Or<T, L, R>
482where T: Clone, L: Parse<T>, R: Parse<T, Output = L::Output, Err = L::Err> {
483  left: L,
484  right: R,
485  _t: PhantomData<T>,
486}
487
488impl<T, L, R> Parse<T> for Or<T, L, R>
489where T: Clone, L: Parse<T>, R: Parse<T, Output = L::Output, Err = L::Err> {
490  type Err = L::Err;
491  type Output = L::Output;
492
493  fn parse(self, input: T) -> Result<(T, Self::Output), Self::Err> {
494    match self.left.parse(input.clone()) {
495      Ok(res) => Ok(res),
496      Err(_) => self.right.parse(input), // todo: consider handling Indeterminate differently
497    }
498  }
499}
500
501
502/// The parser for [Parse::or], see method for documentation.
503#[derive(Debug, PartialEq, Eq, Clone, Hash)]
504#[must_use = "parsers are lazy and do not do anything until consumed"]
505pub struct And<T, L, R>
506where T: Clone + Eq, L: Parse<T>, R: Parse<T, Err = L::Err> {
507  left: L,
508  right: R,
509  length_err: L::Err,
510  _t: PhantomData<T>,
511}
512
513impl<T, L, R> And<T, L, R>
514where T: Clone + Eq, L: Parse<T>, R: Parse<T, Err = L::Err> {
515  /// Pass through the first parser's output, dropping the output of the second.
516  ///
517  /// Due to the architecture of Parse, it is important to note that both
518  /// parsers are still ran. This is commonly used when the second output of a
519  /// conjunction parser is not desired, such as when checking a precondition.
520  ///
521  /// # Examples
522  /// ```
523  /// use pcomb::parse::{Parse, Match, ParseError};
524  /// use pcomb::parsers::str::integer;
525  ///
526  /// // we want to verify it is an integer but ignore the output
527  /// let parser = Match("420")
528  ///   .and(ParseError::Reject, integer::<u32>)  // this fuse has Output = ("420", 420)
529  ///   .first();  // now Output = "420"
530  ///
531  /// assert_eq!(parser.parse("420.1"), Ok((".1", "420")));
532  /// ```
533  pub fn first(self) -> Map<T, Self, impl Clone + Copy + Send + Sync + Fn((L::Output, R::Output)) -> L::Output, L::Output> {
534    self.map(|(out, _)| out)
535  }
536
537  /// Pass through the second parser's output, dropping the output of the first.
538  ///
539  /// Due to the architecture of Parse, it is important to note that both
540  /// parsers are still ran. This is commonly used when the second output of a
541  /// conjunction parser is not desired, such as when checking a precondition.
542  ///
543  /// # Examples
544  /// ```
545  /// use pcomb::parse::{Parse, Match, ParseError};
546  /// use pcomb::parsers::str::integer;
547  ///
548  /// // we want to verify it is exactly 420 but want it as an integer
549  /// let parser = Match("420")
550  ///   .and(ParseError::Reject, integer::<u32>)  // this fuse has Output = ("420", 420)
551  ///   .second();  // now Output = 420
552  ///
553  /// assert_eq!(parser.parse("420.1"), Ok((".1", 420)));
554  /// ```
555  pub fn second(self) -> Map<T, Self, impl Clone + Copy + Send + Sync + Fn((L::Output, R::Output)) -> R::Output, R::Output> {
556    self.map(|(_, out)| out)
557  }
558}
559
560impl<T, L, R> Parse<T> for And<T, L, R>
561where T: Clone + Eq, L: Parse<T>, R: Parse<T, Err = L::Err> {
562  type Err = L::Err;
563  type Output = (L::Output, R::Output);
564
565  fn parse(self, input: T) -> Result<(T, Self::Output), Self::Err> {
566    let (left_rest, left_output) = self.left.parse(input.clone())?;
567    let (right_rest, right_output) = self.right.parse(input)?;
568
569    if left_rest == right_rest {
570      Ok((left_rest, (left_output, right_output)))
571    } else {
572      Err(self.length_err)
573    }
574  }
575}
576
577
578/// The parser for [Parse::fuse], see method for documentation.
579#[derive(Debug, PartialEq, Eq, Clone, Hash)]
580#[must_use = "parsers are lazy and do not do anything until consumed"]
581pub struct Fuse<T, L, R>
582where L: Parse<T>, R: Parse<T, Err = L::Err> {
583  left: L,
584  right: R,
585  _t: PhantomData<T>,
586}
587
588impl<T, L, R> Fuse<T, L, R>
589where L: Parse<T>, R: Parse<T, Err = L::Err> {
590  /// Pass through the first parser's output, dropping the output of the second.
591  ///
592  /// Due to the architecture of Parse, it is important to note that both
593  /// parsers are still ran. This is commonly used when the second output of a
594  /// fused parser is not desired, such as when parsing delimiters.
595  ///
596  /// # Examples
597  /// ```
598  /// use pcomb::parse::{Parse, Match};
599  ///
600  /// let parser = Match("hello")
601  ///   .fuse(Match(" "))  // this fuse has Output = ("hello", " ")
602  ///   .first()  // now Output = "hello"
603  ///   .map(|out: &str| Vec::from([out]))  // convert into a Vec and push it
604  ///   .fuse_extend(Match("world"));
605  ///
606  /// // notice how the space get excluded
607  /// assert_eq!(parser.parse("hello world!"), Ok(("!", vec!["hello", "world"])));
608  /// ```
609  pub fn first(self) -> Map<T, Self, impl Clone + Copy + Send + Sync + Fn((L::Output, R::Output)) -> L::Output, L::Output> {
610    self.map(|(out, _)| out)
611  }
612
613  /// Pass through the second parser's output, dropping the output of the first.
614  ///
615  /// Due to the architecture of Parse, it is important to note that both
616  /// parsers are still ran. This is commonly used when the first output of a
617  /// fused parser is not desired, such as when parsing delimiters.
618  ///
619  /// # Examples
620  /// ```
621  /// use pcomb::parse::{Parse, Match};
622  /// use pcomb::parsers::str::{alpha, integer};
623  ///
624  /// let parser = Match("let ")
625  ///   .fuse(alpha)  // this fuse has Output = ("let ", "x")
626  ///   .second()  // now Output = "x"
627  ///   .fuse(Match(" = "))  // Output = ("x", " = ")
628  ///   .first()  // Output = ("x")
629  ///   .fuse(integer::<u32>);  // Output = ("x", 4)
630  ///
631  /// assert_eq!(parser.parse("let x = 4;"), Ok((";", ("x", 4))));
632  /// ```
633  pub fn second(self) -> Map<T, Self, impl Clone + Copy + Send + Sync + Fn((L::Output, R::Output)) -> R::Output, R::Output> {
634    self.map(|(_, out)| out)
635  }
636}
637
638impl<T, L, R> Parse<T> for Fuse<T, L, R>
639where L: Parse<T>, R: Parse<T, Err = L::Err> {
640  type Err = L::Err;
641  type Output = (L::Output, R::Output);
642
643  fn parse(self, input: T) -> Result<(T, Self::Output), Self::Err> {
644    let (rest, left_output) = self.left.parse(input)?;
645    let (rest, right_output) = self.right.parse(rest)?;
646    Ok((rest, (left_output, right_output)))
647  }
648}
649
650
651/// The parser for [Parse::fuse_extend], see method for documentation.
652#[derive(Debug, PartialEq, Eq, Clone, Hash)]
653#[must_use = "parsers are lazy and do not do anything until consumed"]
654pub struct FuseExtend<T, L, LO, R>
655where L: Parse<T, Output = LO>, R: Parse<T, Err = L::Err>, LO: Extend<R::Output> {
656  left: L,
657  right: R,
658  _t: PhantomData<T>,
659}
660
661impl<T, L, LO, R> Parse<T> for FuseExtend<T, L, LO, R>
662where L: Parse<T, Output = LO>, R: Parse<T, Err = L::Err>, LO: Extend<R::Output> {
663  type Err = L::Err;
664  type Output = L::Output;
665
666  fn parse(self, input: T) -> Result<(T, Self::Output), Self::Err> {
667    let (rest, (mut left, right)) = self.left.fuse(self.right).parse(input)?;
668    left.extend(iter::once(right));
669    Ok((rest, left))
670  }
671}
672
673
674/// The parser for [Parse::repeat_const], see method for documentation.
675#[derive(Debug, PartialEq, Eq, Clone, Hash)]
676#[must_use = "parsers are lazy and do not do anything until consumed"]
677pub struct RepeatConst<T, P, const N: usize>
678where P: Parse<T> + Clone {
679  parser: P,
680  _t: PhantomData<T>,
681}
682
683impl<T, P, const N: usize> Parse<T> for RepeatConst<T, P, N>
684where P: Parse<T> + Clone {
685  type Err = P::Err;
686  type Output = [P::Output; N];
687
688  fn parse(self, input: T) -> Result<(T, Self::Output), Self::Err> {
689    let mut output: [MaybeUninit<P::Output>; N] = unsafe {
690      MaybeUninit::uninit().assume_init()
691    };
692
693    let mut rest = input;
694
695    for i in 0..N {
696      match self.parser.clone().parse(rest) {
697        Ok((new_rest, new_output)) => {
698          rest = new_rest;
699          output[i].write(new_output);
700        },
701        Err(error) => {
702          // since MaybeUninit doesn't implement Drop, we should drop individual
703          // elements if we are going to return early to avoid not running Drop
704          for item in &mut output[0..i] {  // i is exclusive
705            // safety: we have written an element to every index before index i.
706            // since item can only be from before index i, we must of written to
707            // it before.
708            unsafe { ptr::drop_in_place(item.as_mut_ptr()); }
709          }
710
711          return Err(error);
712        }
713      }
714    }
715
716    // safety: at this point the entire array can only be full. We have written
717    // an element to every index. Therefore each element is initialized. Also
718    // MaybeUninit<T> is guaranteed to have the same binary representation as T,
719    // so transmuting from MaybeUninit<T> to T is always sound so long as T is
720    // initialized and valid.
721    // note: this requires transmute_copy because https://github.com/rust-lang/rust/issues/61956
722    let output: [P::Output; N] = unsafe { mem::transmute_copy(&output) };
723    Ok((rest, output))
724  }
725}
726
727
728/// The parser for [Parse::repeat_greedy], see method for documentation.
729#[derive(Debug, PartialEq, Eq, Clone, Hash)]
730#[must_use = "parsers are lazy and do not do anything until consumed"]
731pub struct RepeatGreedy<T, P, O>
732where T: Clone, P: Parse<T> + Clone, O: Extend<P::Output> {
733  parser: P,
734  output: O,
735  _t: PhantomData<T>,
736}
737
738impl<T, P, O> Parse<T> for RepeatGreedy<T, P, O>
739where T: Clone, P: Parse<T> + Clone, O: Extend<P::Output> {
740  type Err = P::Err;  // todo: infallible
741  type Output = O;
742
743  fn parse(mut self, input: T) -> Result<(T, Self::Output), Self::Err> {
744    let mut rest = input;
745
746    loop {
747      match self.parser.clone().parse(rest.clone()) {
748        Ok((new_rest, output)) => {
749          rest = new_rest;
750          self.output.extend(iter::once(output));
751        },
752        // todo: consider an adapter which does not drop the error
753        Err(_) => return Ok((rest, self.output)),
754      }
755    }
756  }
757}
758
759
760// todo: RepeatLazy, a repeat with Err?, repeat_at_least, repeat not const
761
762
763// todo: macro docs
764#[macro_export]
765macro_rules! any_of {
766  ($parser1:expr $(, $parser:expr )* $(,)? ) => {
767    {
768      use $crate::parse::Parse;
769
770      $parser1
771        $(
772          .or($parser)
773        )*
774    }
775  };
776}
777
778#[macro_export]
779macro_rules! any_of_match {
780  ( $($parser:expr),* $(,)? ) => {
781    any_of!(
782      $(
783        Match($parser),
784      )*
785    )
786  };
787}
788
789#[macro_export]
790macro_rules! any_of_match_arr {
791  ( $($parser:expr),* $(,)? ) => {
792    any_of!(
793      $(
794        // todo: this is stupid, &[T; N] does not work in certain cases
795        Match(&[$parser][..]),
796      )*
797    )
798  };
799}
800
801
802#[cfg(test)]
803mod test {
804  use super::*;
805
806  #[test]
807  fn slice() {
808    let slice = "asdfghjk";
809    for i in 0..slice.len() + 1 {
810      for j in 0..slice.len() + 1 {
811        assert_eq!(slice.slice(i..j), slice.get(i..j));
812      }
813    }
814  }
815
816  #[test]
817  fn split_at() {
818    let slice = "asdfghjk";
819    assert_eq!(Slice::split_at(&slice, 3), Some(("asd", "fghjk")));
820  }
821
822  #[test]
823  fn match_test() {
824    let val = "asdfg";
825    assert_eq!(val.parse_with(Match("asd")), Ok(("fg", "asd")));
826  }
827
828  #[test]
829  fn any_of() {
830    let parser = any_of!(Match("a"), Match("b"), Match("c").map(|_| "C"));
831    assert_eq!(parser.clone().parse(&"abcde"), Ok(("bcde", "a")));
832    assert_eq!(parser.clone().parse(&"cde"), Ok(("de", "C")));
833    assert_eq!(parser.parse(&"def"), Err(ParseError::Reject));
834  }
835
836  #[test]
837  fn any_of_match() {
838    let parser = any_of_match!("a", "b", "c", "d", "e", "f");
839    assert_eq!(parser.clone().parse("fedcba"), Ok(("edcba", "f")));
840
841    let parser = any_of_match_arr![2i32, 4i32, 6i32, 8i32, 0i32];
842    assert_eq!(parser.parse(&[2i32, 3, 4][..]), Ok((&[3, 4][..], &[2][..])));
843  }
844}