1use crate::{
4 parsers::{empty, map, EmptyParser, MapParser},
5 types::ParserOutput,
6 ParseContext, ParseIter, Parser, Reported, Result,
7};
8
9#[derive(Debug, PartialEq, Eq)]
10pub enum Either<A, B> {
11 Left(A),
12 Right(B),
13}
14
15#[derive(Copy, Clone)]
16pub struct EitherParser<A, B> {
17 left: A,
18 right: B,
19}
20
21pub struct EitherParseIter<'parse, A, B>
22where
23 A: Parser + 'parse,
24 B: Parser + 'parse,
25{
26 start: usize,
27 parsers: &'parse EitherParser<A, B>,
28 iter: Either<A::Iter<'parse>, B::Iter<'parse>>,
29}
30
31impl<A, B> Parser for EitherParser<A, B>
32where
33 A: Parser,
34 B: Parser,
35{
36 type Output = Either<A::Output, B::Output>;
37 type RawOutput = (Either<A::Output, B::Output>,);
38 type Iter<'parse> = EitherParseIter<'parse, A, B>
39 where
40 A: 'parse,
41 B: 'parse;
42
43 fn parse_iter<'parse>(
44 &'parse self,
45 context: &mut ParseContext<'parse>,
46 start: usize,
47 ) -> Result<Self::Iter<'parse>, Reported> {
48 let iter = match self.left.parse_iter(context, start) {
49 Ok(iter) => Either::Left(iter),
50 Err(Reported) => Either::Right(self.right.parse_iter(context, start)?),
51 };
52 Ok(EitherParseIter {
53 start,
54 parsers: self,
55 iter,
56 })
57 }
58}
59
60impl<'parse, A, B> ParseIter<'parse> for EitherParseIter<'parse, A, B>
61where
62 A: Parser,
63 B: Parser,
64{
65 type RawOutput = (Either<A::Output, B::Output>,);
66
67 fn match_end(&self) -> usize {
68 match &self.iter {
69 Either::Left(iter) => iter.match_end(),
70 Either::Right(iter) => iter.match_end(),
71 }
72 }
73
74 fn backtrack(&mut self, context: &mut ParseContext<'parse>) -> Result<(), Reported> {
75 match &mut self.iter {
76 Either::Left(iter) => {
77 if iter.backtrack(context).is_ok() {
78 return Ok(());
79 }
80 self.iter = Either::Right(self.parsers.right.parse_iter(context, self.start)?);
81 Ok(())
82 }
83 Either::Right(iter) => iter.backtrack(context),
84 }
85 }
86
87 fn convert(&self) -> (Either<A::Output, B::Output>,) {
88 (match &self.iter {
89 Either::Left(iter) => Either::Left(iter.convert().into_user_type()),
90 Either::Right(iter) => Either::Right(iter.convert().into_user_type()),
91 },)
92 }
93}
94
95pub fn either<A, B>(left: A, right: B) -> EitherParser<A, B> {
96 EitherParser { left, right }
97}
98
99pub type AltParser<A, B, T> =
100 MapParser<EitherParser<A, B>, fn(Either<<A as Parser>::Output, <B as Parser>::Output>) -> T>;
101
102#[doc(hidden)]
104pub fn alt<A, B, T>(left: A, right: B) -> AltParser<A, B, T>
105where
106 A: Parser<Output = T>,
107 B: Parser<Output = T>,
108{
109 map(either(left, right), |out| match out {
110 Either::Left(value) => value,
111 Either::Right(value) => value,
112 })
113}
114
115pub type OptParser<P> = AltParser<P, EmptyParser, Option<<P as Parser>::Output>>;
116
117#[doc(hidden)]
119pub fn opt<P>(pattern: P) -> OptParser<P>
120where
121 P: Parser,
122{
123 map(either(pattern, empty()), |e| match e {
124 Either::Left(left) => Some(left),
125 Either::Right(()) => None,
126 })
127}