lip/
lib.rs

1//! # Lip Parsing Library
2//!
3//! Lip provides powerful parser combinators for you to
4//! create reusable and flexible parsers.
5
6#[cfg(test)]
7mod tests;
8
9use itertools::Itertools;
10use std::cmp::Ordering;
11use std::collections::HashSet;
12use std::fmt::{Debug, Display};
13use std::marker::PhantomData;
14use unicode_segmentation::UnicodeSegmentation as Uni;
15use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
16
17/// Add location information to any type.
18///
19/// Used by [located](fn.located.html) to add `from` and `to` locations to any captured values
20/// for more precise error messages.
21#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct Located<A> {
23    pub value: A,
24    pub from: Location,
25    pub to: Location,
26}
27
28/// Records the location of a character within the source string.
29///
30/// Uses `row` and `col`. The first character of the source is
31/// at row 1 and column 1. Column width aligns mostly with
32/// displayed width of unicode characters and strings
33/// according to the UAX#11 rules, with exceptions
34/// made for compound emojis like 👩‍🔬. For example, most CJK characters
35/// like 我 and 혇 occupies two column widths. And most emojis occupies
36/// two column widths as well.
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
38pub struct Location {
39    pub row: usize,
40    pub col: usize,
41}
42
43impl Ord for Location {
44    fn cmp(&self, other: &Self) -> Ordering {
45        self.row
46            .cmp(&other.row)
47            .then_with(|| self.col.cmp(&other.col))
48    }
49}
50
51impl PartialOrd for Location {
52    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
53        Some(self.cmp(other))
54    }
55}
56
57/// Records the result of the parser.
58///
59/// Similar to the [`std::result::Result`](https://doc.rust-lang.org/std/result/enum.Result.html) type, outputs `ParseResult::Ok` if parsing succeeds
60/// and `ParseResult::Err` if parsing fails.
61///
62/// `ParseResult::Ok` contains:
63/// * input: the part of source string left after parsing finished
64/// * location: the [Location](struct.Location.html) of the end of parse,
65/// * output: the output of the parsing
66/// * state: the final state of the parser
67/// * committed: If committed is true, then the parser has succeeded and
68/// has committed to this parse. If a parser after this fails,
69/// other parser alternatives will not be attempted
70///
71/// `ParseResult::Err` contains:
72/// * message: the message explaining what and why the parse failed
73/// * from: the starting [Location](struct.Location.html) of the error
74/// * to: the ending [Location](struct.Location.html) of the error
75/// * state: the final state of the parser
76///
77/// A word about `state`:
78/// Sometimes you want to keep track of extra information outside the current location
79/// and the rest of the source string. For example, you may want to put
80/// different symbols encountered into a symbol table as a replacement mapping
81/// after parsing finished or keep track of the current instruction index.
82/// This library uses `state` to capture any kind of extra information like the ones
83/// we mentioned above during parsing. The only requirement on `state` is implementation
84/// of the `Clone` trait. Here's an example `state`:
85/// ```
86/// # use std::collections::HashMap;
87/// #[derive(Clone, Debug)]
88/// pub struct State {
89///   symbol_table: HashMap<String, usize>, // build up a symbol table
90///   instruction_index: usize, // count which instruction we are at
91///   variable_index: usize, // count how many variables we encountered
92/// }
93/// ```
94/// To update `state` during and after parsing, use `update_state`.
95#[derive(Debug, PartialEq, Eq)]
96pub enum ParseResult<'a, Output, State> {
97    Ok {
98        input: &'a str,
99        location: Location,
100        output: Output,
101        state: State,
102        committed: bool,
103    },
104    Err {
105        message: String,
106        from: Location,
107        to: Location,
108        state: State,
109        committed: bool,
110    },
111}
112
113pub struct ParseOk<'a, Output, State> {
114    input: &'a str,
115    output: Output,
116    location: Location,
117    state: State,
118    committed: bool,
119}
120
121pub struct ParseErr<State> {
122    message: String,
123    from: Location,
124    to: Location,
125    state: State,
126    committed: bool,
127}
128
129pub type StdParseResult<'a, A, S> = Result<ParseOk<'a, A, S>, ParseErr<S>>;
130
131impl<'a, A, S> From<ParseResult<'a, A, S>> for StdParseResult<'a, A, S> {
132    fn from(val: ParseResult<'a, A, S>) -> Self {
133        match val {
134            ParseResult::Ok {
135                input,
136                location,
137                output,
138                state,
139                committed,
140            } => Ok(ParseOk {
141                input,
142                location,
143                output,
144                state,
145                committed,
146            }),
147            ParseResult::Err {
148                message,
149                from,
150                to,
151                state,
152                committed,
153            } => Err(ParseErr {
154                message,
155                from,
156                to,
157                state,
158                committed,
159            }),
160        }
161    }
162}
163
164impl<'a, A, S> From<StdParseResult<'a, A, S>> for ParseResult<'a, A, S> {
165    fn from(result: StdParseResult<'a, A, S>) -> ParseResult<'a, A, S> {
166        match result {
167            Ok(ParseOk {
168                input,
169                location,
170                output,
171                state,
172                committed,
173            }) => ParseResult::Ok {
174                input,
175                location,
176                output,
177                state,
178                committed,
179            },
180            Err(ParseErr {
181                message,
182                from,
183                to,
184                state,
185                committed,
186            }) => ParseResult::Err {
187                message,
188                from,
189                to,
190                state,
191                committed,
192            },
193        }
194    }
195}
196
197impl<'a, T, S: Clone + 'a> ParseResult<'a, T, S> {
198    /// Map the parse output to a new value if parse succeeds.
199    /// Otherwise, return error as usual.
200    pub fn map<U, F: FnOnce(T) -> U>(self, func: F) -> ParseResult<'a, U, S> {
201        match self {
202            ParseResult::Ok {
203                input,
204                location,
205                output,
206                state,
207                committed,
208            } => ParseResult::Ok {
209                input,
210                location,
211                output: func(output),
212                state,
213                committed,
214            },
215            ParseResult::Err {
216                message,
217                from,
218                to,
219                state,
220                committed,
221            } => ParseResult::Err {
222                message,
223                from,
224                to,
225                state,
226                committed,
227            },
228        }
229    }
230    /// Map the parse output to a new value if parse succeeds.
231    /// The map function is supplied both the output and the
232    /// state of the parser.
233    /// Otherwise, return error as usual.
234    pub fn map_with_state<U, F: FnOnce(T, S) -> U>(self, func: F) -> ParseResult<'a, U, S> {
235        match self {
236            ParseResult::Ok {
237                input,
238                location,
239                output,
240                state,
241                committed,
242            } => ParseResult::Ok {
243                input,
244                location,
245                output: func(output, state.clone()),
246                state,
247                committed,
248            },
249            ParseResult::Err {
250                message,
251                from,
252                to,
253                state,
254                committed,
255            } => ParseResult::Err {
256                message,
257                from,
258                to,
259                state,
260                committed,
261            },
262        }
263    }
264    /// Map the error message to a new message if parse fails.
265    /// Otherwise, return output as usual.
266    pub fn map_err<F: FnOnce(String) -> String>(self, func: F) -> ParseResult<'a, T, S> {
267        match self {
268            ParseResult::Ok {
269                input,
270                location,
271                output,
272                state,
273                committed,
274            } => ParseResult::Ok {
275                input,
276                location,
277                output,
278                state,
279                committed,
280            },
281            ParseResult::Err {
282                message,
283                from,
284                to,
285                state,
286                committed,
287            } => ParseResult::Err {
288                message: func(message),
289                from,
290                to,
291                state,
292                committed,
293            },
294        }
295    }
296    /// Returns a new parser which is given the current output if parse succeeds.
297    /// Otherwise, return error as usual.
298    pub fn and_then<U, F: FnOnce(&'a str, T, Location, S) -> ParseResult<'a, U, S>>(
299        self,
300        func: F,
301    ) -> ParseResult<'a, U, S> {
302        match self {
303            ParseResult::Ok {
304                input,
305                output,
306                location,
307                state,
308                committed,
309            } => match func(input, output, location, state) {
310                ParseResult::Ok {
311                    input,
312                    output,
313                    location,
314                    state,
315                    committed: cur_committed,
316                } => ParseResult::Ok {
317                    input,
318                    output,
319                    location,
320                    state,
321                    committed: committed || cur_committed,
322                },
323                ParseResult::Err {
324                    message,
325                    from,
326                    to,
327                    state,
328                    committed: cur_committed,
329                } => ParseResult::Err {
330                    message,
331                    from,
332                    to,
333                    state,
334                    committed: committed || cur_committed,
335                },
336            },
337            ParseResult::Err {
338                message,
339                from,
340                to,
341                state,
342                committed,
343            } => ParseResult::Err {
344                message,
345                from,
346                to,
347                state,
348                committed,
349            },
350        }
351    }
352
353    pub fn backtrackable(self) -> ParseResult<'a, T, S> {
354        match self {
355            ParseResult::Ok {
356                input,
357                location,
358                output,
359                state,
360                ..
361            } => ParseResult::Ok {
362                input,
363                location,
364                output,
365                state,
366                committed: false,
367            },
368            ParseResult::Err {
369                message,
370                from,
371                to,
372                state,
373                ..
374            } => ParseResult::Err {
375                message,
376                from,
377                to,
378                state,
379                committed: false,
380            },
381        }
382    }
383
384    fn unwrap(self, source: &'a str) -> T {
385        match self {
386            ParseResult::Ok { output, .. } => output,
387            ParseResult::Err {
388                message, from, to, ..
389            } => {
390                println!("{}", display_error(source, message, from, to));
391                panic!();
392            }
393        }
394    }
395    fn unwrap_err(self) -> String
396    where
397        T: Debug + 'a,
398    {
399        match self {
400            ParseResult::Ok { output, .. } => panic!("{:#?}", output),
401            ParseResult::Err { message, .. } => message,
402        }
403    }
404}
405
406#[derive(Clone)]
407pub struct Map<P, F>(P, F);
408
409impl<'a, A: 'a, B: 'a, P: 'a, F: Clone> Parser<'a> for Map<P, F>
410where
411    P: Parser<'a, Output = A>,
412    F: FnOnce(A) -> B,
413{
414    type Output = B;
415
416    type State = P::State;
417
418    fn parse(
419        &mut self,
420        input: &'a str,
421        location: Location,
422        state: Self::State,
423    ) -> ParseResult<'a, B, Self::State> {
424        self.0.parse(input, location, state).map(self.1.clone())
425    }
426}
427
428#[derive(Clone)]
429pub struct MapWithState<P, F>(P, F);
430
431impl<'a, A, B, P, F: Clone> Parser<'a> for MapWithState<P, F>
432where
433    P: Parser<'a, Output = A>,
434    F: FnOnce(A, P::State) -> B,
435{
436    type Output = B;
437
438    type State = P::State;
439
440    fn parse(
441        &mut self,
442        input: &'a str,
443        location: Location,
444        state: Self::State,
445    ) -> ParseResult<'a, B, Self::State> {
446        match self.0.parse(input, location, state) {
447            ParseResult::Ok {
448                input,
449                output,
450                location,
451                state,
452                committed,
453            } => ParseResult::Ok {
454                input,
455                output: self.1.clone()(output, state.clone()),
456                location,
457                state,
458                committed,
459            },
460            ParseResult::Err {
461                message,
462                from,
463                to,
464                state,
465                committed,
466            } => ParseResult::Err {
467                message,
468                from,
469                to,
470                state,
471                committed,
472            },
473        }
474    }
475}
476
477#[derive(Clone)]
478pub struct MapErr<P, F>(P, F);
479
480impl<'a, P: 'a, F: Clone> Parser<'a> for MapErr<P, F>
481where
482    P: Parser<'a>,
483    F: FnOnce(String) -> String,
484{
485    type Output = P::Output;
486
487    type State = P::State;
488
489    fn parse(
490        &mut self,
491        input: &'a str,
492        location: Location,
493        state: Self::State,
494    ) -> ParseResult<'a, Self::Output, Self::State> {
495        self.0.parse(input, location, state).map_err(self.1.clone())
496    }
497}
498
499#[derive(Clone)]
500pub struct AndThen<P1, F>(P1, F);
501
502impl<'a, P1, P2, F: Clone, S: Clone + 'a> Parser<'a> for AndThen<P1, F>
503where
504    P1: Parser<'a, State = S>,
505    P2: Parser<'a, State = S>,
506    F: FnOnce(P1::Output) -> P2,
507{
508    type Output = P2::Output;
509
510    type State = S;
511
512    fn parse(
513        &mut self,
514        input: &'a str,
515        location: Location,
516        state: Self::State,
517    ) -> ParseResult<'a, Self::Output, Self::State> {
518        self.0.parse(input, location, state).and_then(
519            |cur_input, cur_output, cur_location, cur_state| {
520                self.1.clone()(cur_output).parse(cur_input, cur_location, cur_state)
521            },
522        )
523    }
524}
525
526#[derive(Clone)]
527pub struct Pred<'a, P: 'a, F>(P, F, &'a str);
528
529impl<'a, P: 'a, F: 'a, Output: std::fmt::Display> Parser<'a> for Pred<'a, P, F>
530where
531    P: Parser<'a, Output = Output>,
532    F: Fn(&P::Output) -> bool,
533{
534    type Output = P::Output;
535
536    type State = P::State;
537
538    fn parse(
539        &mut self,
540        input: &'a str,
541        location: Location,
542        state: Self::State,
543    ) -> ParseResult<'a, Self::Output, Self::State> {
544        match self.0.parse(input, location, state) {
545            ParseResult::Ok {
546                input: cur_input,
547                output: content,
548                location: cur_location,
549                state: cur_state,
550                committed: cur_committed,
551            } => {
552                if self.1(&content) {
553                    ParseResult::Ok {
554                        input: cur_input,
555                        output: content,
556                        location: cur_location,
557                        state: cur_state,
558                        committed: true,
559                    }
560                } else {
561                    ParseResult::Err {
562                        message: format!(
563                            "I'm expecting {} but found {}.",
564                            self.2,
565                            display_token(content)
566                        ),
567                        from: location,
568                        to: cur_location,
569                        state: cur_state,
570                        committed: cur_committed,
571                    }
572                }
573            }
574            ParseResult::Err {
575                message,
576                from,
577                to,
578                state,
579                ..
580            } => ParseResult::Err {
581                message,
582                from,
583                to,
584                state,
585                committed: false,
586            },
587        }
588    }
589}
590
591#[derive(Clone)]
592pub struct End<P>(P);
593
594impl<'a, P> Parser<'a> for End<P>
595where
596    P: Parser<'a>,
597{
598    type Output = P::Output;
599
600    type State = P::State;
601
602    fn parse(
603        &mut self,
604        input: &'a str,
605        location: Location,
606        state: Self::State,
607    ) -> ParseResult<'a, Self::Output, Self::State> {
608        match self.0.parse(input, location, state) {
609            ParseResult::Ok {
610                input,
611                location,
612                state,
613                output,
614                ..
615            } => {
616                if !input.is_empty() {
617                    ParseResult::Err {
618                        message: "I'm expecting the end of input.".to_string(),
619                        from: location,
620                        to: location,
621                        state,
622                        committed: false,
623                    }
624                } else {
625                    ParseResult::Ok {
626                        input,
627                        output,
628                        location,
629                        state,
630                        committed: false,
631                    }
632                }
633            }
634            ParseResult::Err {
635                message,
636                from,
637                to,
638                state,
639                committed,
640            } => ParseResult::Err {
641                message,
642                from,
643                to,
644                state,
645                committed,
646            },
647        }
648    }
649}
650
651#[derive(Clone)]
652pub struct UpdateState<P, F>(P, F);
653
654impl<'a, P: 'a, F> Parser<'a> for UpdateState<P, F>
655where
656    P: Parser<'a>,
657    F: Fn(&P::Output, P::State) -> P::State,
658{
659    type Output = P::Output;
660
661    type State = P::State;
662
663    fn parse(
664        &mut self,
665        input: &'a str,
666        location: Location,
667        state: Self::State,
668    ) -> ParseResult<'a, Self::Output, Self::State> {
669        match self.0.parse(input, location, state) {
670            ParseResult::Ok {
671                input: cur_input,
672                location: cur_location,
673                state: cur_state,
674                output,
675                committed,
676            } => {
677                let new_state = self.1(&output, cur_state);
678                ParseResult::Ok {
679                    input: cur_input,
680                    output,
681                    location: cur_location,
682                    state: new_state,
683                    committed,
684                }
685            }
686            err @ ParseResult::Err { .. } => err,
687        }
688    }
689}
690
691#[derive(Clone)]
692pub struct Update<P, F>(P, F);
693
694impl<'a, P: 'a, A, B, F: Clone> Parser<'a> for Update<P, F>
695where
696    P: Parser<'a, Output = A>,
697    F: FnOnce(&'a str, A, Location, P::State) -> ParseResult<'a, B, P::State>,
698{
699    type Output = B;
700
701    type State = P::State;
702
703    fn parse(
704        &mut self,
705        input: &'a str,
706        location: Location,
707        state: Self::State,
708    ) -> ParseResult<'a, Self::Output, Self::State> {
709        match self.0.parse(input, location, state) {
710            ParseResult::Ok {
711                input: cur_input,
712                location: cur_location,
713                state: cur_state,
714                output,
715                ..
716            } => self.1.clone()(cur_input, output, cur_location, cur_state),
717            ParseResult::Err {
718                message,
719                from,
720                to,
721                state,
722                committed,
723            } => ParseResult::Err {
724                message,
725                from,
726                to,
727                state,
728                committed,
729            },
730        }
731    }
732}
733
734pub struct Ignore<P>(P);
735
736impl<'a, P> Parser<'a> for Ignore<P>
737where
738    P: Parser<'a>,
739{
740    type Output = ();
741
742    type State = P::State;
743
744    fn parse(
745        &mut self,
746        input: &'a str,
747        location: Location,
748        state: Self::State,
749    ) -> ParseResult<'a, Self::Output, Self::State> {
750        match self.0.parse(input, location, state) {
751            ParseResult::Ok {
752                input,
753                location,
754                state,
755                committed,
756                ..
757            } => ParseResult::Ok {
758                input,
759                location,
760                output: (),
761                state,
762                committed,
763            },
764            ParseResult::Err {
765                message,
766                from,
767                to,
768                state,
769                committed,
770            } => ParseResult::Err {
771                message,
772                from,
773                to,
774                state,
775                committed,
776            },
777        }
778    }
779}
780
781pub struct Keep<P1, P2>(P1, P2);
782
783impl<'a, P1, P2, A, B, F, S: Clone + 'a> Parser<'a> for Keep<P1, P2>
784where
785    F: FnOnce(A) -> B,
786    P1: Parser<'a, Output = F, State = S>,
787    P2: Parser<'a, Output = A, State = S>,
788{
789    type Output = B;
790
791    type State = P1::State;
792
793    fn parse(
794        &mut self,
795        input: &'a str,
796        location: Location,
797        state: Self::State,
798    ) -> ParseResult<'a, Self::Output, Self::State> {
799        self.0
800            .parse(input, location, state)
801            .and_then(|cur_input, func, cur_location, cur_state| {
802                self.1.parse(cur_input, cur_location, cur_state).map(func)
803            })
804    }
805}
806
807pub struct Skip<P1, P2>(P1, P2);
808
809impl<'a, P1, P2, S: Clone + 'a> Parser<'a> for Skip<P1, P2>
810where
811    P1: Parser<'a, State = S>,
812    P2: Parser<'a, State = S>,
813{
814    type Output = P1::Output;
815
816    type State = P1::State;
817
818    fn parse(
819        &mut self,
820        input: &'a str,
821        location: Location,
822        state: Self::State,
823    ) -> ParseResult<'a, Self::Output, Self::State> {
824        self.0.parse(input, location, state).and_then(
825            |cur_input, left_output, cur_location, cur_state| {
826                self.1
827                    .parse(cur_input, cur_location, cur_state)
828                    .map(|_| left_output)
829            },
830        )
831    }
832}
833
834#[derive(Clone)]
835pub struct Backtrackable<P>(P);
836
837impl<'a, P: 'a> Parser<'a> for Backtrackable<P>
838where
839    P: Parser<'a>,
840{
841    type Output = P::Output;
842
843    type State = P::State;
844
845    fn parse(
846        &mut self,
847        input: &'a str,
848        location: Location,
849        state: Self::State,
850    ) -> ParseResult<'a, Self::Output, Self::State> {
851        self.0.parse(input, location, state).backtrackable()
852    }
853}
854
855pub trait Parser<'a> {
856    type Output;
857
858    type State: Clone;
859
860    /// Parse a given input, starting at
861    /// a given location and state.
862    fn parse(
863        &mut self,
864        input: &'a str,
865        location: Location,
866        state: Self::State,
867    ) -> ParseResult<'a, Self::Output, Self::State>;
868    /// Run the parser on a given input, starting at
869    /// the first character.
870    ///
871    /// Example:
872    ///
873    /// Parse a (x, y) position pair.
874    /// ```
875    /// # use lip::*;
876    /// // Parse an (x, y) position pair
877    /// let position = succeed!(|x, y| (x, y))
878    ///   .keep(int())
879    ///   .skip(token(","))
880    ///   .keep(int())
881    ///   .run("2, 3", ()); // position == (2, 3)
882    /// ```
883    fn run(
884        &mut self,
885        input: &'a str,
886        state: Self::State,
887    ) -> ParseResult<'a, Self::Output, Self::State> {
888        self.parse(input, Location { row: 1, col: 1 }, state)
889    }
890    /// Map the output to a new output if parse succeeds.
891    /// Otherwise, return error as usual.
892    ///
893    /// The only difference from the `map` on `ParseResult`
894    /// is that this `map` turns one `Parser` into another while the `map`
895    /// on `ParseResult` turns one `ParseResult` into another.
896    fn map<F: 'a, NewOutput: 'a>(self, map_fn: F) -> Map<Self, F>
897    where
898        Self: Sized + 'a,
899        F: Fn(Self::Output) -> NewOutput,
900    {
901        map(self, map_fn)
902    }
903    /// The map function is supplied both the output and the
904    /// state of the parser.
905    /// Otherwise, return error as usual.
906    ///
907    /// The only difference from the `map_with_state` on `ParseResult`
908    /// is that this `map_with_state` turns one `Parser` into another while the `map_with_state`
909    /// on `ParseResult` turns one `ParseResult` into another.
910    fn map_with_state<F: 'a, NewOutput: 'a>(self, map_fn: F) -> MapWithState<Self, F>
911    where
912        Self: Sized + 'a,
913        F: Fn(Self::Output, Self::State) -> NewOutput,
914    {
915        map_with_state(self, map_fn)
916    }
917    /// Map the error message to a new message if parse fails.
918    /// Otherwise, return output as usual.
919    ///
920    /// The only difference from the `map_err` on `ParseResult`
921    /// is that this `map_err` turns one `Parser` into another while the `map_err`
922    /// on `ParseResult` turns one `ParseResult` into another.
923    fn map_err<F>(self, map_fn: F) -> MapErr<Self, F>
924    where
925        Self: Sized + 'a,
926        F: Fn(String) -> String,
927    {
928        map_err(self, map_fn)
929    }
930    /// Returns a new parser which is given the current output if parse succeeds.
931    /// Otherwise, return error as usual.
932    ///
933    /// The only difference from the `and_then` on `ParseResult`
934    /// is that this `and_then` turns one `Parser` into another while the `and_then`
935    /// on `ParseResult` turns one `ParseResult` into another.
936    fn and_then<F, P2, B>(self, f: F) -> AndThen<Self, F>
937    where
938        Self: Sized + 'a,
939        P2: Parser<'a, Output = B>,
940        F: Fn(Self::Output) -> P2,
941    {
942        and_then(self, f)
943    }
944    /// Judge if the output meets the requirement using a predicate function
945    /// if the parse succeeds. Otherwise, return error as usual.
946    fn pred<F>(self, predicate: F, expecting: &'a str) -> Pred<Self, F>
947    where
948        Self: Sized + 'a,
949        F: Fn(&Self::Output) -> bool,
950    {
951        pred(self, predicate, expecting)
952    }
953    /// Ignore the parse output and return `()` (emtpy tuple)
954    fn ignore(self) -> Ignore<Self>
955    where
956        Self: Sized + 'a,
957    {
958        Ignore(self)
959    }
960    /// Update the state given the new output and state of the parse if parse succeeds.
961    /// Otherwise, return error as usual.
962    fn update_state<F>(self, f: F) -> UpdateState<Self, F>
963    where
964        Self: Sized + 'a,
965        F: Fn(Self::Output, Self::State) -> Self::State,
966    {
967        update_state(self, f)
968    }
969    /// Update the result of the parser if parse succeeds.
970    /// Otherwise, return error as usual.
971    ///
972    /// This is the most general and powerful method of the parser.
973    /// Think about using simpler methods like `map` and `map_err` before
974    /// choosing `update`.
975    fn update<B, F: Clone>(self, f: F) -> Update<Self, F>
976    where
977        Self: Sized + 'a,
978        F: FnOnce(&'a str, Self::Output, Location, Self::State) -> ParseResult<'a, B, Self::State>,
979    {
980        update(self, f)
981    }
982    /// Check if you have reached the end of the input you are parsing.
983    ///
984    /// If you want to parse an input containing only "abc":
985    /// ```
986    /// # use lip::*;
987    /// assert_succeed(
988    ///  token("abc").end(),
989    ///  "abc", "abc",
990    /// );
991    /// assert_fail(
992    ///   token("abc").end(),
993    ///   "abcd", "I'm expecting the end of input.",
994    /// );
995    /// ```
996    fn end(self) -> End<Self>
997    where
998        Self: Sized + 'a,
999    {
1000        end(self)
1001    }
1002    /// Keep values in a parser pipeline.
1003    ///
1004    /// Exammple:
1005    ///
1006    /// Parse a (x, y) position pair.
1007    /// ```
1008    /// # use lip::*;
1009    /// // Parse an (x, y) position pair
1010    /// let position = succeed!(|x, y| (x, y))
1011    ///   .keep(int())
1012    ///   .skip(token(","))
1013    ///   .keep(int())
1014    ///   .run("2, 3", ()); // position == (2, 3)
1015    /// ```
1016    fn keep<A, B, P2>(self, arg_parser: P2) -> Keep<Self, P2>
1017    where
1018        Self: Sized + 'a,
1019        Self::Output: FnOnce(A) -> B + Clone,
1020        P2: Parser<'a, Output = A>,
1021    {
1022        keep(self, arg_parser)
1023    }
1024    /// Skip values in a parser pipeline.
1025    ///
1026    /// Exammple:
1027    ///
1028    /// Parse a (x, y) position pair.
1029    /// ```
1030    /// # use lip::*;
1031    /// // Parse an (x, y) position pair
1032    /// let position = succeed!(|x, y| (x, y))
1033    ///   .keep(int())
1034    ///   .skip(token(","))
1035    ///   .keep(int())
1036    ///   .run("2, 3", ()); // position == (2, 3)
1037    /// ```
1038    fn skip<P2>(self, ignored_parser: P2) -> Skip<Self, P2>
1039    where
1040        Self: Sized + 'a,
1041        P2: Parser<'a>,
1042    {
1043        Skip(self, ignored_parser)
1044    }
1045
1046    fn backtrackable(self) -> Backtrackable<Self>
1047    where
1048        Self: Sized + 'a,
1049    {
1050        backtrackable(self)
1051    }
1052
1053    fn first_of_two<T2>(self) -> OneOfTwo<Self, T2>
1054    where
1055        Self: Sized + 'a,
1056        T2: Parser<'a, Output = Self::Output, State = Self::State>,
1057    {
1058        OneOfTwo::First(self)
1059    }
1060
1061    fn second_of_two<T1>(self) -> OneOfTwo<T1, Self>
1062    where
1063        Self: Sized + 'a,
1064        T1: Parser<'a, Output = Self::Output, State = Self::State>,
1065    {
1066        OneOfTwo::Second(self)
1067    }
1068
1069    fn first_of_three<T2, T3>(self) -> OneOfThree<Self, T2, T3>
1070    where
1071        Self: Sized + 'a,
1072        T2: Parser<'a, Output = Self::Output, State = Self::State>,
1073        T3: Parser<'a, Output = Self::Output, State = Self::State>,
1074    {
1075        OneOfThree::First(self)
1076    }
1077
1078    fn second_of_three<T1, T3>(self) -> OneOfThree<T1, Self, T3>
1079    where
1080        Self: Sized + 'a,
1081        T1: Parser<'a, Output = Self::Output, State = Self::State>,
1082        T3: Parser<'a, Output = Self::Output, State = Self::State>,
1083    {
1084        OneOfThree::Second(self)
1085    }
1086
1087    fn third_of_three<T1, T2>(self) -> OneOfThree<T1, T2, Self>
1088    where
1089        Self: Sized + 'a,
1090        T1: Parser<'a, Output = Self::Output, State = Self::State>,
1091        T2: Parser<'a, Output = Self::Output, State = Self::State>,
1092    {
1093        OneOfThree::Third(self)
1094    }
1095}
1096
1097fn and_then<'a, P1, P2, F>(parser: P1, f: F) -> AndThen<P1, F>
1098where
1099    P1: Parser<'a>,
1100    P2: Parser<'a>,
1101    F: Fn(P1::Output) -> P2,
1102{
1103    AndThen(parser, f)
1104}
1105
1106/// Parse a given token string.
1107///
1108/// ⚠️ Newlines are not allowed in tokens.
1109pub fn token<'a, S: Clone + 'a>(expected: &'a str) -> impl Parser<Output = &'a str, State = S> {
1110    fn_parser(move |input: &'a str, location: Location, state: S| {
1111        let peek = input.get(0..expected.len());
1112        if peek == Some(expected) {
1113            ParseResult::Ok {
1114                input: &input[expected.len()..],
1115                output: expected,
1116                location: increment_col(unicode_column_width(expected), location),
1117                state,
1118                committed: true,
1119            }
1120        } else {
1121            let expected_len = expected.graphemes(true).count();
1122            let peek_str = &input.graphemes(true).take(expected_len).join("");
1123            ParseResult::Err {
1124                message: format!(
1125                    "I'm expecting a `{}` but found {}.",
1126                    expected,
1127                    display_token(peek_str)
1128                ),
1129                from: location,
1130                to: Location {
1131                    col: location.col + unicode_column_width(peek_str),
1132                    ..location
1133                },
1134                state,
1135                committed: false,
1136            }
1137        }
1138    })
1139}
1140
1141fn increment_col(additional_col: usize, location: Location) -> Location {
1142    Location {
1143        col: location.col + additional_col,
1144        ..location
1145    }
1146}
1147
1148fn increment_row(additional_row: usize, location: Location) -> Location {
1149    Location {
1150        row: location.row + additional_row,
1151        col: 1,
1152    }
1153}
1154
1155fn display_token<T: Display>(token: T) -> String {
1156    let token_str = &token.to_string();
1157    if unicode_column_width(token_str) == 0 {
1158        "nothing".to_string()
1159    } else {
1160        format!("`{}`", token_str.replace('\n', "\\n"))
1161    }
1162}
1163
1164/// Pair up two parsers. Run the left parser, then the right,
1165/// and last combine both outputs into a tuple.
1166fn pair<'a, P1: 'a, P2: 'a, R1: Clone + 'a, R2: Clone + 'a, S: Clone + 'a>(
1167    mut parser1: P1,
1168    mut parser2: P2,
1169) -> impl Parser<'a, Output = (R1, R2), State = S>
1170where
1171    P1: Parser<'a, Output = R1, State = S>,
1172    P2: Parser<'a, Output = R2, State = S>,
1173{
1174    fn_parser(move |input, location, state| {
1175        parser1.parse(input, location, state).and_then(
1176            |cur_input, first_output, cur_location, cur_state| {
1177                parser2
1178                    .parse(cur_input, cur_location, cur_state)
1179                    .map(|second_output| (first_output.clone(), second_output))
1180            },
1181        )
1182    })
1183}
1184
1185fn map<'a, P: 'a, F: 'a, B>(parser: P, map_fn: F) -> Map<P, F>
1186where
1187    P: Parser<'a>,
1188    F: Fn(P::Output) -> B,
1189{
1190    Map(parser, map_fn)
1191}
1192
1193fn map_with_state<'a, P: 'a, F: 'a, A, B>(parser: P, map_fn: F) -> MapWithState<P, F>
1194where
1195    P: Parser<'a, Output = A>,
1196    F: Fn(P::Output, P::State) -> B,
1197{
1198    MapWithState(parser, map_fn)
1199}
1200
1201fn map_err<'a, P: 'a, F>(parser: P, map_fn: F) -> MapErr<P, F>
1202where
1203    P: Parser<'a>,
1204    F: Fn(String) -> String,
1205{
1206    MapErr(parser, map_fn)
1207}
1208
1209fn backtrackable<'a, P>(parser: P) -> Backtrackable<P>
1210where
1211    P: Parser<'a>,
1212{
1213    Backtrackable(parser)
1214}
1215
1216/// Run the left parser, then the right, last keep the left result and discard the right.
1217fn left<'a, P1: 'a, P2: 'a, R1: Clone + 'a, R2: Clone + 'a, S: Clone + 'a>(
1218    parser1: P1,
1219    parser2: P2,
1220) -> impl Parser<'a, Output = R1, State = S>
1221where
1222    P1: Parser<'a, Output = R1, State = S>,
1223    P2: Parser<'a, Output = R2, State = S>,
1224{
1225    map(pair(parser1, parser2), |(left, _right)| left)
1226}
1227
1228fn keep<'a, P1, P2, F, A, B>(parser1: P1, parser2: P2) -> Keep<P1, P2>
1229where
1230    F: FnOnce(A) -> B,
1231    P1: Parser<'a, Output = F>,
1232    P2: Parser<'a, Output = A>,
1233{
1234    Keep(parser1, parser2)
1235}
1236
1237pub type BoxedParser<'a, A, S> = Box<dyn FnMut(&'a str, Location, S) -> ParseResult<'a, A, S> + 'a>;
1238
1239impl<'a, A, S: Clone + 'a> Parser<'a> for BoxedParser<'a, A, S> {
1240    type Output = A;
1241    type State = S;
1242
1243    fn parse(&mut self, input: &'a str, location: Location, state: S) -> ParseResult<'a, A, S> {
1244        (*self)(input, location, state)
1245    }
1246}
1247
1248#[derive(Copy, Clone)]
1249pub struct FnParser<F, A, S>(F, PhantomData<A>, PhantomData<S>);
1250
1251pub fn fn_parser<'a, A, S: Clone, F>(f: F) -> FnParser<F, A, S>
1252where
1253    F: FnMut(&'a str, Location, S) -> ParseResult<'a, A, S>,
1254{
1255    FnParser(f, PhantomData, PhantomData)
1256}
1257
1258impl<'a, A, S: Clone, F> Parser<'a> for FnParser<F, A, S>
1259where
1260    F: FnMut(&'a str, Location, S) -> ParseResult<'a, A, S>,
1261{
1262    type Output = A;
1263    type State = S;
1264
1265    fn parse(&mut self, input: &'a str, location: Location, state: S) -> ParseResult<'a, A, S> {
1266        (self.0)(input, location, state)
1267    }
1268}
1269
1270#[doc(hidden)]
1271pub fn succeed_helper<'a, A: Clone + 'a, S: Clone + 'a>(
1272    output: A,
1273) -> impl Parser<'a, Output = A, State = S> {
1274    fn_parser(move |input, location, state: S| ParseResult::Ok {
1275        input,
1276        location,
1277        state,
1278        output: output.clone(),
1279        committed: false,
1280    })
1281}
1282
1283/// A parser that succeeds without chomping any characters.
1284///
1285/// Seems weird on its own, but it is very useful in combination with other functions.
1286/// The docs for [keep](trait.Parser.html#method.keep) and [and_then](trait.Parser.html#method.and_then) have some neat examples.
1287#[macro_export]
1288macro_rules! succeed {
1289  (|$first_arg:ident $(, $arg:ident )*| $function_body:expr) => {
1290    succeed_helper(move |$first_arg| $(move |$arg|)* {
1291      $function_body
1292    })
1293  };
1294  (|$first_arg:ident:$first_arg_type:ty $(, $arg:ident:$arg_type:ty )*| $function_body:expr) => {
1295    succeed_helper(move |$first_arg:$first_arg_type| $(move |$arg:$arg_type|)* {
1296      $function_body
1297    })
1298  };
1299  ($value:expr) => {
1300    succeed_helper($value)
1301  };
1302  () => {
1303    succeed_helper(())
1304  }
1305}
1306
1307fn end<'a, P>(parser: P) -> End<P>
1308where
1309    P: Parser<'a>,
1310{
1311    End(parser)
1312}
1313
1314/// Indicate that a parser has reached a dead end.
1315///
1316/// "Everything was going fine until I ran into this problem."
1317pub fn problem<'a, F1: 'a, F2: 'a, A: 'a, S: Clone + 'a>(
1318    message: String,
1319    from: F1,
1320    to: F2,
1321) -> impl Parser<'a, Output = A, State = S>
1322where
1323    F1: Fn(Location) -> Location,
1324    F2: Fn(Location) -> Location,
1325{
1326    fn_parser(move |_input, location, state: S| ParseResult::Err {
1327        message: message.clone(),
1328        from: from(location),
1329        to: to(location),
1330        state,
1331        committed: false,
1332    })
1333}
1334
1335/// Run the left parser, then the right, last keep the right result and discard the left.
1336fn right<'a, P1: 'a, P2: 'a, R1: Clone + 'a, R2: Clone + 'a, S: Clone + 'a>(
1337    parser1: P1,
1338    parser2: P2,
1339) -> impl Parser<'a, Output = R2, State = S>
1340where
1341    P1: Parser<'a, Output = R1, State = S>,
1342    P2: Parser<'a, Output = R2, State = S>,
1343{
1344    map(pair(parser1, parser2), |(_left, right)| right)
1345}
1346
1347/// Run the parser one or more times and combine each output into a vector of outputs.
1348pub fn one_or_more<'a, P: 'a, A: Clone + 'a, S: Clone + 'a>(
1349    mut parser: P,
1350) -> BoxedParser<'a, Vec<A>, S>
1351where
1352    P: Parser<'a, Output = A, State = S>,
1353{
1354    Box::new(move |mut input, mut location, mut state| {
1355        let mut output = Vec::new();
1356        let mut committed = false;
1357
1358        match parser.parse(input, location, state) {
1359            ParseResult::Ok {
1360                input: cur_input,
1361                output: first_item,
1362                location: cur_location,
1363                state: cur_state,
1364                committed: cur_committed,
1365            } => {
1366                input = cur_input;
1367                location = cur_location;
1368                state = cur_state;
1369                committed |= cur_committed;
1370                output.push(first_item);
1371            }
1372            ParseResult::Err {
1373                message,
1374                from,
1375                to,
1376                state,
1377                committed,
1378            } => {
1379                return ParseResult::Err {
1380                    message,
1381                    from,
1382                    to,
1383                    state,
1384                    committed,
1385                };
1386            }
1387        }
1388
1389        loop {
1390            match parser.parse(input, location, state.clone()) {
1391                ParseResult::Ok {
1392                    input: cur_input,
1393                    output: cur_item,
1394                    location: cur_location,
1395                    state: cur_state,
1396                    committed: cur_committed,
1397                    ..
1398                } => {
1399                    input = cur_input;
1400                    location = cur_location;
1401                    state = cur_state;
1402                    committed |= cur_committed;
1403                    output.push(cur_item);
1404                }
1405                ParseResult::Err {
1406                    message,
1407                    from,
1408                    to,
1409                    state,
1410                    committed,
1411                } => {
1412                    if committed {
1413                        return ParseResult::Err {
1414                            message,
1415                            from,
1416                            to,
1417                            state,
1418                            committed,
1419                        };
1420                    } else {
1421                        break;
1422                    }
1423                }
1424            }
1425        }
1426
1427        ParseResult::Ok {
1428            input,
1429            output,
1430            location,
1431            state,
1432            committed,
1433        }
1434    })
1435}
1436
1437/// Run the parser zero or more times until an end delimiter (or end of input) and combine each output into a vector of outputs.
1438pub fn zero_or_more_until<'a, P: 'a, A: Clone + 'a, E: 'a, B: 'a, S: Clone + 'a>(
1439    item_name: &'static str,
1440    mut parser: P,
1441    end_name: &'static str,
1442    mut end_parser: E,
1443) -> BoxedParser<'a, Vec<A>, S>
1444where
1445    P: Parser<'a, Output = A, State = S>,
1446    E: Parser<'a, Output = B, State = ()>,
1447{
1448    Box::new(move |mut input, mut location, mut state| {
1449        let mut output = Vec::new();
1450        let mut committed = false;
1451
1452        // end_parser must run first
1453        // because the language of parser may be a superset of end_parser
1454        match end_parser.parse(input, location, ()) {
1455            ParseResult::Ok {
1456                committed: cur_committed,
1457                ..
1458            } => {
1459                committed |= cur_committed;
1460                return ParseResult::Ok {
1461                    input,
1462                    output,
1463                    location,
1464                    state,
1465                    committed,
1466                };
1467            }
1468            ParseResult::Err {
1469                message,
1470                from,
1471                to,
1472                committed,
1473                ..
1474            } => {
1475                if committed {
1476                    return ParseResult::Err {
1477                        message,
1478                        from,
1479                        to,
1480                        state,
1481                        committed,
1482                    };
1483                }
1484            } // no big deal, continue parsing
1485        }
1486
1487        match parser.parse(input, location, state) {
1488            ParseResult::Ok {
1489                input: cur_input,
1490                output: first_item,
1491                location: cur_location,
1492                state: cur_state,
1493                committed: cur_committed,
1494            } => {
1495                input = cur_input;
1496                location = cur_location;
1497                state = cur_state;
1498                committed |= cur_committed;
1499                output.push(first_item);
1500            }
1501            ParseResult::Err {
1502                message,
1503                from,
1504                to,
1505                state,
1506                committed: cur_committed,
1507            } => {
1508                committed |= cur_committed;
1509                // end_parser must have failed as well
1510                // because we only run parser if end_parser fails at first
1511                if input.is_empty() {
1512                    // reached the end of input
1513                    return ParseResult::Ok {
1514                        input,
1515                        output,
1516                        location,
1517                        state,
1518                        committed,
1519                    };
1520                } else {
1521                    return ParseResult::Err {
1522                        message,
1523                        from,
1524                        to,
1525                        state,
1526                        committed,
1527                    };
1528                }
1529            }
1530        }
1531
1532        loop {
1533            match end_parser.parse(input, location, ()) {
1534                ParseResult::Ok {
1535                    committed: cur_committed,
1536                    ..
1537                } => {
1538                    committed |= cur_committed;
1539                    return ParseResult::Ok {
1540                        input,
1541                        output,
1542                        location,
1543                        state,
1544                        committed,
1545                    };
1546                }
1547                ParseResult::Err {
1548                    message,
1549                    from,
1550                    to,
1551                    committed: err_committed,
1552                    ..
1553                } => {
1554                    if err_committed {
1555                        return ParseResult::Err {
1556                            message,
1557                            from,
1558                            to,
1559                            state,
1560                            committed: err_committed,
1561                        };
1562                    }
1563                    match parser.parse(input, location, state.clone()) {
1564                        ParseResult::Ok {
1565                            input: cur_input,
1566                            output: cur_item,
1567                            location: cur_location,
1568                            state: cur_state,
1569                            committed: cur_committed,
1570                        } => {
1571                            input = cur_input;
1572                            location = cur_location;
1573                            state = cur_state;
1574                            committed |= cur_committed;
1575                            output.push(cur_item);
1576                        }
1577                        ParseResult::Err {
1578                            from: end_from,
1579                            to: end_to,
1580                            committed: cur_committed,
1581                            ..
1582                        } => {
1583                            committed |= cur_committed;
1584                            if input.is_empty() {
1585                                // reached the end of input
1586                                return ParseResult::Ok {
1587                                    input,
1588                                    output,
1589                                    location,
1590                                    state,
1591                                    committed,
1592                                };
1593                            } else {
1594                                return ParseResult::Err {
1595                                    message: format!("I'm expecting either {} or {}. However, neither was found.", item_name, end_name),
1596                                    from: end_from,
1597                                    to: end_to,
1598                                    state,
1599                                    committed,
1600                                };
1601                            }
1602                        }
1603                    }
1604                }
1605            }
1606        }
1607    })
1608}
1609
1610/// Run the parser one or more times until an end delimiter (or end of input) and combine each output into a vector of outputs.
1611pub fn one_or_more_until<'a, P: 'a, A: Clone + 'a, E: 'a, B: 'a, S: Clone + 'a>(
1612    item_name: &'static str,
1613    mut parser: P,
1614    end_name: &'static str,
1615    mut end_parser: E,
1616) -> BoxedParser<'a, Vec<A>, S>
1617where
1618    P: Parser<'a, Output = A, State = S>,
1619    E: Parser<'a, Output = B, State = ()>,
1620{
1621    Box::new(move |mut input, mut location, mut state| {
1622        let mut output = Vec::new();
1623        let mut committed = false;
1624
1625        match end_parser.parse(input, location, ()) {
1626            ParseResult::Ok {
1627                location: end_location,
1628                committed: cur_committed,
1629                ..
1630            } => {
1631                committed |= cur_committed;
1632                return ParseResult::Err {
1633                    message: format!(
1634                        "I'm expecting at least one occurrence of {} but reached {}.",
1635                        item_name, end_name
1636                    ),
1637                    from: location,
1638                    to: end_location,
1639                    state,
1640                    committed,
1641                };
1642            }
1643            ParseResult::Err {
1644                message,
1645                from,
1646                to,
1647                committed: err_committed,
1648                ..
1649            } => {
1650                if err_committed {
1651                    return ParseResult::Err {
1652                        message,
1653                        from,
1654                        to,
1655                        state,
1656                        committed: err_committed,
1657                    };
1658                }
1659                match parser.parse(input, location, state) {
1660                    ParseResult::Ok {
1661                        input: cur_input,
1662                        output: first_item,
1663                        location: cur_location,
1664                        state: cur_state,
1665                        committed: cur_committed,
1666                    } => {
1667                        input = cur_input;
1668                        location = cur_location;
1669                        state = cur_state;
1670                        committed |= cur_committed;
1671                        output.push(first_item);
1672                    }
1673                    ParseResult::Err {
1674                        message,
1675                        from,
1676                        to,
1677                        state,
1678                        committed: cur_committed,
1679                    } => {
1680                        committed |= cur_committed;
1681                        return ParseResult::Err {
1682                            message,
1683                            from,
1684                            to,
1685                            state,
1686                            committed,
1687                        };
1688                    }
1689                }
1690            }
1691        }
1692
1693        loop {
1694            match end_parser.parse(input, location, ()) {
1695                ParseResult::Ok { .. } => {
1696                    return ParseResult::Ok {
1697                        input,
1698                        output,
1699                        location,
1700                        state,
1701                        committed,
1702                    };
1703                }
1704                ParseResult::Err {
1705                    message,
1706                    from,
1707                    to,
1708                    committed: err_committed,
1709                    ..
1710                } => {
1711                    if err_committed {
1712                        return ParseResult::Err {
1713                            message,
1714                            from,
1715                            to,
1716                            state,
1717                            committed: err_committed,
1718                        };
1719                    }
1720                    match parser.parse(input, location, state.clone()) {
1721                        ParseResult::Ok {
1722                            input: cur_input,
1723                            output: cur_item,
1724                            location: cur_location,
1725                            state: cur_state,
1726                            committed: cur_committed,
1727                        } => {
1728                            input = cur_input;
1729                            location = cur_location;
1730                            state = cur_state;
1731                            committed |= cur_committed;
1732                            output.push(cur_item);
1733                        }
1734                        ParseResult::Err {
1735                            from: end_from,
1736                            to: end_to,
1737                            committed: cur_committed,
1738                            ..
1739                        } => {
1740                            committed |= cur_committed;
1741                            if input.is_empty() {
1742                                // reached the end of input
1743                                return ParseResult::Ok {
1744                                    input,
1745                                    output,
1746                                    location,
1747                                    state,
1748                                    committed,
1749                                };
1750                            } else {
1751                                return ParseResult::Err {
1752                                message: format!("I'm expecting either {} or {}. However, neither was found.", item_name, end_name),
1753                                from: end_from,
1754                                to: end_to,
1755                                state,
1756                                committed,
1757                            };
1758                            }
1759                        }
1760                    }
1761                }
1762            }
1763        }
1764    })
1765}
1766
1767/// Run the parser zero or more times and combine each output into a vector of outputs.
1768pub fn zero_or_more<'a, P: 'a, A: Clone + 'a, S: Clone + 'a>(
1769    mut parser: P,
1770) -> BoxedParser<'a, Vec<A>, S>
1771where
1772    P: Parser<'a, Output = A, State = S>,
1773{
1774    Box::new(move |mut input, mut location, mut state: S| {
1775        let mut output = Vec::new();
1776        let mut committed = false;
1777
1778        loop {
1779            match parser.parse(input, location, state.clone()) {
1780                ParseResult::Ok {
1781                    input: cur_input,
1782                    output: cur_item,
1783                    location: cur_location,
1784                    state: cur_state,
1785                    committed: cur_committed,
1786                } => {
1787                    input = cur_input;
1788                    location = cur_location;
1789                    state = cur_state;
1790                    committed |= cur_committed;
1791                    output.push(cur_item);
1792                }
1793                ParseResult::Err {
1794                    message,
1795                    from,
1796                    to,
1797                    state,
1798                    committed,
1799                } => {
1800                    if committed {
1801                        return ParseResult::Err {
1802                            message,
1803                            from,
1804                            to,
1805                            state,
1806                            committed,
1807                        };
1808                    } else {
1809                        break;
1810                    }
1811                }
1812            }
1813        }
1814
1815        ParseResult::Ok {
1816            input,
1817            output,
1818            location,
1819            state,
1820            committed,
1821        }
1822    })
1823}
1824
1825/// Match any single unicode grapheme, internally used together with `pred`.
1826fn any_grapheme<'a, S: Clone + 'a>(
1827    expecting: &'a str,
1828) -> impl Parser<'a, Output = &'a str, State = S> {
1829    fn_parser(move |input: &'a str, location: Location, state| {
1830        match Uni::graphemes(input, true).next() {
1831            Some(c) => match c {
1832                "\n" | "\r\n" => ParseResult::Ok {
1833                    input: &input[c.len()..],
1834                    output: c,
1835                    location: increment_row(1, location),
1836                    state,
1837                    committed: false,
1838                },
1839                _ => ParseResult::Ok {
1840                    input: &input[c.len()..],
1841                    output: c,
1842                    location: increment_col(grapheme_column_width(c), location),
1843                    state,
1844                    committed: false,
1845                },
1846            },
1847            _ => ParseResult::Err {
1848                message: format!("I'm expecting {} but reached the end of input.", expecting),
1849                from: location,
1850                to: location,
1851                state,
1852                committed: false,
1853            },
1854        }
1855    })
1856}
1857
1858/// Match any single character, internally used together with `pred`.
1859fn any_char<'a, S: Clone + 'a>(expecting: &str) -> impl Parser<'_, Output = char, State = S> {
1860    fn_parser(
1861        move |input: &str, location: Location, state| match input.chars().next() {
1862            Some(c) => match c {
1863                '\n' => ParseResult::Ok {
1864                    input: &input[c.len_utf8()..],
1865                    output: c,
1866                    location: increment_row(1, location),
1867                    state,
1868                    committed: false,
1869                },
1870                _ => ParseResult::Ok {
1871                    input: &input[c.len_utf8()..],
1872                    output: c,
1873                    location: increment_col(char_column_width(c), location),
1874                    state,
1875                    committed: false,
1876                },
1877            },
1878            _ => ParseResult::Err {
1879                message: format!("I'm expecting {} but reached the end of input.", expecting),
1880                from: location,
1881                to: location,
1882                state,
1883                committed: false,
1884            },
1885        },
1886    )
1887}
1888
1889/// Chomp one grapheme if it passes the test.
1890pub fn chomp_if<'a, F: 'a, S: Clone + 'a>(
1891    predicate: F,
1892    expecting: &'a str,
1893) -> impl Parser<'_, Output = (), State = S>
1894where
1895    F: Fn(&'a str) -> bool,
1896{
1897    any_grapheme(expecting)
1898        .pred(move |output| predicate(output), expecting)
1899        .ignore()
1900}
1901
1902/// Chomp one character if it passes the test.
1903pub fn chomp_ifc<'a, F: 'a, S: Clone + 'a>(
1904    predicate: F,
1905    expecting: &'a str,
1906) -> impl Parser<'_, Output = (), State = S>
1907where
1908    F: Fn(char) -> bool,
1909{
1910    any_char(expecting)
1911        .pred(move |output| predicate(*output), expecting)
1912        .ignore()
1913}
1914
1915/// Chomp zero or more graphemes if they pass the test.
1916pub fn chomp_while0<'a, F: 'a, S: Clone + 'a>(
1917    predicate: F,
1918    expecting: &'a str,
1919) -> impl Parser<'_, Output = (), State = S>
1920where
1921    F: Fn(&'a str) -> bool,
1922{
1923    zero_or_more(chomp_if(predicate, expecting)).ignore()
1924}
1925
1926/// Chomp zero or more characters if they pass the test.
1927///
1928/// This is commonly useful for chomping whiespaces and variable names:
1929/// ```
1930/// # use lip::*;
1931/// fn space0<'a, S: Clone + 'a>() -> impl Parser<'a, Output = (), State = S> {
1932///   chomp_while0c(|c: char| c == ' ', "a whitespace")
1933/// }
1934/// ```
1935/// See [variable](fn.variable.html) for how this can be used to chomp variable names.
1936pub fn chomp_while0c<'a, F: 'a, S: Clone + 'a>(
1937    predicate: F,
1938    expecting: &'a str,
1939) -> impl Parser<'_, Output = (), State = S>
1940where
1941    F: Fn(char) -> bool,
1942{
1943    zero_or_more(chomp_ifc(predicate, expecting)).ignore()
1944}
1945
1946/// Chomp one or more graphemes if they pass the test.
1947pub fn chomp_while1<'a, F: 'a, S: Clone + 'a>(
1948    predicate: F,
1949    expecting: &'a str,
1950) -> impl Parser<'_, Output = (), State = S>
1951where
1952    F: Fn(&str) -> bool,
1953{
1954    one_or_more(chomp_if(predicate, expecting)).ignore()
1955}
1956
1957/// Chomp one or more characters if they pass the test.
1958///
1959/// This can be used to chomp digits:
1960/// ```
1961/// # use lip::*;
1962/// fn digits<'a, S: Clone + 'a>() -> impl Parser<'a, Output = String, State = S> {
1963///   take_chomped(chomp_while1c(
1964///     &(| character: char | character.is_digit(10)),
1965///     "decimal digits"
1966///   ))
1967/// }
1968/// ```
1969/// See [digits](fn.digits.html) for a more complete digits parser with leading zero checks.
1970pub fn chomp_while1c<'a, F: 'a, S: Clone + 'a>(
1971    predicate: F,
1972    expecting: &'a str,
1973) -> impl Parser<'_, Output = (), State = S>
1974where
1975    F: Fn(char) -> bool,
1976{
1977    one_or_more(chomp_ifc(predicate, expecting)).ignore()
1978}
1979/// Take the chomped string from a bunch of chompers.
1980///
1981/// Sometimes parsers like `int` or `variable` cannot do exactly what you need.
1982/// The "chomping" family of functions is meant for that case!
1983/// Maybe you need to parse valid [PHP variables](https://www.w3schools.com/php/php_variables.asp) like `$x` and `$txt`:
1984/// ```
1985/// # use lip::*;
1986/// fn php_variable<'a, S: Clone + 'a>() -> impl Parser<'a, Output = String, State = S> {
1987///   take_chomped(succeed!()
1988///     .skip(chomp_ifc(|c: char| c == '$', "a '$'"))
1989///     .skip(chomp_ifc(|c: char| c.is_alphabetic() || c == '_', "a letter or a '_'"))
1990///     .skip(chomp_while0c(|c: char| c.is_alphanumeric() || c == '_', "a letter, digit, or '_'"))
1991///   )
1992/// }
1993/// ```
1994pub fn take_chomped<'a, P: 'a, S: Clone + 'a>(
1995    mut parser: P,
1996) -> impl Parser<'a, Output = String, State = S>
1997where
1998    P: Parser<'a, State = S>,
1999{
2000    fn_parser(
2001        move |input, location, state| match parser.parse(input, location, state) {
2002            ParseResult::Ok {
2003                input: cur_input,
2004                location: cur_location,
2005                state: cur_state,
2006                committed: cur_committed,
2007                ..
2008            } => ParseResult::Ok {
2009                input: cur_input,
2010                output: get_difference(input, cur_input).to_string(),
2011                location: cur_location,
2012                state: cur_state,
2013                committed: cur_committed,
2014            },
2015            ParseResult::Err {
2016                message,
2017                from,
2018                to,
2019                state,
2020                committed,
2021            } => ParseResult::Err {
2022                message,
2023                from,
2024                to,
2025                state,
2026                committed,
2027            },
2028        },
2029    )
2030}
2031
2032fn get_difference<'a>(whole_str: &'a str, substr: &'a str) -> &'a str {
2033    &whole_str[..whole_str.len() - substr.len()]
2034}
2035
2036fn pred<'a, P: 'a, F>(parser: P, predicate: F, expecting: &'a str) -> Pred<'a, P, F>
2037where
2038    P: Parser<'a>,
2039    F: Fn(&P::Output) -> bool,
2040{
2041    Pred(parser, predicate, expecting)
2042}
2043
2044/// Parse a single space character.
2045fn space_char<'a, S: Clone + 'a>() -> impl Parser<'a, Output = (), State = S> {
2046    chomp_if(&(|c: &str| c == " "), "a whitespace")
2047}
2048
2049/// Parse a single newline character.
2050///
2051/// Handles `\r\n` in Windows and `\n` on other platforms.
2052fn newline_char<'a, S: Clone + 'a>() -> impl Parser<'a, Output = (), State = S> {
2053    fn_parser(move |input, location, state: S| {
2054        let mut cur_input: &str = input;
2055        let mut cur_location: Location = location;
2056        let mut cur_state: S = state.clone();
2057        let result1 =
2058            chomp_ifc(&(|c: char| c == '\r'), "a carriage return").parse(input, location, state);
2059        if let ParseResult::Ok {
2060            input,
2061            location,
2062            state,
2063            ..
2064        } = result1
2065        {
2066            cur_input = input;
2067            cur_location = location;
2068            cur_state = state;
2069        }
2070        let result = chomp_ifc(&(|c: char| c == '\n'), "a newline").parse(
2071            cur_input,
2072            cur_location,
2073            cur_state,
2074        );
2075        match result {
2076            ParseResult::Ok {
2077                input,
2078                output,
2079                location,
2080                state,
2081                committed,
2082            } => ParseResult::Ok {
2083                input,
2084                output,
2085                state,
2086                committed,
2087                location: increment_row(1, location),
2088            },
2089            err @ ParseResult::Err { .. } => err,
2090        }
2091    })
2092}
2093
2094/// Parsers zero or more newline characters, each with indentations in front.
2095///
2096/// Indentation can also be `""` (no indentation)
2097pub fn newline0<'a, P: 'a, S: Clone + 'a>(
2098    indent_parser: P,
2099) -> impl Parser<'a, Output = (), State = S>
2100where
2101    P: Parser<'a, Output = (), State = S>,
2102{
2103    zero_or_more(pair(indent_parser, newline_char())).ignore()
2104}
2105
2106/// Parsers one or more newline characters, each with indentations in front.
2107///
2108/// Indentation can also be `""` (no indentation)
2109pub fn newline1<'a, P>(indent_parser: P) -> impl Parser<'a, Output = ()>
2110where
2111    P: Parser<'a, Output = ()> + 'a,
2112{
2113    pair(newline_char(), newline0(indent_parser)).ignore()
2114}
2115
2116/// Parse zero or more space characters.
2117pub fn space0<'a, S: Clone + 'a>() -> impl Parser<'a, Output = (), State = S> {
2118    zero_or_more(space_char()).ignore()
2119}
2120
2121/// Parse one or more space characters.
2122pub fn space1<'a, S: Clone + 'a>() -> impl Parser<'a, Output = (), State = S> {
2123    one_or_more(space_char()).ignore()
2124}
2125
2126/// Parse an indentation specified the number of spaces.
2127pub fn indent<'a, S: Clone + 'a>(
2128    number_of_spaces: usize,
2129) -> impl Parser<'a, Output = (), State = S> {
2130    repeat(number_of_spaces, space_char())
2131        .ignore()
2132        .map_err(move |_| {
2133            format!(
2134                "I'm expecting an indentation.\nAll indentations should be {} spaces.",
2135                number_of_spaces
2136            )
2137        })
2138}
2139
2140/// Parse a given number of indentations specified the number of spaces.
2141pub fn indents<'a, S: Clone + 'a>(
2142    number_of_spaces: usize,
2143    number_of_indents: usize,
2144) -> impl Parser<'a, Output = (), State = S> {
2145    repeat(number_of_indents, indent(number_of_spaces))
2146        .map_err(move |_| {
2147            format!(
2148                "I'm expecting {} indentation{}.\nAll indentations should be {} spaces.",
2149                number_of_indents,
2150                plural_suffix(number_of_indents),
2151                number_of_spaces,
2152            )
2153        })
2154        .ignore()
2155}
2156
2157fn plural_suffix(count: usize) -> &'static str {
2158    if count > 1 {
2159        "s"
2160    } else {
2161        ""
2162    }
2163}
2164
2165/// Repeat a parser n times
2166pub fn repeat<'a, A: Clone + 'a, P: 'a, S: Clone + 'a>(
2167    times: usize,
2168    mut parser: P,
2169) -> BoxedParser<'a, Vec<A>, S>
2170where
2171    P: Parser<'a, Output = A, State = S>,
2172{
2173    Box::new(move |mut input, mut location, mut state: S| {
2174        let mut output = Vec::new();
2175        let mut committed = false;
2176
2177        if times == 0 {
2178            return ParseResult::Ok {
2179                input,
2180                location,
2181                output,
2182                state,
2183                committed,
2184            };
2185        }
2186
2187        let mut counter = 0;
2188
2189        while let ParseResult::Ok {
2190            input: cur_input,
2191            output: cur_item,
2192            location: cur_location,
2193            state: cur_state,
2194            committed: cur_committed,
2195        } = parser.parse(input, location, state.clone())
2196        {
2197            if counter >= times {
2198                break;
2199            }
2200            input = cur_input;
2201            location = cur_location;
2202            state = cur_state;
2203            output.push(cur_item);
2204            counter += 1;
2205            committed |= cur_committed;
2206        }
2207
2208        ParseResult::Ok {
2209            input,
2210            output,
2211            location,
2212            state,
2213            committed,
2214        }
2215    })
2216}
2217
2218/// Parse one of many things.
2219///
2220/// Parser goes through each one option in order until one succeeds.
2221/// If none succeeds, return error.
2222#[macro_export]
2223macro_rules! one_of {
2224  ($single_parser:expr) => { $single_parser };
2225  ($first_parser:expr, $($parsers:expr),+) => {
2226    either($first_parser, one_of!($($parsers),*))
2227  };
2228}
2229
2230/// Choose either the left parser or the right parser to parse.
2231///
2232/// For choosing between more than two parsers, use [`one_of!`](macro.one_of!.html)
2233#[doc(hidden)]
2234pub fn either<'a, P1, P2, A: Clone + 'a, S: Clone + 'a>(
2235    mut parser1: P1,
2236    mut parser2: P2,
2237) -> impl Parser<'a, Output = A, State = S>
2238where
2239    P1: Parser<'a, Output = A, State = S> + 'a,
2240    P2: Parser<'a, Output = A, State = S> + 'a,
2241{
2242    fn_parser(move |input, location, state| {
2243        let result = match parser1.parse(input, location, state) {
2244            ok @ ParseResult::Ok { .. } => ok,
2245            ParseResult::Err {
2246                message,
2247                from,
2248                to,
2249                state,
2250                committed,
2251            } => {
2252                if committed {
2253                    ParseResult::Err {
2254                        message,
2255                        from,
2256                        to,
2257                        state,
2258                        committed,
2259                    }
2260                } else {
2261                    parser2.parse(input, location, state)
2262                }
2263            }
2264        };
2265        result
2266    })
2267}
2268
2269/// Optionally parse something. Returns supplied default value if parse failed.
2270pub fn optional_with_default<'a, A: Clone + 'a, P: 'a, S: Clone + 'a>(
2271    default: A,
2272    mut parser: P,
2273) -> impl Parser<'a, Output = A, State = S>
2274where
2275    P: Parser<'a, Output = A, State = S>,
2276{
2277    fn_parser(move |input, location, state| {
2278        let result = match parser.parse(input, location, state) {
2279            ok @ ParseResult::Ok { .. } => ok,
2280            ParseResult::Err {
2281                message,
2282                from,
2283                to,
2284                state,
2285                committed,
2286            } => {
2287                if committed {
2288                    ParseResult::Err {
2289                        message,
2290                        from,
2291                        to,
2292                        state,
2293                        committed,
2294                    }
2295                } else {
2296                    ParseResult::Ok {
2297                        input,
2298                        location,
2299                        output: default.clone(),
2300                        state,
2301                        committed: false,
2302                    }
2303                }
2304            }
2305        };
2306        result
2307    })
2308}
2309
2310/// Optionally parse something.
2311pub fn optional<'a, A: Clone + 'a, P: 'a, S: Clone + 'a>(
2312    mut parser: P,
2313) -> impl Parser<'a, Output = Option<A>, State = S>
2314where
2315    P: Parser<'a, Output = A, State = S>,
2316{
2317    fn_parser(
2318        move |input, location, state| match parser.parse(input, location, state) {
2319            ok @ ParseResult::Ok { .. } => ok.map(Some),
2320            ParseResult::Err {
2321                message,
2322                from,
2323                to,
2324                state,
2325                committed,
2326            } => {
2327                if committed {
2328                    ParseResult::Err {
2329                        message,
2330                        from,
2331                        to,
2332                        state,
2333                        committed,
2334                    }
2335                } else {
2336                    ParseResult::Ok {
2337                        input,
2338                        location,
2339                        output: None,
2340                        state,
2341                        committed: false,
2342                    }
2343                }
2344            }
2345        },
2346    )
2347}
2348
2349/// Parse a newline that maybe preceeded by a comment started with `comment_symbol`.
2350pub fn newline_with_comment<'a, S: Clone + 'a>(
2351    comment_symbol: &'a str,
2352) -> impl Parser<'_, Output = (), State = S> {
2353    succeed!()
2354        .skip(space0())
2355        .skip(either(newline_char(), line_comment(comment_symbol)))
2356}
2357
2358/// Parse a line comment started with `comment_symbol`.
2359pub fn line_comment<'a, S: Clone + 'a>(
2360    comment_symbol: &'a str,
2361) -> impl Parser<'_, Output = (), State = S> {
2362    succeed!()
2363        .skip(token(comment_symbol))
2364        .skip(zero_or_more(chomp_ifc(
2365            &(|c: char| c != '\n' && c != '\r'),
2366            "any character",
2367        )))
2368        .skip(newline_char())
2369}
2370
2371/// Parses a decimal integer, excluding the sign in front.
2372///
2373/// run int "1"    == Ok 1
2374///
2375/// run int "1234" == Ok 1234
2376///
2377/// run int "-789" == Err ...
2378///
2379/// run int "0123" == Err ...
2380///
2381/// run int "1.34" == Err ...
2382///
2383/// run int "1e31" == Err ...
2384///
2385/// run int "123a" == Err ...
2386///
2387/// run int "0x1A" == Err ...
2388pub fn int<'a, S: Clone + 'a>() -> impl Parser<'a, Output = usize, State = S> {
2389    digits("an integer", false).map(|int_str| int_str.parse().unwrap())
2390}
2391
2392/// Parses a floating point number, excluding the sign in front.
2393///
2394/// run float "123"       == Ok 123
2395///
2396/// run float "3.1415"    == Ok 3.1415
2397///
2398/// run float "0.1234"    == Ok 0.1234
2399///
2400/// run float ".1234"     == Err ...
2401///
2402/// run float "1e-42"     == Ok 1e-42
2403///
2404/// run float "6.022e23"  == Ok 6.022e23
2405///
2406/// run float "6.022E23"  == Ok 6.022e23
2407///
2408/// run float "6.022e+23" == Ok 6.022e23
2409pub fn float<'a, S: Clone + 'a>() -> impl Parser<'a, Output = f64, State = S> {
2410    let expecting = "a floating point number";
2411    succeed!(
2412        |whole: String, fraction: Option<String>, exponent: Option<String>| (whole
2413            + &fraction.unwrap_or_default()
2414            + &exponent.unwrap_or_default())
2415            .parse()
2416            .unwrap()
2417    )
2418    .keep(digits(expecting, false))
2419    .keep(optional(
2420        right(token("."), digits(expecting, true)).map(|digits| ".".to_owned() + &digits),
2421    ))
2422    .keep(optional(
2423        succeed!(|sign: Option<&'a str>, exponent: String| "e".to_string()
2424            + sign.unwrap_or_default()
2425            + &exponent)
2426        .skip(either(token("e"), token("E")))
2427        .keep(optional(either(token("+"), token("-"))))
2428        .keep(digits(expecting, false)),
2429    ))
2430}
2431
2432fn digits<'a, S: Clone + 'a>(
2433    name: &'a str,
2434    allow_leading_zeroes: bool,
2435) -> impl Parser<'_, Output = String, State = S> {
2436    take_chomped(chomp_while1c(&(|c: char| c.is_ascii_digit()), name)).update(
2437        move |input, digits: String, location: Location, state: S| {
2438            if !allow_leading_zeroes && digits.starts_with('0') && digits.len() > 1 {
2439                ParseResult::Err {
2440                    message: format!("You can't have leading zeroes in {}.", name),
2441                    from: Location {
2442                        col: location.col - digits.len(),
2443                        ..location
2444                    },
2445                    to: location,
2446                    state,
2447                    committed: false,
2448                }
2449            } else {
2450                ParseResult::Ok {
2451                    input,
2452                    output: digits,
2453                    location,
2454                    state,
2455                    committed: true,
2456                }
2457            }
2458        },
2459    )
2460}
2461
2462/// Parse a variable.
2463///
2464/// If we want to parse a PascalCase variable excluding three reserved words, we can try something like:
2465/// ```
2466/// # use lip::*;
2467/// let reserved = &([ "Func", "Import", "Export" ].iter().cloned().map(| element | element.to_string()).collect());
2468/// assert_succeed(
2469///   variable(&(|c| c.is_uppercase()), &(|c| c.is_lowercase()), &(|_| false), reserved, "a PascalCase variable"),
2470///   "Dict", "Dict".to_string()
2471/// );
2472/// ```
2473/// If we want to parse a snake_case variable, we can try something like:
2474/// ```
2475/// # use lip::*;
2476/// # use std::collections::HashSet;
2477/// assert_succeed(
2478///  variable(&(|c| c.is_lowercase()), &(|c| c.is_lowercase() || c.is_digit(10)), &(|c| c == '_'), &HashSet::new(), "a snake_case variable"),
2479///  "my_variable_1", "my_variable_1".to_string()
2480/// );
2481/// ```
2482/// The below uses the same snake_case variable parser. However, the separator `_` appeared at the end of the name `invalid_variable_name_`:
2483/// ```
2484/// # use lip::*;
2485/// # use std::collections::HashSet;
2486/// assert_fail(
2487///  variable(&(|c| c.is_lowercase()), &(|c| c.is_lowercase() || c.is_digit(10)), &(|c| c == '_'), &HashSet::new(), "a snake_case variable"),
2488///  "invalid_variable_name_", "I'm expecting a snake_case variable but found `invalid_variable_name_` ended with the separator `_`."
2489/// );
2490/// ```
2491pub fn variable<'a, S: Clone + 'a, F1: Clone, F2: Clone, F3: Clone>(
2492    start: &'a F1,
2493    inner: &'a F2,
2494    separator: &'a F3,
2495    reserved: &'a HashSet<String>,
2496    expecting: &'a str,
2497) -> impl Parser<'a, Output = String, State = S>
2498where
2499    F1: Fn(char) -> bool,
2500    F2: Fn(char) -> bool,
2501    F3: Fn(char) -> bool,
2502{
2503    take_chomped(pair(
2504        chomp_ifc(start, expecting),
2505        chomp_while0c(move |c: char| inner(c) || separator(c), expecting),
2506    ))
2507    .update(move |input, name, location, state| {
2508        if reserved.contains(&name) {
2509            ParseResult::Err {
2510                message: format!(
2511                    "I'm expecting {} but found a reserved word `{}`.",
2512                    expecting, name
2513                ),
2514                from: Location {
2515                    col: location.col - name.len(),
2516                    ..location
2517                },
2518                to: location,
2519                state,
2520                committed: false,
2521            }
2522        } else if name
2523            .chars()
2524            .zip(name[1..].chars())
2525            .any(|(c, next_c)| separator(c) && separator(next_c))
2526        {
2527            ParseResult::Err {
2528                message: format!(
2529                    "I'm expecting {} but found `{}` with duplicated separators.",
2530                    expecting, name
2531                ),
2532                from: Location {
2533                    col: location.col - name.len(),
2534                    ..location
2535                },
2536                to: location,
2537                state,
2538                committed: false,
2539            }
2540        } else if separator(name.chars().last().unwrap()) {
2541            ParseResult::Err {
2542                message: format!(
2543                    "I'm expecting {} but found `{}` ended with the separator `{}`.",
2544                    expecting,
2545                    name,
2546                    &name.chars().last().unwrap()
2547                ),
2548                from: Location {
2549                    col: location.col - name.len(),
2550                    ..location
2551                },
2552                to: location,
2553                state,
2554                committed: false,
2555            }
2556        } else {
2557            ParseResult::Ok {
2558                input,
2559                location,
2560                output: name,
2561                state,
2562                committed: true,
2563            }
2564        }
2565    })
2566}
2567
2568/// What’s the deal with trailing commas? Are they Forbidden? Are they Optional? Are they Mandatory?
2569#[derive(Copy, Clone)]
2570pub enum Trailing {
2571    Forbidden,
2572    Optional,
2573    Mandatory,
2574}
2575
2576#[derive(Clone)]
2577pub enum OneOfTwo<T1, T2> {
2578    First(T1),
2579    Second(T2),
2580}
2581
2582impl<'a, P1, P2, S: Clone + 'a> Parser<'a> for OneOfTwo<P1, P2>
2583where
2584    P1: Parser<'a, State = S>,
2585    P2: Parser<'a, Output = P1::Output, State = S>,
2586{
2587    type Output = P1::Output;
2588    type State = S;
2589
2590    fn parse(
2591        &mut self,
2592        input: &'a str,
2593        location: Location,
2594        state: Self::State,
2595    ) -> ParseResult<'a, Self::Output, Self::State> {
2596        match self {
2597            OneOfTwo::First(ref mut p) => p.parse(input, location, state),
2598            OneOfTwo::Second(ref mut p) => p.parse(input, location, state),
2599        }
2600    }
2601}
2602
2603#[derive(Clone)]
2604pub enum OneOfThree<T1, T2, T3> {
2605    First(T1),
2606    Second(T2),
2607    Third(T3),
2608}
2609
2610impl<'a, P1, P2, P3, S: Clone + 'a> Parser<'a> for OneOfThree<P1, P2, P3>
2611where
2612    P1: Parser<'a, State = S>,
2613    P2: Parser<'a, Output = P1::Output, State = S>,
2614    P3: Parser<'a, Output = P1::Output, State = S>,
2615{
2616    type Output = P1::Output;
2617    type State = S;
2618
2619    fn parse(
2620        &mut self,
2621        input: &'a str,
2622        location: Location,
2623        state: Self::State,
2624    ) -> ParseResult<'a, Self::Output, Self::State> {
2625        match self {
2626            OneOfThree::First(ref mut p) => p.parse(input, location, state),
2627            OneOfThree::Second(ref mut p) => p.parse(input, location, state),
2628            OneOfThree::Third(ref mut p) => p.parse(input, location, state),
2629        }
2630    }
2631}
2632
2633/// Parse a sequence like lists or code blocks.
2634///
2635/// Example:
2636/// Parse a list containing the string "abc" with optional trailing comma:
2637/// ```
2638/// # use lip::*;
2639/// assert_succeed(sequence(
2640///   token("["),
2641///   || token("abc"),
2642///   || token(","),
2643///   || space0(),
2644///   token("]"),
2645///   Trailing::Optional),
2646/// "[abc, abc, abc]", vec!["abc", "abc", "abc"]);
2647/// ```
2648/// Note: `spaces` are inserted between every part.
2649/// So if you use `space1` instead of `space0`, you need to
2650/// put more spaces before and after separators, between
2651/// start symbol and first item and between last item or separator
2652/// and the end symbol:
2653/// ```
2654/// # use lip::*;
2655/// assert_succeed(sequence(
2656///   token("["),
2657///   || token("abc"),
2658///   || token(","),
2659///   || space1(),
2660///   token("]"),
2661///   Trailing::Optional),
2662/// "[ abc , abc , abc ]", vec!["abc", "abc", "abc"]);
2663/// ```
2664pub fn sequence<
2665    'a,
2666    A: Clone + 'a,
2667    StartOutput: Clone + 'a,
2668    StartParser: 'a,
2669    ItemParser: 'a,
2670    SepOutput: Clone + 'a,
2671    SepParser: 'a,
2672    SpacesParser: 'a,
2673    EndOutput: Clone + 'a,
2674    EndParser: 'a,
2675    S: Clone + 'a,
2676>(
2677    start: StartParser,
2678    item: impl Fn() -> ItemParser,
2679    separator: impl Fn() -> SepParser,
2680    spaces: impl Fn() -> SpacesParser,
2681    end: EndParser,
2682    trailing: Trailing,
2683) -> impl Parser<'a, Output = Vec<A>, State = S>
2684where
2685    StartParser: Parser<'a, Output = StartOutput, State = S>,
2686    ItemParser: Parser<'a, Output = A, State = S>,
2687    SepParser: Parser<'a, Output = SepOutput, State = S>,
2688    SpacesParser: Parser<'a, Output = (), State = S>,
2689    EndParser: Parser<'a, Output = EndOutput, State = S>,
2690{
2691    wrap(
2692        pair(start, spaces()),
2693        optional(
2694            pair(
2695                item(),
2696                right(
2697                    spaces(),
2698                    left(
2699                        zero_or_more(wrap(
2700                            left(separator(), spaces()).backtrackable(),
2701                            item(),
2702                            spaces(),
2703                        )),
2704                        match trailing {
2705                            Trailing::Forbidden => succeed!().first_of_three(),
2706                            Trailing::Optional => {
2707                                optional_with_default((), left(separator().ignore(), spaces()))
2708                                    .second_of_three()
2709                            }
2710                            Trailing::Mandatory => {
2711                                left(separator(), spaces()).ignore().third_of_three()
2712                            }
2713                        },
2714                    ),
2715                ),
2716            )
2717            .map(move |(first_item, mut rest_items)| {
2718                rest_items.insert(0, first_item);
2719                rest_items
2720            }),
2721        )
2722        .map(|items| items.unwrap_or(vec![])),
2723        end,
2724    )
2725}
2726
2727/// Wrap a parser with two other delimiter parsers
2728fn wrap<'a, A: Clone + 'a, B: Clone + 'a, C: Clone + 'a, P1: 'a, P2: 'a, P3: 'a, S: Clone + 'a>(
2729    left_delimiter: P1,
2730    wrapped: P2,
2731    right_delimiter: P3,
2732) -> impl Parser<'a, Output = B, State = S>
2733where
2734    P1: Parser<'a, Output = A, State = S>,
2735    P2: Parser<'a, Output = B, State = S>,
2736    P3: Parser<'a, Output = C, State = S>,
2737{
2738    right(left_delimiter, left(wrapped, right_delimiter))
2739}
2740
2741/// Record the beginning and ending location of the thing being parsed.
2742///
2743/// You can surround any parser with `located` and remember the location
2744/// of the parsed output for later error messaging or text processing.
2745pub fn located<'a, P: 'a, A, S: Clone + 'a>(
2746    mut parser: P,
2747) -> impl Parser<'a, Output = Located<A>, State = S>
2748where
2749    P: Parser<'a, Output = A, State = S>,
2750{
2751    fn_parser(
2752        move |input, location, state| match parser.parse(input, location, state) {
2753            ParseResult::Ok {
2754                input: cur_input,
2755                output,
2756                location: cur_location,
2757                state: cur_state,
2758                committed: cur_committed,
2759            } => ParseResult::Ok {
2760                input: cur_input,
2761                output: Located {
2762                    value: output,
2763                    from: Location {
2764                        row: location.row,
2765                        col: location.col,
2766                    },
2767                    to: Location {
2768                        row: cur_location.row,
2769                        col: cur_location.col,
2770                    },
2771                },
2772                location: cur_location,
2773                state: cur_state,
2774                committed: cur_committed,
2775            },
2776            ParseResult::Err {
2777                message,
2778                from,
2779                to,
2780                state,
2781                committed,
2782            } => ParseResult::Err {
2783                message,
2784                from,
2785                to,
2786                state,
2787                committed,
2788            },
2789        },
2790    )
2791}
2792
2793/// Pretty print the error.
2794///
2795/// Example:
2796/// 1| A=A+2
2797///      ^^^
2798/// ⚠️ I can't find a computation instruction matching `A+2`.
2799/// Try something like `D+1` and `0`.
2800pub fn display_error(source: &str, error_message: String, from: Location, to: Location) -> String {
2801    let row = from.row;
2802    let col = from.col;
2803    let line = source.lines().nth(row - 1).unwrap();
2804    let error_length = if from.row < to.row {
2805        std::cmp::max(line.len() + 1 - from.col, 1)
2806    } else if to.col == from.col {
2807        1
2808    } else {
2809        to.col - from.col
2810    };
2811    let row_tag = row.to_string();
2812    let row_tag_len = if row < source.lines().count() {
2813        (row + 1).to_string().len()
2814    } else {
2815        row_tag.len()
2816    };
2817    let prev_line = if row > 1 {
2818        format!("{: >width$}", (row - 1).to_string(), width = row_tag_len)
2819            + "| "
2820            + source.lines().nth(row - 2).unwrap()
2821            + "\n"
2822    } else {
2823        String::new()
2824    };
2825    let next_line = if row < source.lines().count() {
2826        (row + 1).to_string() + "| " + source.lines().nth(row).unwrap() + "\n"
2827    } else {
2828        String::new()
2829    };
2830    let error_line = row_tag + "| " + line;
2831    let error_pointer = " ".repeat(col - 1 + row_tag_len + 2) + &"^".repeat(error_length);
2832    prev_line + &error_line + "\n" + &error_pointer + "\n" + &next_line + "⚠️ " + &error_message
2833}
2834
2835fn update_state<'a, P: 'a, F>(parser: P, f: F) -> UpdateState<P, F>
2836where
2837    P: Parser<'a>,
2838    F: Fn(P::Output, P::State) -> P::State,
2839{
2840    UpdateState(parser, f)
2841}
2842
2843fn update<'a, P: 'a, A, B, F: Clone>(parser: P, f: F) -> Update<P, F>
2844where
2845    P: Parser<'a, Output = A>,
2846    F: FnOnce(&'a str, A, Location, P::State) -> ParseResult<'a, B, P::State>,
2847{
2848    Update(parser, f)
2849}
2850
2851#[doc(hidden)]
2852pub fn assert_succeed<'a, P: 'a, A: PartialEq + Debug>(mut parser: P, source: &'a str, expected: A)
2853where
2854    P: Parser<'a, Output = A, State = ()>,
2855{
2856    assert_eq!(
2857        parser
2858            .parse(source, Location { row: 1, col: 1 }, ())
2859            .unwrap(source),
2860        expected
2861    )
2862}
2863
2864#[doc(hidden)]
2865pub fn assert_fail<'a, P: 'a, A: Debug>(mut parser: P, source: &'a str, message: &'a str)
2866where
2867    P: Parser<'a, Output = A, State = ()>,
2868{
2869    assert_eq!(
2870        parser
2871            .parse(source, Location { row: 1, col: 1 }, ())
2872            .unwrap_err(),
2873        message
2874    )
2875}
2876
2877/// Returns the number of cells visually occupied by a sequence
2878/// of graphemes
2879/// source: https://github.com/unicode-rs/unicode-width/issues/4#issuecomment-549906181
2880fn unicode_column_width(s: &str) -> usize {
2881    s.graphemes(true).map(grapheme_column_width).sum()
2882}
2883
2884/// Returns the number of cells visually occupied by a grapheme.
2885/// The input string must be a single grapheme.
2886/// source: https://github.com/unicode-rs/unicode-width/issues/4#issuecomment-549906181
2887fn grapheme_column_width(s: &str) -> usize {
2888    // Due to this issue:
2889    // https://github.com/unicode-rs/unicode-width/issues/4
2890    // we cannot simply use the unicode-width crate to compute
2891    // the desired value.
2892    // Let's check for emoji-ness for ourselves first
2893    use xi_unicode::EmojiExt;
2894    for c in s.chars() {
2895        if c.is_emoji_modifier_base() || c.is_emoji_modifier() {
2896            // treat modifier sequences as double wide
2897            return 2;
2898        }
2899    }
2900    UnicodeWidthStr::width(s)
2901}
2902
2903fn char_column_width(c: char) -> usize {
2904    UnicodeWidthChar::width(c).unwrap_or(0)
2905}