1 //! This crate contains parser combinators, roughly based on the Haskell libraries
2 //! [parsec](http://hackage.haskell.org/package/parsec) and
3 //! [attoparsec](https://hackage.haskell.org/package/attoparsec).
4 //!
5 //! A parser in this library can be described as a function which takes some input and if it
6 //! is successful, returns a value together with the remaining input.
7 //! A parser combinator is a function which takes one or more parsers and returns a new parser.
8 //! For instance the [`many`] parser can be used to convert a parser for single digits into one that
9 //! parses multiple digits. By modeling parsers in this way it becomes easy to compose complex
10 //! parsers in an almost declarative way.
11 //!
12 //! # Overview
13 //!
14 //! `combine` limits itself to creating [LL(1) parsers](https://en.wikipedia.org/wiki/LL_parser)
15 //! (it is possible to opt-in to LL(k) parsing using the [`attempt`] combinator) which makes the
16 //! parsers easy to reason about in both function and performance while sacrificing
17 //! some generality. In addition to you being able to reason better about the parsers you
18 //! construct `combine` the library also takes the knowledge of being an LL parser and uses it to
19 //! automatically construct good error messages.
20 //!
21 //! ```rust
22 //! extern crate combine;
23 //! use combine::{Parser, EasyParser};
24 //! use combine::stream::position;
25 //! use combine::parser::char::{digit, letter};
26 //! const MSG: &'static str = r#"Parse error at line: 1, column: 1
27 //! Unexpected `|`
28 //! Expected digit or letter
29 //! "#;
30 //!
31 //! fn main() {
32 //!     // Wrapping a `&str` with `State` provides automatic line and column tracking. If `State`
33 //!     // was not used the positions would instead only be pointers into the `&str`
34 //!     if let Err(err) = digit().or(letter()).easy_parse(position::Stream::new("|")) {
35 //!         assert_eq!(MSG, format!("{}", err));
36 //!     }
37 //! }
38 //! ```
39 //!
40 //! This library is currently split into a few core modules:
41 //!
42 //! * [`parser`][mod parser] is where you will find all the parsers that combine provides. It contains the core
43 //! [`Parser`] trait as well as several submodules such as `sequence` or `choice` which each
44 //! contain several parsers aimed at a specific niche.
45 //!
46 //! * [`stream`] contains the second most important trait next to [`Parser`]. Streams represent the
47 //! data source which is being parsed such as `&[u8]`, `&str` or iterators.
48 //!
49 //! * [`easy`] contains combine's default "easy" error and stream handling. If you use the
50 //! `easy_parse` method to start your parsing these are the types that are used.
51 //!
52 //! * [`error`] contains the types and traits that make up combine's error handling. Unless you
53 //! need to customize the errors your parsers return you should not need to use this module much.
54 //!
55 //!
56 //! # Examples
57 //!
58 //! ```
59 //! extern crate combine;
60 //! use combine::parser::char::{spaces, digit, char};
61 //! use combine::{many1, sep_by, Parser, EasyParser};
62 //! use combine::stream::easy;
63 //!
64 //! fn main() {
65 //!     //Parse spaces first and use the with method to only keep the result of the next parser
66 //!     let integer = spaces()
67 //!         //parse a string of digits into an i32
68 //!         .with(many1(digit()).map(|string: String| string.parse::<i32>().unwrap()));
69 //!
70 //!     //Parse integers separated by commas, skipping whitespace
71 //!     let mut integer_list = sep_by(integer, spaces().skip(char(',')));
72 //!
73 //!     //Call parse with the input to execute the parser
74 //!     let input = "1234, 45,78";
75 //!     let result: Result<(Vec<i32>, &str), easy::ParseError<&str>> =
76 //!         integer_list.easy_parse(input);
77 //!     match result {
78 //!         Ok((value, _remaining_input)) => println!("{:?}", value),
79 //!         Err(err) => println!("{}", err)
80 //!     }
81 //! }
82 //! ```
83 //!
84 //! If we need a parser that is mutually recursive or if we want to export a reusable parser the
85 //! [`parser!`] macro can be used. In effect it makes it possible to return a parser without naming
86 //! the type of the parser (which can be very large due to combine's trait based approach). While
87 //! it is possible to do avoid naming the type without the macro those solutions require either
88 //! allocation (`Box<dyn Parser< Input, Output = O, PartialState = P>>`) or via `impl Trait` in the
89 //! return position. The macro thus threads the needle and makes it possible to have
90 //! non-allocating, anonymous parsers on stable rust.
91 //!
92 //! ```
93 //! #[macro_use]
94 //! extern crate combine;
95 //! use combine::parser::char::{char, letter, spaces};
96 //! use combine::{between, choice, many1, parser, sep_by, Parser, EasyParser};
97 //! use combine::error::{ParseError, StdParseResult};
98 //! use combine::stream::{Stream, Positioned};
99 //! use combine::stream::position;
100 //!
101 //! #[derive(Debug, PartialEq)]
102 //! pub enum Expr {
103 //!     Id(String),
104 //!     Array(Vec<Expr>),
105 //!     Pair(Box<Expr>, Box<Expr>)
106 //! }
107 //!
108 //! // `impl Parser` can be used to create reusable parsers with zero overhead
109 //! fn expr_<Input>() -> impl Parser< Input, Output = Expr>
110 //!     where Input: Stream<Token = char>,
111 //! {
112 //!     let word = many1(letter());
113 //!
114 //!     // A parser which skips past whitespace.
115 //!     // Since we aren't interested in knowing that our expression parser
116 //!     // could have accepted additional whitespace between the tokens we also silence the error.
117 //!     let skip_spaces = || spaces().silent();
118 //!
119 //!     //Creates a parser which parses a char and skips any trailing whitespace
120 //!     let lex_char = |c| char(c).skip(skip_spaces());
121 //!
122 //!     let comma_list = sep_by(expr(), lex_char(','));
123 //!     let array = between(lex_char('['), lex_char(']'), comma_list);
124 //!
125 //!     //We can use tuples to run several parsers in sequence
126 //!     //The resulting type is a tuple containing each parsers output
127 //!     let pair = (lex_char('('),
128 //!                 expr(),
129 //!                 lex_char(','),
130 //!                 expr(),
131 //!                 lex_char(')'))
132 //!                    .map(|t| Expr::Pair(Box::new(t.1), Box::new(t.3)));
133 //!
134 //!     choice((
135 //!         word.map(Expr::Id),
136 //!         array.map(Expr::Array),
137 //!         pair,
138 //!     ))
139 //!         .skip(skip_spaces())
140 //! }
141 //!
142 //! // As this expression parser needs to be able to call itself recursively `impl Parser` can't
143 //! // be used on its own as that would cause an infinitely large type. We can avoid this by using
144 //! // the `parser!` macro which erases the inner type and the size of that type entirely which
145 //! // lets it be used recursively.
146 //! //
147 //! // (This macro does not use `impl Trait` which means it can be used in rust < 1.26 as well to
148 //! // emulate `impl Parser`)
149 //! parser!{
150 //!     fn expr[Input]()(Input) -> Expr
151 //!     where [Input: Stream<Token = char>]
152 //!     {
153 //!         expr_()
154 //!     }
155 //! }
156 //!
157 //! fn main() {
158 //!     let result = expr()
159 //!         .parse("[[], (hello, world), [rust]]");
160 //!     let expr = Expr::Array(vec![
161 //!           Expr::Array(Vec::new())
162 //!         , Expr::Pair(Box::new(Expr::Id("hello".to_string())),
163 //!                      Box::new(Expr::Id("world".to_string())))
164 //!         , Expr::Array(vec![Expr::Id("rust".to_string())])
165 //!     ]);
166 //!     assert_eq!(result, Ok((expr, "")));
167 //! }
168 //! ```
169 //!
170 //! [`combinator`]: combinator/index.html
171 //! [mod parser]: parser/index.html
172 //! [`easy`]: easy/index.html
173 //! [`error`]: error/index.html
174 //! [`char`]: parser/char/index.html
175 //! [`byte`]: parser/byte/index.html
176 //! [`range`]: parser/range/index.html
177 //! [`many`]: parser/repeat/fn.many.html
178 //! [`attempt`]: parser/combinator/fn.attempt.html
179 //! [`satisfy`]: parser/token/fn.satisfy.html
180 //! [`or`]: parser/trait.Parser.html#method.or
181 //! [`Stream`]: stream/trait.Stream.html
182 //! [`RangeStream`]: stream/trait.RangeStream.html
183 //! [`Parser`]: parser/trait.Parser.html
184 //! [fn parser]: parser/function/fn.parser.html
185 //! [`parser!`]: macro.parser.html
186 // inline is only used on trivial functions returning parsers
187 #![allow(
188     clippy::inline_always,
189     clippy::type_complexity,
190     clippy::too_many_arguments,
191     clippy::match_like_matches_macro
192 )]
193 #![cfg_attr(not(feature = "std"), no_std)]
194 #![cfg_attr(docsrs, feature(doc_cfg))]
195 
196 #[cfg(feature = "alloc")]
197 extern crate alloc;
198 
199 #[doc(inline)]
200 pub use crate::error::{ParseError, ParseResult, StdParseResult};
201 
202 #[cfg(feature = "std")]
203 #[doc(inline)]
204 pub use crate::parser::EasyParser;
205 
206 #[doc(inline)]
207 pub use crate::parser::Parser;
208 
209 #[doc(inline)]
210 pub use crate::stream::{Positioned, RangeStream, RangeStreamOnce, Stream, StreamOnce};
211 
212 #[doc(inline)]
213 pub use crate::parser::{
214     choice::optional,
215     combinator::{attempt, look_ahead, not_followed_by},
216     error::{unexpected, unexpected_any},
217     function::parser,
218     repeat::{
219         chainl1, chainr1, count, count_min_max, many, many1, sep_by, sep_by1, sep_end_by,
220         sep_end_by1, skip_count, skip_count_min_max, skip_many, skip_many1,
221     },
222     sequence::between,
223     token::{
224         any, eof, none_of, one_of, position, produce, satisfy, satisfy_map, token, tokens, value,
225     },
226 };
227 
228 #[doc(inline)]
229 pub use crate::parser::choice::choice;
230 
231 #[doc(inline)]
232 pub use crate::parser::combinator::from_str;
233 
234 #[doc(inline)]
235 pub use crate::parser::token::tokens_cmp;
236 
237 /// Declares a named parser which can easily be reused.
238 ///
239 /// The expression which creates the parser should have no side effects as it may be called
240 /// multiple times even during a single parse attempt.
241 ///
242 /// NOTE: You can use `impl Trait` in the return position instead. See the [json parser][] for an
243 /// example.
244 ///
245 /// [json parser]:https://github.com/Marwes/combine/blob/master/benches/json.rs
246 ///
247 /// ```
248 /// #[macro_use]
249 /// extern crate combine;
250 /// use combine::parser::char::digit;
251 /// use combine::{any, choice, from_str, many1, Parser, EasyParser, Stream};
252 /// use combine::error::ParseError;
253 ///
254 /// parser!{
255 ///     /// `[Input]` represents a normal type parameters and lifetime declaration for the function
256 ///     /// It gets expanded to `<Input>`
257 ///     fn integer[Input]()(Input) -> i32
258 ///     where [
259 ///         Input: Stream<Token = char>,
260 ///         <Input::Error as ParseError<Input::Token, Input::Range, Input::Position>>::StreamError:
261 ///             From<::std::num::ParseIntError>,
262 ///     ]
263 ///     {
264 ///         // The body must be a block body ( `{ <block body> }`) which ends with an expression
265 ///         // which evaluates to a parser
266 ///         from_str(many1::<String, _, _>(digit()))
267 ///     }
268 /// }
269 ///
270 /// #[derive(Debug, PartialEq)]
271 /// pub enum IntOrString {
272 ///     Int(i32),
273 ///     String(String),
274 /// }
275 /// // prefix with `pub` to declare a public parser
276 /// parser!{
277 ///     // Documentation comments works as well
278 ///
279 ///     /// Parses an integer or a string (any characters)
280 ///     pub fn integer_or_string[Input]()(Input) -> IntOrString
281 ///     where [
282 ///         Input: Stream<Token = char>,
283 ///         <Input::Error as ParseError<Input::Token, Input::Range, Input::Position>>::StreamError:
284 ///             From<::std::num::ParseIntError>,
285 ///     ]
286 ///     {
287 ///         choice!(
288 ///             integer().map(IntOrString::Int),
289 ///             many1(any()).map(IntOrString::String)
290 ///         )
291 ///     }
292 /// }
293 ///
294 /// parser!{
295 ///     // Give the created type a unique name
296 ///     #[derive(Clone)]
297 ///     pub struct Twice;
298 ///     pub fn twice[Input, F, P](f: F)(Input) -> (P::Output, P::Output)
299 ///         where [P: Parser<Input>,
300 ///                F: FnMut() -> P]
301 ///     {
302 ///         (f(), f())
303 ///     }
304 /// }
305 ///
306 /// fn main() {
307 ///     assert_eq!(integer().easy_parse("123"), Ok((123, "")));
308 ///     assert!(integer().easy_parse("!").is_err());
309 ///
310 ///     assert_eq!(
311 ///         integer_or_string().easy_parse("123"),
312 ///         Ok((IntOrString::Int(123), ""))
313 ///     );
314 ///     assert_eq!(
315 ///         integer_or_string().easy_parse("abc"),
316 ///         Ok((IntOrString::String("abc".to_string()), ""))
317 ///     );
318 ///     assert_eq!(twice(|| digit()).parse("123"), Ok((('1', '2'), "3")));
319 /// }
320 /// ```
321 #[macro_export]
322 macro_rules! parser {
323     (
324         type PartialState = $partial_state: ty;
325         $(#[$attr:meta])*
326         $fn_vis: vis fn $name: ident [$($type_params: tt)*]( $($arg: ident :  $arg_type: ty),*)
327             ($input_type: ty) -> $output_type: ty
328             where [$($where_clause: tt)*]
329         $parser: block
330     ) => {
331         $crate::combine_parser_impl!{
332             #[allow(non_camel_case_types)]
333             #[doc(hidden)]
334             $fn_vis struct $name;
335             (type PartialState = ($partial_state);)
336             $(#[$attr])*
337             $fn_vis fn $name [$($type_params)*]($($arg : $arg_type),*)($input_type) -> $output_type
338                 where [$($where_clause)*]
339             $parser
340         }
341     };
342     (
343         $(#[$derive:meta])*
344         $struct_vis: vis struct $type_name: ident;
345         type PartialState = $partial_state: ty;
346         $(#[$attr:meta])*
347         $fn_vis: vis fn $name: ident [$($type_params: tt)*]( $($arg: ident :  $arg_type: ty),* )
348             ($input_type: ty) -> $output_type: ty
349             where [$($where_clause: tt)*]
350         $parser: block
351     ) => {
352         $crate::combine_parser_impl!{
353             $(#[$derive])*
354             $struct_vis struct $type_name;
355             (type PartialState = ($partial_state);)
356             $(#[$attr])*
357             $fn_vis fn $name [$($type_params)*]($($arg : $arg_type),*)($input_type) -> $output_type
358                 where [$($where_clause)*]
359             $parser
360         }
361     };
362     (
363         $(#[$attr:meta])*
364         $fn_vis: vis fn $name: ident [$($type_params: tt)*]( $($arg: ident :  $arg_type: ty),*)
365             ($input_type: ty) -> $output_type: ty
366             where [$($where_clause: tt)*]
367         $parser: block
368     ) => {
369         $crate::combine_parser_impl!{
370             #[allow(non_camel_case_types)]
371             #[doc(hidden)]
372             $fn_vis struct $name;
373             (type PartialState = (());)
374             $(#[$attr])*
375             $fn_vis fn $name [$($type_params)*]($($arg : $arg_type),*)($input_type) -> $output_type
376                 where [$($where_clause)*]
377             $parser
378         }
379     };
380     (
381         $(#[$derive:meta])*
382         $struct_vis: vis struct $type_name: ident;
383         $(#[$attr:meta])*
384         $fn_vis: vis fn $name: ident [$($type_params: tt)*]( $($arg: ident :  $arg_type: ty),* )
385             ($input_type: ty) -> $output_type: ty
386             where [$($where_clause: tt)*]
387         $parser: block
388     ) => {
389         $crate::combine_parser_impl!{
390             $(#[$derive])*
391             $struct_vis struct $type_name;
392             (type PartialState = (());)
393             $(#[$attr])*
394             $fn_vis fn $name [$($type_params)*]($($arg : $arg_type),*)($input_type) -> $output_type
395                 where [$($where_clause)*]
396             $parser
397         }
398     };
399 }
400 
401 #[doc(hidden)]
402 #[macro_export]
403 macro_rules! combine_parse_partial {
404     ((()) $mode:ident $input:ident $state:ident $parser:block) => {{
405         let _ = $state;
406         let mut state = Default::default();
407         let state = &mut state;
408         $parser.parse_mode($mode, $input, state)
409     }};
410     (($ignored:ty) $mode:ident $input:ident $state:ident $parser:block) => {
411         $parser.parse_mode($mode, $input, $state)
412     };
413 }
414 
415 #[doc(hidden)]
416 #[macro_export]
417 macro_rules! combine_parser_impl {
418     (
419         $(#[$derive:meta])*
420         $struct_vis: vis struct $type_name: ident;
421         (type PartialState = ($($partial_state: tt)*);)
422         $(#[$attr:meta])*
423         $fn_vis: vis fn $name: ident [$($type_params: tt)*]( $($arg: ident :  $arg_type: ty),*)
424             ($input_type: ty) -> $output_type: ty
425             where [$($where_clause: tt)*]
426         $parser: block
427     ) => {
428 
429         $(#[$derive])*
430         $struct_vis struct $type_name<$($type_params)*>
431             where <$input_type as $crate::stream::StreamOnce>::Error:
432                 $crate::error::ParseError<
433                     <$input_type as $crate::stream::StreamOnce>::Token,
434                     <$input_type as $crate::stream::StreamOnce>::Range,
435                     <$input_type as $crate::stream::StreamOnce>::Position
436                     >,
437                 $input_type: $crate::stream::Stream,
438                 $($where_clause)*
439         {
440             $(pub $arg : $arg_type,)*
441             __marker: $crate::lib::marker::PhantomData<fn ($input_type) -> $output_type>
442         }
443 
444         // We want this to work on older compilers, at least for a while
445         #[allow(non_shorthand_field_patterns)]
446         impl<$($type_params)*> $crate::Parser<$input_type> for $type_name<$($type_params)*>
447             where <$input_type as $crate::stream::StreamOnce>::Error:
448                     $crate::error::ParseError<
449                         <$input_type as $crate::stream::StreamOnce>::Token,
450                         <$input_type as $crate::stream::StreamOnce>::Range,
451                         <$input_type as $crate::stream::StreamOnce>::Position
452                         >,
453                 $input_type: $crate::stream::Stream,
454                 $($where_clause)*
455         {
456 
457             type Output = $output_type;
458             type PartialState = $($partial_state)*;
459 
460             $crate::parse_mode!($input_type);
461             #[inline]
462             fn parse_mode_impl<M>(
463                 &mut self,
464                 mode: M,
465                 input: &mut $input_type,
466                 state: &mut Self::PartialState,
467                 ) -> $crate::error::ParseResult<$output_type, <$input_type as $crate::stream::StreamOnce>::Error>
468             where M: $crate::parser::ParseMode
469             {
470                 let $type_name { $( $arg: ref mut $arg,)* .. } = *self;
471                 $crate::combine_parse_partial!(($($partial_state)*) mode input state $parser)
472             }
473 
474             #[inline]
475             fn add_error(
476                 &mut self,
477                 errors: &mut $crate::error::Tracked<
478                     <$input_type as $crate::stream::StreamOnce>::Error
479                     >)
480             {
481                 let $type_name { $( $arg : ref mut $arg,)*  .. } = *self;
482                 let mut parser = $parser;
483                 {
484                     let _: &mut dyn $crate::Parser< $input_type, Output = $output_type, PartialState = _> = &mut parser;
485                 }
486                 parser.add_error(errors)
487             }
488 
489             fn add_committed_expected_error(
490                 &mut self,
491                 errors: &mut $crate::error::Tracked<
492                     <$input_type as $crate::stream::StreamOnce>::Error
493                     >)
494             {
495                 let $type_name { $( $arg : ref mut $arg,)*  .. } = *self;
496                 let mut parser = $parser;
497                 {
498                     let _: &mut dyn $crate::Parser< $input_type, Output = $output_type, PartialState = _> = &mut parser;
499                 }
500                 parser.add_committed_expected_error(errors)
501             }
502         }
503 
504         $(#[$attr])*
505         #[inline]
506         $fn_vis fn $name< $($type_params)* >(
507                 $($arg : $arg_type),*
508             ) -> $type_name<$($type_params)*>
509             where <$input_type as $crate::stream::StreamOnce>::Error:
510                     $crate::error::ParseError<
511                         <$input_type as $crate::stream::StreamOnce>::Token,
512                         <$input_type as $crate::stream::StreamOnce>::Range,
513                         <$input_type as $crate::stream::StreamOnce>::Position
514                         >,
515                 $input_type: $crate::stream::Stream,
516                 $($where_clause)*
517         {
518             $type_name {
519                 $($arg,)*
520                 __marker: $crate::lib::marker::PhantomData
521             }
522         }
523     };
524 }
525 
526 /// Internal API. May break without a semver bump
527 macro_rules! forward_parser {
528     ($input: ty, $method: ident $( $methods: ident)*, $($field: tt)*) => {
529         forward_parser!($input, $method $($field)+);
530         forward_parser!($input, $($methods)*, $($field)+);
531     };
532     ($input: ty, parse_mode $($field: tt)+) => {
533         #[inline]
534         fn parse_mode_impl<M>(
535             &mut self,
536             mode: M,
537             input: &mut $input,
538             state: &mut Self::PartialState,
539         ) -> ParseResult<Self::Output, <$input as $crate::StreamOnce>::Error>
540         where
541             M: ParseMode,
542         {
543             self.$($field)+.parse_mode(mode, input, state).map(|(a, _)| a)
544         }
545     };
546     ($input: ty, parse_lazy $($field: tt)+) => {
547         fn parse_lazy(
548             &mut self,
549             input: &mut $input,
550         ) -> ParseResult<Self::Output, <$input as $crate::StreamOnce>::Error> {
551             self.$($field)+.parse_lazy(input)
552         }
553     };
554     ($input: ty, parse_first $($field: tt)+) => {
555         fn parse_first(
556             &mut self,
557             input: &mut $input,
558             state: &mut Self::PartialState,
559         ) -> ParseResult<Self::Output, <$input as $crate::StreamOnce>::Error> {
560             self.$($field)+.parse_first(input, state)
561         }
562     };
563     ($input: ty, parse_partial $($field: tt)+) => {
564         fn parse_partial(
565             &mut self,
566             input: &mut $input,
567             state: &mut Self::PartialState,
568         ) -> ParseResult<Self::Output, <$input as $crate::StreamOnce>::Error> {
569             self.$($field)+.parse_partial(input, state)
570         }
571     };
572     ($input: ty, add_error $($field: tt)+) => {
573 
574         fn add_error(&mut self, error: &mut $crate::error::Tracked<<$input as $crate::StreamOnce>::Error>) {
575             self.$($field)+.add_error(error)
576         }
577     };
578     ($input: ty, add_committed_expected_error $($field: tt)+) => {
579         fn add_committed_expected_error(&mut self, error: &mut $crate::error::Tracked<<$input as $crate::StreamOnce>::Error>) {
580             self.$($field)+.add_committed_expected_error(error)
581         }
582     };
583     ($input: ty, parser_count $($field: tt)+) => {
584         fn parser_count(&self) -> $crate::ErrorOffset {
585             self.$($field)+.parser_count()
586         }
587     };
588     ($input: ty, $field: tt) => {
589         forward_parser!($input, parse_lazy parse_first parse_partial add_error add_committed_expected_error parser_count, $field);
590     };
591     ($input: ty, $($field: tt)+) => {
592     };
593 }
594 
595 // Facade over the core types we need
596 // Public but hidden to be accessible in macros
597 #[doc(hidden)]
598 pub mod lib {
599     #[cfg(not(feature = "std"))]
600     pub use core::*;
601 
602     #[cfg(feature = "std")]
603     pub use std::*;
604 }
605 
606 #[cfg(feature = "std")]
607 #[doc(inline)]
608 pub use crate::stream::easy;
609 
610 /// Error types and traits which define what kind of errors combine parsers may emit
611 #[macro_use]
612 pub mod error;
613 #[macro_use]
614 pub mod stream;
615 #[macro_use]
616 pub mod parser;
617 
618 #[cfg(feature = "futures-core-03")]
619 pub mod future_ext;
620 
621 #[doc(hidden)]
622 #[derive(Clone, PartialOrd, PartialEq, Debug, Copy)]
623 pub struct ErrorOffset(u8);
624 
625 #[cfg(test)]
626 mod tests {
627 
628     use crate::parser::char::{char, string};
629 
630     use super::*;
631 
632     #[test]
chainl1_error_consume()633     fn chainl1_error_consume() {
634         fn first<T, U>(t: T, _: U) -> T {
635             t
636         }
637         let mut p = chainl1(string("abc"), char(',').map(|_| first));
638         assert!(p.parse("abc,ab").is_err());
639     }
640 
641     #[test]
choice_strings()642     fn choice_strings() {
643         let mut fruits = [
644             attempt(string("Apple")),
645             attempt(string("Banana")),
646             attempt(string("Cherry")),
647             attempt(string("Date")),
648             attempt(string("Fig")),
649             attempt(string("Grape")),
650         ];
651         let mut parser = choice(&mut fruits);
652         assert_eq!(parser.parse("Apple"), Ok(("Apple", "")));
653         assert_eq!(parser.parse("Banana"), Ok(("Banana", "")));
654         assert_eq!(parser.parse("Cherry"), Ok(("Cherry", "")));
655         assert_eq!(parser.parse("DateABC"), Ok(("Date", "ABC")));
656         assert_eq!(parser.parse("Fig123"), Ok(("Fig", "123")));
657         assert_eq!(parser.parse("GrapeApple"), Ok(("Grape", "Apple")));
658     }
659 }
660 
661 #[cfg(all(feature = "std", test))]
662 mod std_tests {
663 
664     use crate::{
665         error::StdParseResult,
666         parser::char::{alpha_num, char, digit, letter, spaces, string},
667         stream::{
668             easy,
669             position::{self, SourcePosition},
670         },
671     };
672 
673     use super::{easy::Error, error::Commit, stream::IteratorStream, *};
674 
675     #[test]
optional_error_consume()676     fn optional_error_consume() {
677         let mut p = optional(string("abc"));
678         let err = p.easy_parse(position::Stream::new("ab")).unwrap_err();
679         assert_eq!(err.position, SourcePosition { line: 1, column: 1 });
680     }
681 
follow<Input>(input: &mut Input) -> StdParseResult<(), Input> where Input: Stream<Token = char, Error = easy::ParseError<Input>>, Input::Position: Default, Input::Error: std::fmt::Debug, Input::Token: PartialEq, Input::Range: PartialEq,682     fn follow<Input>(input: &mut Input) -> StdParseResult<(), Input>
683     where
684         Input: Stream<Token = char, Error = easy::ParseError<Input>>,
685         Input::Position: Default,
686         Input::Error: std::fmt::Debug,
687         Input::Token: PartialEq,
688         Input::Range: PartialEq,
689     {
690         let before = input.checkpoint();
691         match input.uncons() {
692             Ok(c) => {
693                 if c.is_alphanumeric() {
694                     input.reset(before).unwrap();
695                     let e = Error::Unexpected(c.into());
696                     Err(Commit::Peek(easy::Errors::new(input.position(), e).into()))
697                 } else {
698                     Ok(((), Commit::Peek(())))
699                 }
700             }
701             Err(_) => Ok(((), Commit::Peek(()))),
702         }
703     }
704 
integer<Input>(input: &mut Input) -> StdParseResult<i64, Input> where Input: Stream<Token = char>,705     fn integer<Input>(input: &mut Input) -> StdParseResult<i64, Input>
706     where
707         Input: Stream<Token = char>,
708     {
709         let (s, input) = many1::<String, _, _>(digit())
710             .expected("integer")
711             .parse_stream(input)
712             .into_result()?;
713         let mut n = 0;
714         for c in s.chars() {
715             n = n * 10 + (c as i64 - '0' as i64);
716         }
717         Ok((n, input))
718     }
719 
720     #[test]
test_integer()721     fn test_integer() {
722         let result = parser(integer).parse("123");
723         assert_eq!(result, Ok((123i64, "")));
724     }
725     #[test]
list()726     fn list() {
727         let mut p = sep_by(parser(integer), char(','));
728         let result = p.parse("123,4,56");
729         assert_eq!(result, Ok((vec![123i64, 4, 56], "")));
730     }
731 
732     #[test]
iterator()733     fn iterator() {
734         let result = parser(integer)
735             .parse(position::Stream::new(IteratorStream::new("123".chars())))
736             .map(|(i, mut input)| (i, input.uncons().is_err()));
737         assert_eq!(result, Ok((123i64, true)));
738     }
739 
740     #[test]
field()741     fn field() {
742         let word = || many(alpha_num());
743         let c_decl = (word(), spaces(), char(':'), spaces(), word())
744             .map(|t| (t.0, t.4))
745             .parse("x: int");
746         assert_eq!(c_decl, Ok((("x".to_string(), "int".to_string()), "")));
747     }
748 
749     #[test]
source_position()750     fn source_position() {
751         let source = r"
752 123
753 ";
754         let mut parsed_state = position::Stream::with_positioner(source, SourcePosition::new());
755         let result = (spaces(), parser(integer), spaces())
756             .map(|t| t.1)
757             .parse_stream(&mut parsed_state)
758             .into_result();
759         let state = Commit::Commit(position::Stream {
760             positioner: SourcePosition { line: 3, column: 1 },
761             input: "",
762         });
763         assert_eq!(
764             result.map(|(x, c)| (x, c.map(|_| parsed_state))),
765             Ok((123i64, state))
766         );
767     }
768 
769     #[derive(Debug, PartialEq)]
770     pub enum Expr {
771         Id(String),
772         Int(i64),
773         Array(Vec<Expr>),
774         Plus(Box<Expr>, Box<Expr>),
775         Times(Box<Expr>, Box<Expr>),
776     }
777 
778     parser! {
779         fn expr[Input]()(Input) -> Expr
780         where
781             [Input: Stream<Token = char>,]
782         {
783             let word = many1(letter()).expected("identifier");
784             let integer = parser(integer);
785             let array = between(char('['), char(']'), sep_by(expr(), char(','))).expected("[");
786             let paren_expr = between(char('('), char(')'), parser(term)).expected("(");
787             spaces()
788                 .silent()
789                 .with(
790                     word.map(Expr::Id)
791                         .or(integer.map(Expr::Int))
792                         .or(array.map(Expr::Array))
793                         .or(paren_expr),
794                 )
795                 .skip(spaces().silent())
796         }
797     }
798 
799     #[test]
expression_basic()800     fn expression_basic() {
801         let result = sep_by(expr(), char(',')).parse("int, 100, [[], 123]");
802         let exprs = vec![
803             Expr::Id("int".to_string()),
804             Expr::Int(100),
805             Expr::Array(vec![Expr::Array(vec![]), Expr::Int(123)]),
806         ];
807         assert_eq!(result, Ok((exprs, "")));
808     }
809 
810     #[test]
expression_error()811     fn expression_error() {
812         let input = r"
813 ,123
814 ";
815         let result = expr().easy_parse(position::Stream::new(input));
816         let err = easy::Errors {
817             position: SourcePosition { line: 2, column: 1 },
818             errors: vec![
819                 Error::Unexpected(','.into()),
820                 Error::Expected("integer".into()),
821                 Error::Expected("identifier".into()),
822                 Error::Expected("[".into()),
823                 Error::Expected("(".into()),
824             ],
825         };
826         assert_eq!(result, Err(err));
827     }
828 
term<Input>(input: &mut Input) -> StdParseResult<Expr, Input> where Input: Stream<Token = char>,829     fn term<Input>(input: &mut Input) -> StdParseResult<Expr, Input>
830     where
831         Input: Stream<Token = char>,
832     {
833         fn times(l: Expr, r: Expr) -> Expr {
834             Expr::Times(Box::new(l), Box::new(r))
835         }
836         fn plus(l: Expr, r: Expr) -> Expr {
837             Expr::Plus(Box::new(l), Box::new(r))
838         }
839         let mul = char('*').map(|_| times);
840         let add = char('+').map(|_| plus);
841         let factor = chainl1(expr(), mul);
842         chainl1(factor, add).parse_stream(input).into()
843     }
844 
845     #[test]
operators()846     fn operators() {
847         let input = r"
848 1 * 2 + 3 * test
849 ";
850         let (result, _) = parser(term).parse(position::Stream::new(input)).unwrap();
851 
852         let e1 = Expr::Times(Box::new(Expr::Int(1)), Box::new(Expr::Int(2)));
853         let e2 = Expr::Times(
854             Box::new(Expr::Int(3)),
855             Box::new(Expr::Id("test".to_string())),
856         );
857         assert_eq!(result, Expr::Plus(Box::new(e1), Box::new(e2)));
858     }
859 
860     #[test]
error_position()861     fn error_position() {
862         let mut p = string("let")
863             .skip(parser(follow))
864             .map(|x| x.to_string())
865             .or(many1(digit()));
866         match p.easy_parse(position::Stream::new("le123")) {
867             Ok(_) => panic!(),
868             Err(err) => assert_eq!(err.position, SourcePosition { line: 1, column: 1 }),
869         }
870         match p.easy_parse(position::Stream::new("let1")) {
871             Ok(_) => panic!(),
872             Err(err) => assert_eq!(err.position, SourcePosition { line: 1, column: 4 }),
873         }
874     }
875 
876     #[test]
sep_by_error_consume()877     fn sep_by_error_consume() {
878         let mut p = sep_by::<Vec<_>, _, _, _>(string("abc"), char(','));
879         let err = p.easy_parse(position::Stream::new("ab,abc")).unwrap_err();
880         assert_eq!(err.position, SourcePosition { line: 1, column: 1 });
881     }
882 
883     #[test]
inner_error_consume()884     fn inner_error_consume() {
885         let mut p = many::<Vec<_>, _, _>(between(char('['), char(']'), digit()));
886         let result = p.easy_parse(position::Stream::new("[1][2][]"));
887         assert!(result.is_err(), "{:?}", result);
888         let error = result.map(|x| format!("{:?}", x)).unwrap_err();
889         assert_eq!(error.position, SourcePosition { line: 1, column: 8 });
890     }
891 
892     #[test]
infinite_recursion_in_box_parser()893     fn infinite_recursion_in_box_parser() {
894         let _: Result<(Vec<_>, _), _> = (many(Box::new(digit()))).parse("1");
895     }
896 
897     #[test]
unsized_parser()898     fn unsized_parser() {
899         let mut parser: Box<dyn Parser<_, Output = char, PartialState = _>> = Box::new(digit());
900         let borrow_parser = &mut *parser;
901         assert_eq!(borrow_parser.parse("1"), Ok(('1', "")));
902     }
903 
904     #[test]
std_error()905     fn std_error() {
906         use std::error::Error as StdError;
907 
908         use std::fmt;
909 
910         #[derive(Debug)]
911         struct Error;
912         impl fmt::Display for Error {
913             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
914                 write!(f, "error")
915             }
916         }
917         impl StdError for Error {
918             fn description(&self) -> &str {
919                 "error"
920             }
921         }
922         let result: Result<((), _), easy::Errors<char, &str, _>> =
923             EasyParser::easy_parse(&mut string("abc").and_then(|_| Err(Error)), "abc");
924         assert!(result.is_err());
925         // Test that ParseError can be coerced to a StdError
926         let _ = result.map_err(|err| {
927             let err: Box<dyn StdError> = Box::new(err);
928             err
929         });
930     }
931 
932     #[test]
extract_std_error()933     fn extract_std_error() {
934         // The previous test verified that we could map a ParseError to a StdError by dropping
935         // the internal error details.
936         // This test verifies that we can map a ParseError to a StdError
937         // without dropping the internal error details.  Consumers using `error-chain` will
938         // appreciate this.  For technical reasons this is pretty janky; see the discussion in
939         // https://github.com/Marwes/combine/issues/86, and excuse the test with significant
940         // boilerplate!
941         use std::error::Error as StdError;
942 
943         use std::fmt;
944 
945         #[derive(Clone, PartialEq, Debug)]
946         struct CloneOnly(String);
947 
948         #[derive(Debug)]
949         struct DisplayVec<T>(Vec<T>);
950 
951         #[derive(Debug)]
952         struct ExtractedError(usize, DisplayVec<Error<CloneOnly, DisplayVec<CloneOnly>>>);
953 
954         impl StdError for ExtractedError {
955             fn description(&self) -> &str {
956                 "extracted error"
957             }
958         }
959 
960         impl fmt::Display for CloneOnly {
961             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
962                 write!(f, "{}", self.0)
963             }
964         }
965 
966         impl<T: fmt::Debug> fmt::Display for DisplayVec<T> {
967             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
968                 write!(f, "[{:?}]", self.0)
969             }
970         }
971 
972         impl fmt::Display for ExtractedError {
973             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
974                 writeln!(f, "Parse error at {}", self.0)?;
975                 Error::fmt_errors(&(self.1).0, f)
976             }
977         }
978 
979         let input = &[CloneOnly("x".to_string()), CloneOnly("y".to_string())][..];
980         let result = token(CloneOnly("z".to_string()))
981             .easy_parse(input)
982             .map_err(|e| e.map_position(|p| p.translate_position(input)))
983             .map_err(|e| {
984                 ExtractedError(
985                     e.position,
986                     DisplayVec(
987                         e.errors
988                             .into_iter()
989                             .map(|e| e.map_range(|r| DisplayVec(r.to_owned())))
990                             .collect(),
991                     ),
992                 )
993             });
994 
995         assert!(result.is_err());
996         // Test that the fresh ExtractedError is Display, so that the internal errors can be
997         // inspected by consuming code; and that the ExtractedError can be coerced to StdError.
998         let _ = result.map_err(|err| {
999             let s = format!("{}", err);
1000             assert!(s.starts_with("Parse error at 0"));
1001             assert!(s.contains("Expected"));
1002             let err: Box<dyn StdError> = Box::new(err);
1003             err
1004         });
1005     }
1006 }
1007